transformed.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Boost.Range library
  2. //
  3. // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
  11. #define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
  12. #include <boost/range/adaptor/argument_fwd.hpp>
  13. #include <boost/range/iterator_range.hpp>
  14. #include <boost/iterator/transform_iterator.hpp>
  15. #include <boost/utility/result_of.hpp>
  16. namespace boost
  17. {
  18. namespace range_detail
  19. {
  20. template< class F, class R >
  21. struct transformed_range :
  22. public boost::iterator_range<
  23. boost::transform_iterator< F,
  24. BOOST_DEDUCED_TYPENAME range_iterator<R>::type
  25. >
  26. >
  27. {
  28. private:
  29. typedef boost::iterator_range<
  30. boost::transform_iterator< F,
  31. BOOST_DEDUCED_TYPENAME range_iterator<R>::type
  32. >
  33. >
  34. base;
  35. public:
  36. typedef F transform_fn_type;
  37. typedef R source_range_type;
  38. transformed_range( F f, R& r )
  39. : base( boost::make_transform_iterator( boost::begin(r), f ),
  40. boost::make_transform_iterator( boost::end(r), f ) )
  41. { }
  42. };
  43. template< class T >
  44. struct transform_holder : holder<T>
  45. {
  46. transform_holder( T r ) : holder<T>(r)
  47. { }
  48. };
  49. template< class InputRng, class UnaryFunction >
  50. inline transformed_range<UnaryFunction,InputRng>
  51. operator|( InputRng& r,
  52. const transform_holder<UnaryFunction>& f )
  53. {
  54. return transformed_range<UnaryFunction,InputRng>( f.val, r );
  55. }
  56. template< class InputRng, class UnaryFunction >
  57. inline transformed_range<UnaryFunction, const InputRng>
  58. operator|( const InputRng& r,
  59. const transform_holder<UnaryFunction>& f )
  60. {
  61. return transformed_range<UnaryFunction, const InputRng>( f.val, r );
  62. }
  63. } // 'range_detail'
  64. using range_detail::transformed_range;
  65. namespace adaptors
  66. {
  67. namespace
  68. {
  69. const range_detail::forwarder<range_detail::transform_holder>
  70. transformed =
  71. range_detail::forwarder<range_detail::transform_holder>();
  72. }
  73. template<class UnaryFunction, class InputRange>
  74. inline transformed_range<UnaryFunction, InputRange>
  75. transform(InputRange& rng, UnaryFunction fn)
  76. {
  77. return transformed_range<UnaryFunction, InputRange>(fn, rng);
  78. }
  79. template<class UnaryFunction, class InputRange>
  80. inline transformed_range<UnaryFunction, const InputRange>
  81. transform(const InputRange& rng, UnaryFunction fn)
  82. {
  83. return transformed_range<UnaryFunction, const InputRange>(fn, rng);
  84. }
  85. } // 'adaptors'
  86. }
  87. #endif