ref_unwrapped.hpp 2.8 KB

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