• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Range library
2 //
3 //  Copyright Robin Eckert 2015.
4 //  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
5 //  distribution is subject to the Boost Software License, Version
6 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // For more information, see http://www.boost.org/libs/range/
10 //
11 
12 #ifndef BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
13 #define BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
14 
15 #include <boost/range/adaptor/transformed.hpp>
16 #include <boost/range/reference.hpp>
17 #include <boost/range/concepts.hpp>
18 #include <boost/type_traits/declval.hpp>
19 #include <utility>
20 
21 #if !defined(BOOST_NO_CXX11_DECLTYPE)
22 
23 namespace boost
24 {
25     namespace range_detail
26     {
27         struct ref_unwrapped_forwarder {};
28 
29         template<class SinglePassRange>
30         struct unwrap_ref
31         {
32             typedef BOOST_DEDUCED_TYPENAME
33                           range_reference<SinglePassRange>::type argument_type;
34 
35             typedef decltype( boost::declval<argument_type>().get() ) result_type;
36 
operator ()boost::range_detail::unwrap_ref37             result_type operator()( argument_type &&r ) const
38             {
39                 return r.get();
40             }
41         };
42 
43 
44         template<class SinglePassRange>
45         class unwrap_ref_range
46             : public transformed_range<unwrap_ref<SinglePassRange>,
47                                        SinglePassRange>
48         {
49             typedef transformed_range<unwrap_ref<SinglePassRange>,
50                                            SinglePassRange> base;
51         public:
52             typedef unwrap_ref<SinglePassRange> transform_fn_type;
53             typedef SinglePassRange source_range_type;
54 
unwrap_ref_range(transform_fn_type fn,source_range_type & rng)55             unwrap_ref_range(transform_fn_type fn, source_range_type &rng)
56                 : base(fn, rng)
57             {
58             }
59 
unwrap_ref_range(const base & other)60             unwrap_ref_range(const base &other) : base(other) {}
61         };
62 
63         template<class SinglePassRange>
64         inline unwrap_ref_range<SinglePassRange>
operator |(SinglePassRange & r,ref_unwrapped_forwarder)65         operator|(SinglePassRange& r, ref_unwrapped_forwarder)
66         {
67             BOOST_RANGE_CONCEPT_ASSERT((
68                 SinglePassRangeConcept<SinglePassRange>));
69 
70             return operator|( r,
71                 boost::adaptors::transformed(unwrap_ref<SinglePassRange>()));
72         }
73 
74     }
75 
76     using range_detail::unwrap_ref_range;
77 
78     namespace adaptors
79     {
80         namespace
81         {
82             const range_detail::ref_unwrapped_forwarder ref_unwrapped =
83                                        range_detail::ref_unwrapped_forwarder();
84         }
85 
86         template<class SinglePassRange>
87         inline unwrap_ref_range<SinglePassRange>
ref_unwrap(SinglePassRange & rng)88         ref_unwrap(SinglePassRange& rng)
89         {
90             BOOST_RANGE_CONCEPT_ASSERT((
91                 SinglePassRangeConcept<SinglePassRange>));
92 
93             return unwrap_ref_range<SinglePassRange>(
94                 range_detail::unwrap_ref<SinglePassRange>(), rng );
95         }
96     } // 'adaptors'
97 
98 }
99 
100 #endif
101 
102 #endif
103