diff --git a/include/boost/range/detail/join_iterator.hpp b/include/boost/range/detail/join_iterator.hpp index 792f834..020c893 100644 --- a/include/boost/range/detail/join_iterator.hpp +++ b/include/boost/range/detail/join_iterator.hpp @@ -12,9 +12,9 @@ #define BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED #include +#include #include #include -#include #include #include #include @@ -30,21 +30,6 @@ namespace boost template struct join_iterator_link { -private: - class reference_count_t - { - public: - reference_count_t() : m_count(0u) {} - reference_count_t(const reference_count_t&) : m_count(0u) {} - reference_count_t& operator=(const reference_count_t&) { return *this; } - - void increment() { ++m_count; } - bool decrement() { return --m_count ? false : true; } - - private: - unsigned int m_count; - }; - public: join_iterator_link(Iterator1 last1, Iterator2 first2) : last1(last1) @@ -52,43 +37,13 @@ public: { } - void add_reference() const - { - count.increment(); - } - - bool release_reference() const - { - return count.decrement(); - } - Iterator1 last1; Iterator2 first2; private: join_iterator_link() /* = delete */ ; - - mutable reference_count_t count; }; -} // range_detail - -template -inline void intrusive_ptr_add_ref(const range_detail::join_iterator_link* p) -{ - p->add_reference(); -} - -template -inline void intrusive_ptr_release(const range_detail::join_iterator_link* p) -{ - if (p->release_reference()) - delete p; -} - -namespace range_detail -{ - class join_iterator_begin_tag {}; class join_iterator_end_tag {}; @@ -184,7 +139,7 @@ public: join_iterator(unsigned int section, Iterator1 current1, Iterator1 last1, Iterator2 first2, Iterator2 current2) : m_section(section) , m_it(section, current1, current2) - , m_link(new link_t(last1, first2)) + , m_link(link_t(last1, first2)) { } @@ -192,7 +147,7 @@ public: join_iterator(Range1& r1, Range2& r2, join_iterator_begin_tag) : m_section(boost::empty(r1) ? 1u : 0u) , m_it(boost::empty(r1) ? 1u : 0u, boost::begin(r1), boost::begin(r2)) - , m_link(new link_t(boost::end(r1), boost::begin(r2))) + , m_link(link_t(boost::end(r1), boost::begin(r2))) { } @@ -200,7 +155,7 @@ public: join_iterator(const Range1& r1, const Range2& r2, join_iterator_begin_tag) : m_section(boost::empty(r1) ? 1u : 0u) , m_it(boost::empty(r1) ? 1u : 0u, boost::const_begin(r1), boost::const_begin(r2)) - , m_link(new link_t(boost::const_end(r1), boost::const_begin(r2))) + , m_link(link_t(boost::const_end(r1), boost::const_begin(r2))) { } @@ -208,7 +163,7 @@ public: join_iterator(Range1& r1, Range2& r2, join_iterator_end_tag) : m_section(1u) , m_it(1u, boost::end(r1), boost::end(r2)) - , m_link(new link_t(boost::end(r1), boost::begin(r2))) + , m_link(link_t(boost::end(r1), boost::begin(r2))) { } @@ -216,7 +171,7 @@ public: join_iterator(const Range1& r1, const Range2& r2, join_iterator_end_tag) : m_section(1u) , m_it(1u, boost::const_end(r1), boost::const_end(r2)) - , m_link(new link_t(boost::const_end(r1), boost::const_begin(r2))) + , m_link(link_t(boost::const_end(r1), boost::const_begin(r2))) { } @@ -228,9 +183,9 @@ private: else { ++m_it.it1(); - if (m_it.it1() == m_link->last1) + if (m_it.it1() == m_link.last1) { - m_it.it2() = m_link->first2; + m_it.it2() = m_link.first2; m_section = 1u; } } @@ -240,9 +195,9 @@ private: { if (m_section) { - if (m_it.it2() == m_link->first2) + if (m_it.it2() == m_link.first2) { - m_it.it1() = boost::prior(m_link->last1); + m_it.it1() = boost::prior(m_link.last1); m_section = 0u; } else @@ -280,8 +235,8 @@ private: result = other.m_it.it2() - m_it.it2(); else { - result = (m_link->first2 - m_it.it2()) - + (other.m_it.it1() - m_link->last1); + result = (m_link.first2 - m_it.it2()) + + (other.m_it.it1() - m_link.last1); BOOST_ASSERT( result <= 0 ); } @@ -290,8 +245,8 @@ private: { if (other.m_section) { - result = (m_link->last1 - m_it.it1()) - + (other.m_it.it2() - m_link->first2); + result = (m_link.last1 - m_it.it1()) + + (other.m_it.it2() - m_link.first2); } else result = other.m_it.it1() - m_it.it1(); @@ -305,7 +260,7 @@ private: BOOST_ASSERT( m_section == 1u ); if (offset < 0) { - difference_t r2_dist = m_link->first2 - m_it.it2(); + difference_t r2_dist = m_link.first2 - m_it.it2(); BOOST_ASSERT( r2_dist <= 0 ); if (offset >= r2_dist) std::advance(m_it.it2(), offset); @@ -313,7 +268,7 @@ private: { difference_t r1_dist = offset - r2_dist; BOOST_ASSERT( r1_dist <= 0 ); - m_it.it1() = m_link->last1 + r1_dist; + m_it.it1() = m_link.last1 + r1_dist; m_section = 0u; } } @@ -327,7 +282,7 @@ private: BOOST_ASSERT( m_section == 0u ); if (offset > 0) { - difference_t r1_dist = m_link->last1 - m_it.it1(); + difference_t r1_dist = m_link.last1 - m_it.it1(); BOOST_ASSERT( r1_dist >= 0 ); if (offset < r1_dist) std::advance(m_it.it1(), offset); @@ -335,7 +290,7 @@ private: { difference_t r2_dist = offset - r1_dist; BOOST_ASSERT( r2_dist >= 0 ); - m_it.it2() = m_link->first2 + r2_dist; + m_it.it2() = m_link.first2 + r2_dist; m_section = 1u; } } @@ -345,7 +300,7 @@ private: unsigned int m_section; iterator_union m_it; - intrusive_ptr m_link; + link_t m_link; friend class ::boost::iterator_core_access; }; diff --git a/include/boost/range/irange.hpp b/include/boost/range/irange.hpp index ee25d45..8045550 100644 --- a/include/boost/range/irange.hpp +++ b/include/boost/range/irange.hpp @@ -173,28 +173,54 @@ namespace boost } // namespace range_detail template - iterator_range< range_detail::integer_iterator > - irange(Integer first, Integer last) + class integer_range + : public iterator_range< range_detail::integer_iterator > + { + typedef range_detail::integer_iterator iterator_t; + typedef iterator_range base_t; + public: + integer_range(Integer first, Integer last) + : base_t(iterator_t(first), iterator_t(last)) + { + } + }; + + template + class strided_integer_range + : public iterator_range< range_detail::integer_iterator_with_step > + { + typedef range_detail::integer_iterator_with_step iterator_t; + typedef iterator_range base_t; + public: + template + strided_integer_range(Iterator first, Iterator last) + : base_t(first, last) + { + } + }; + + template + integer_range + irange(Integer first, Integer last) { BOOST_ASSERT( first <= last ); - return boost::iterator_range< range_detail::integer_iterator >( - range_detail::integer_iterator(first), - range_detail::integer_iterator(last)); + return integer_range(first, last); } template - iterator_range< range_detail::integer_iterator_with_step > + strided_integer_range irange(Integer first, Integer last, StepSize step_size) { BOOST_ASSERT( step_size != 0 ); BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) ); + typedef typename range_detail::integer_iterator_with_step iterator_t; const std::ptrdiff_t last_step = (static_cast(last) - static_cast(first)) / (static_cast(step_size)); - return boost::iterator_range< iterator_t >( + return strided_integer_range( iterator_t(first, 0, step_size), iterator_t(first, last_step, step_size)); } diff --git a/include/boost/range/join.hpp b/include/boost/range/join.hpp index 518026c..ad0217e 100644 --- a/include/boost/range/join.hpp +++ b/include/boost/range/join.hpp @@ -18,49 +18,64 @@ namespace boost { + namespace range_detail + { template -iterator_range::type, - BOOST_DEDUCED_TYPENAME range_iterator::type, - BOOST_DEDUCED_TYPENAME add_const< - BOOST_DEDUCED_TYPENAME range_value::type>::type> -> +class joined_type +{ +public: + typedef iterator_range< + range_detail::join_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_value::type + > + > type; +}; + + } // namespace range_detail + +template +class joined_range + : public range_detail::joined_type::type +{ + typedef range_detail::join_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_iterator::type, + BOOST_DEDUCED_TYPENAME range_value::type + > iterator_t; + + typedef BOOST_DEDUCED_TYPENAME range_detail::joined_type< + SinglePassRange1, SinglePassRange2>::type base_t; +public: + joined_range(SinglePassRange1& rng1, SinglePassRange2& rng2) + : base_t( + iterator_t(rng1, rng2, range_detail::join_iterator_begin_tag()), + iterator_t(rng1, rng2, range_detail::join_iterator_end_tag()) + ) + { + } +}; + +template +joined_range join(const SinglePassRange1& r1, const SinglePassRange2& r2) { BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - typedef range_detail::join_iterator< - BOOST_DEDUCED_TYPENAME range_iterator::type, - BOOST_DEDUCED_TYPENAME range_iterator::type, - BOOST_DEDUCED_TYPENAME add_const< - BOOST_DEDUCED_TYPENAME range_value::type>::type> iterator_t; - - return iterator_range( - iterator_t(r1, r2, range_detail::join_iterator_begin_tag()), - iterator_t(r1, r2, range_detail::join_iterator_end_tag())); + return joined_range(r1, r2); } template -iterator_range::type, - BOOST_DEDUCED_TYPENAME range_iterator::type, - BOOST_DEDUCED_TYPENAME range_value::type> -> +joined_range join(SinglePassRange1& r1, SinglePassRange2& r2) { BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - typedef range_detail::join_iterator< - BOOST_DEDUCED_TYPENAME range_iterator::type, - BOOST_DEDUCED_TYPENAME range_iterator::type, - BOOST_DEDUCED_TYPENAME range_value::type> iterator_t; - - return iterator_range( - iterator_t(r1, r2, range_detail::join_iterator_begin_tag()), - iterator_t(r1, r2, range_detail::join_iterator_end_tag())); + return joined_range(r1, r2); } } // namespace boost