Chris@16: // Boost.Range library Chris@16: // Chris@16: // Copyright Neil Groves 2007. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org/libs/range/ Chris@16: // Chris@16: Chris@16: #ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED Chris@16: #define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace range_detail Chris@16: { Chris@16: template< class Value > Chris@16: class replace_value Chris@16: { Chris@16: public: Chris@16: typedef const Value& result_type; Chris@16: typedef const Value& first_argument_type; Chris@16: Chris@101: // Rationale: Chris@101: // The default constructor is required to allow the transform Chris@101: // iterator to properly model the iterator concept. Chris@101: replace_value() Chris@101: { Chris@101: } Chris@101: Chris@16: replace_value(const Value& from, const Value& to) Chris@101: : m_impl(data(from, to)) Chris@16: { Chris@16: } Chris@16: Chris@16: const Value& operator()(const Value& x) const Chris@16: { Chris@101: return (x == m_impl->m_from) ? m_impl->m_to : x; Chris@16: } Chris@16: Chris@16: private: Chris@101: struct data Chris@101: { Chris@101: data(const Value& from, const Value& to) Chris@101: : m_from(from) Chris@101: , m_to(to) Chris@101: { Chris@101: } Chris@101: Chris@101: Value m_from; Chris@101: Value m_to; Chris@101: }; Chris@101: boost::optional m_impl; Chris@16: }; Chris@16: Chris@16: template< class R > Chris@16: class replaced_range : Chris@16: public boost::iterator_range< Chris@16: boost::transform_iterator< Chris@16: replace_value< BOOST_DEDUCED_TYPENAME range_value::type >, Chris@16: BOOST_DEDUCED_TYPENAME range_iterator::type > > Chris@16: { Chris@16: private: Chris@16: typedef replace_value< BOOST_DEDUCED_TYPENAME range_value::type > Fn; Chris@16: Chris@16: typedef boost::iterator_range< Chris@16: boost::transform_iterator< Chris@16: replace_value< BOOST_DEDUCED_TYPENAME range_value::type >, Chris@16: BOOST_DEDUCED_TYPENAME range_iterator::type > > base_t; Chris@16: Chris@16: public: Chris@16: typedef BOOST_DEDUCED_TYPENAME range_value::type value_type; Chris@16: Chris@16: replaced_range( R& r, value_type from, value_type to ) Chris@16: : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ), Chris@16: make_transform_iterator( boost::end(r), Fn(from, to) ) ) Chris@16: { } Chris@16: }; Chris@16: Chris@16: template< class T > Chris@16: class replace_holder : public holder2 Chris@16: { Chris@16: public: Chris@16: replace_holder( const T& from, const T& to ) Chris@16: : holder2(from, to) Chris@16: { } Chris@16: private: Chris@16: // not assignable Chris@16: void operator=(const replace_holder&); Chris@16: }; Chris@16: Chris@101: template< class SinglePassRange > Chris@101: inline replaced_range Chris@101: operator|( Chris@101: SinglePassRange& r, Chris@101: const replace_holder< Chris@101: BOOST_DEDUCED_TYPENAME range_value::type>& f ) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return replaced_range(r, f.val1, f.val2); Chris@16: } Chris@16: Chris@101: template< class SinglePassRange > Chris@101: inline replaced_range Chris@101: operator|( Chris@101: const SinglePassRange& r, Chris@101: const replace_holder< Chris@101: BOOST_DEDUCED_TYPENAME range_value::type>& f) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return replaced_range(r, f.val1, f.val2); Chris@16: } Chris@16: } // 'range_detail' Chris@16: Chris@16: using range_detail::replaced_range; Chris@16: Chris@16: namespace adaptors Chris@16: { Chris@16: namespace Chris@16: { Chris@16: const range_detail::forwarder2 Chris@16: replaced = Chris@16: range_detail::forwarder2(); Chris@16: } Chris@16: Chris@101: template Chris@101: inline replaced_range Chris@101: replace(SinglePassRange& rng, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type from, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type to) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return replaced_range(rng, from, to); Chris@16: } Chris@16: Chris@101: template Chris@101: inline replaced_range Chris@101: replace(const SinglePassRange& rng, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type from, Chris@101: BOOST_DEDUCED_TYPENAME range_value::type to) Chris@16: { Chris@101: BOOST_RANGE_CONCEPT_ASSERT(( Chris@101: SinglePassRangeConcept)); Chris@101: Chris@101: return replaced_range(rng, from ,to); Chris@16: } Chris@16: Chris@16: } // 'adaptors' Chris@16: } // 'boost' Chris@16: Chris@16: #endif // include guard