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