replaced.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2007. 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_REPLACED_IMPL_HPP_INCLUDED
  11. #define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
  12. #include <boost/config.hpp>
  13. #include <boost/range/adaptor/argument_fwd.hpp>
  14. #include <boost/range/iterator_range.hpp>
  15. #include <boost/range/begin.hpp>
  16. #include <boost/range/end.hpp>
  17. #include <boost/range/value_type.hpp>
  18. #include <boost/iterator/iterator_adaptor.hpp>
  19. #include <boost/iterator/transform_iterator.hpp>
  20. namespace boost
  21. {
  22. namespace range_detail
  23. {
  24. template< class Value >
  25. class replace_value
  26. {
  27. public:
  28. typedef const Value& result_type;
  29. typedef const Value& first_argument_type;
  30. replace_value(const Value& from, const Value& to)
  31. : m_from(from), m_to(to)
  32. {
  33. }
  34. const Value& operator()(const Value& x) const
  35. {
  36. return (x == m_from) ? m_to : x;
  37. }
  38. private:
  39. Value m_from;
  40. Value m_to;
  41. };
  42. template< class R >
  43. class replaced_range :
  44. public boost::iterator_range<
  45. boost::transform_iterator<
  46. replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
  47. BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
  48. {
  49. private:
  50. typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
  51. typedef boost::iterator_range<
  52. boost::transform_iterator<
  53. replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
  54. BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
  55. public:
  56. typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
  57. replaced_range( R& r, value_type from, value_type to )
  58. : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
  59. make_transform_iterator( boost::end(r), Fn(from, to) ) )
  60. { }
  61. };
  62. template< class T >
  63. class replace_holder : public holder2<T>
  64. {
  65. public:
  66. replace_holder( const T& from, const T& to )
  67. : holder2<T>(from, to)
  68. { }
  69. private:
  70. // not assignable
  71. void operator=(const replace_holder&);
  72. };
  73. template< class InputRng >
  74. inline replaced_range<InputRng>
  75. operator|( InputRng& r,
  76. const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
  77. {
  78. return replaced_range<InputRng>(r, f.val1, f.val2);
  79. }
  80. template< class InputRng >
  81. inline replaced_range<const InputRng>
  82. operator|( const InputRng& r,
  83. const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
  84. {
  85. return replaced_range<const InputRng>(r, f.val1, f.val2);
  86. }
  87. } // 'range_detail'
  88. using range_detail::replaced_range;
  89. namespace adaptors
  90. {
  91. namespace
  92. {
  93. const range_detail::forwarder2<range_detail::replace_holder>
  94. replaced =
  95. range_detail::forwarder2<range_detail::replace_holder>();
  96. }
  97. template<class InputRange>
  98. inline replaced_range<InputRange>
  99. replace(InputRange& rng,
  100. BOOST_DEDUCED_TYPENAME range_value<InputRange>::type from,
  101. BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
  102. {
  103. return replaced_range<InputRange>(rng, from, to);
  104. }
  105. template<class InputRange>
  106. inline replaced_range<const InputRange>
  107. replace(const InputRange& rng,
  108. BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type from,
  109. BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
  110. {
  111. return replaced_range<const InputRange>(rng, from ,to);
  112. }
  113. } // 'adaptors'
  114. } // 'boost'
  115. #endif // include guard