replaced.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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/range/concepts.hpp>
  19. #include <boost/iterator/iterator_adaptor.hpp>
  20. #include <boost/iterator/transform_iterator.hpp>
  21. #include <boost/optional/optional.hpp>
  22. namespace boost
  23. {
  24. namespace range_detail
  25. {
  26. template< class Value >
  27. class replace_value
  28. {
  29. public:
  30. typedef const Value& result_type;
  31. typedef const Value& first_argument_type;
  32. // Rationale:
  33. // The default constructor is required to allow the transform
  34. // iterator to properly model the iterator concept.
  35. replace_value()
  36. {
  37. }
  38. replace_value(const Value& from, const Value& to)
  39. : m_impl(data(from, to))
  40. {
  41. }
  42. const Value& operator()(const Value& x) const
  43. {
  44. return (x == m_impl->m_from) ? m_impl->m_to : x;
  45. }
  46. private:
  47. struct data
  48. {
  49. data(const Value& from, const Value& to)
  50. : m_from(from)
  51. , m_to(to)
  52. {
  53. }
  54. Value m_from;
  55. Value m_to;
  56. };
  57. boost::optional<data> m_impl;
  58. };
  59. template< class R >
  60. class replaced_range :
  61. public boost::iterator_range<
  62. boost::transform_iterator<
  63. replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
  64. BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
  65. {
  66. private:
  67. typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
  68. typedef boost::iterator_range<
  69. boost::transform_iterator<
  70. replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
  71. BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
  72. public:
  73. typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
  74. replaced_range( R& r, value_type from, value_type to )
  75. : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
  76. make_transform_iterator( boost::end(r), Fn(from, to) ) )
  77. { }
  78. };
  79. template< class T >
  80. class replace_holder : public holder2<T>
  81. {
  82. public:
  83. replace_holder( const T& from, const T& to )
  84. : holder2<T>(from, to)
  85. { }
  86. private:
  87. // not assignable
  88. void operator=(const replace_holder&);
  89. };
  90. template< class SinglePassRange, class Value >
  91. inline replaced_range<SinglePassRange>
  92. operator|(SinglePassRange& r, const replace_holder<Value>& f)
  93. {
  94. BOOST_RANGE_CONCEPT_ASSERT((
  95. SinglePassRangeConcept<SinglePassRange>));
  96. return replaced_range<SinglePassRange>(r, f.val1, f.val2);
  97. }
  98. template< class SinglePassRange, class Value >
  99. inline replaced_range<const SinglePassRange>
  100. operator|(const SinglePassRange& r, const replace_holder<Value>& f)
  101. {
  102. BOOST_RANGE_CONCEPT_ASSERT((
  103. SinglePassRangeConcept<const SinglePassRange>));
  104. return replaced_range<const SinglePassRange>(r, f.val1, f.val2);
  105. }
  106. } // 'range_detail'
  107. using range_detail::replaced_range;
  108. namespace adaptors
  109. {
  110. namespace
  111. {
  112. const range_detail::forwarder2<range_detail::replace_holder>
  113. replaced =
  114. range_detail::forwarder2<range_detail::replace_holder>();
  115. }
  116. template< class SinglePassRange, class Value >
  117. inline replaced_range<SinglePassRange>
  118. replace(SinglePassRange& rng, Value from, Value to)
  119. {
  120. BOOST_RANGE_CONCEPT_ASSERT((
  121. SinglePassRangeConcept<SinglePassRange>));
  122. return replaced_range<SinglePassRange>(rng, from, to);
  123. }
  124. template< class SinglePassRange, class Value >
  125. inline replaced_range<const SinglePassRange>
  126. replace(const SinglePassRange& rng, Value from, Value to)
  127. {
  128. BOOST_RANGE_CONCEPT_ASSERT((
  129. SinglePassRangeConcept<const SinglePassRange>));
  130. return replaced_range<const SinglePassRange>(rng, from ,to);
  131. }
  132. } // 'adaptors'
  133. } // 'boost'
  134. #endif // include guard