ref_unwrapped.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. #ifndef BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
  12. #define BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
  13. #include <boost/range/adaptor/transformed.hpp>
  14. #include <boost/range/reference.hpp>
  15. #include <boost/range/concepts.hpp>
  16. #include <boost/type_traits/declval.hpp>
  17. #include <utility>
  18. #if !defined(BOOST_NO_CXX11_DECLTYPE)
  19. namespace boost
  20. {
  21. namespace range_detail
  22. {
  23. struct ref_unwrapped_forwarder {};
  24. template<class SinglePassRange>
  25. struct unwrap_ref
  26. {
  27. typedef BOOST_DEDUCED_TYPENAME
  28. range_reference<SinglePassRange>::type argument_type;
  29. typedef decltype( boost::declval<argument_type>().get() ) result_type;
  30. result_type operator()( argument_type &&r ) const
  31. {
  32. return r.get();
  33. }
  34. };
  35. template<class SinglePassRange>
  36. class unwrap_ref_range
  37. : public transformed_range<unwrap_ref<SinglePassRange>,
  38. SinglePassRange>
  39. {
  40. typedef transformed_range<unwrap_ref<SinglePassRange>,
  41. SinglePassRange> base;
  42. public:
  43. typedef unwrap_ref<SinglePassRange> transform_fn_type;
  44. typedef SinglePassRange source_range_type;
  45. unwrap_ref_range(transform_fn_type fn, source_range_type &rng)
  46. : base(fn, rng)
  47. {
  48. }
  49. unwrap_ref_range(const base &other) : base(other) {}
  50. };
  51. template<class SinglePassRange>
  52. inline unwrap_ref_range<SinglePassRange>
  53. operator|(SinglePassRange& r, ref_unwrapped_forwarder)
  54. {
  55. BOOST_RANGE_CONCEPT_ASSERT((
  56. SinglePassRangeConcept<SinglePassRange>));
  57. return operator|( r,
  58. boost::adaptors::transformed(unwrap_ref<SinglePassRange>()));
  59. }
  60. }
  61. using range_detail::unwrap_ref_range;
  62. namespace adaptors
  63. {
  64. namespace
  65. {
  66. const range_detail::ref_unwrapped_forwarder ref_unwrapped =
  67. range_detail::ref_unwrapped_forwarder();
  68. }
  69. template<class SinglePassRange>
  70. inline unwrap_ref_range<SinglePassRange>
  71. ref_unwrap(SinglePassRange& rng)
  72. {
  73. BOOST_RANGE_CONCEPT_ASSERT((
  74. SinglePassRangeConcept<SinglePassRange>));
  75. return unwrap_ref_range<SinglePassRange>(
  76. range_detail::unwrap_ref<SinglePassRange>(), rng );
  77. }
  78. } // 'adaptors'
  79. }
  80. #endif
  81. #endif