// (C) Copyright David Abrahams 2000. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. // // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, // sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #ifndef BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_ #define BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_ #include #include #include // I was having some problems with VC6. I couldn't tell whether our hack for // stock GCC was causing problems so I needed an easy way to turn it on and // off. Now we can test the hack with various compilers and still have an // "out" if it doesn't work. -dwa 7/31/00 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 && !defined(__STL_USE_NAMESPACES) # define BOOST_RELOPS_AMBIGUITY_BUG 1 #endif namespace boost { // Just a "type envelope"; works around some MSVC deficiencies. template struct type {}; //============================================================================ // Default policies for iterator adaptors. You can use this as a base // class if you want to customize particular policies. struct default_iterator_policies { // Some of these members were defined static, but Borland got confused // and thought they were non-const. template Reference dereference(type, const Iterator& x) const { return *x; } template static void increment(Iterator& x) { ++x; } template static void decrement(Iterator& x) { --x; } template static void advance(Iterator& x, DifferenceType n) { x += n; } template Difference distance(type, const Iterator1& x, const Iterator2& y) const { return y - x; } template bool equal(const Iterator1& x, const Iterator2& y) const { return x == y; } template bool less(const Iterator1& x, const Iterator2& y) const { return x < y; } }; // putting the comparisons in a base class avoids the g++ // ambiguous overload bug due to the relops operators #ifdef BOOST_RELOPS_AMBIGUITY_BUG template struct iterator_comparisons : Base { }; template inline bool operator==(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); const D2& y = static_cast(yb); return x.policies().equal(x.iter(), y.iter()); } template inline bool operator!=(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); const D2& y = static_cast(yb); return !x.policies().equal(x.iter(), y.iter()); } template inline bool operator<(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); const D2& y = static_cast(yb); return x.policies().less(x.iter(), y.iter()); } template inline bool operator>(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); const D2& y = static_cast(yb); return x.policies().less(y.iter(), x.iter()); } template inline bool operator>=(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); const D2& y = static_cast(yb); return !x.policies().less(x.iter(), y.iter()); } template inline bool operator<=(const iterator_comparisons& xb, const iterator_comparisons& yb) { const D1& x = static_cast(xb); const D2& y = static_cast(yb); return !x.policies().less(y.iter(), x.iter()); } #endif //============================================================================ // iterator_adaptor - A generalized adaptor around an existing // iterator, which is itself an iterator // // Iterator - the iterator type being wrapped. // // Policies - a set of policies determining how the resulting iterator // works. // // Traits - a class satisfying the same requirements as a specialization of // std::iterator_traits for the resulting iterator. // template #endif > struct iterator_adaptor : #ifdef BOOST_RELOPS_AMBIGUITY_BUG iterator_comparisons< iterator_adaptor, #endif boost::iterator #ifdef BOOST_RELOPS_AMBIGUITY_BUG > #endif { typedef iterator_adaptor Self; public: typedef typename Traits::difference_type difference_type; typedef typename Traits::value_type value_type; typedef typename Traits::pointer pointer; typedef typename Traits::reference reference; typedef typename Traits::iterator_category iterator_category; typedef Iterator iterator_type; iterator_adaptor() { } iterator_adaptor(const Iterator& iter, const Policies& p = Policies()) : m_iter_p(iter, p) {} template iterator_adaptor (const iterator_adaptor& src) : m_iter_p(src.iter(), src.policies()) { } reference operator*() const { return policies().dereference(type(), iter()); } #ifdef _MSC_VER # pragma warning(push) # pragma warning( disable : 4284 ) #endif pointer operator->() const { return &*this; } #ifdef _MSC_VER # pragma warning(pop) #endif reference operator[](difference_type n) { return *(*this + n); } Self& operator++() { #ifdef __MWERKS__ // Odd bug, MWERKS couldn't deduce the type for the member template // Workaround by explicitly specifying the type. policies().increment(iter()); #else policies().increment(iter()); #endif return *this; } Self operator++(int) { Self tmp(*this); ++*this; return tmp; } Self& operator--() { #ifdef __MWERKS__ policies().decrement(iter()); #else policies().decrement(iter()); #endif return *this; } Self operator--(int) { Self tmp(*this); --*this; return tmp; } Self& operator+=(difference_type n) { #ifdef __MWERKS__ policies().advance(iter(), n); #else policies().advance(iter(), n); #endif return *this; } Self& operator-=(difference_type n) { #ifdef __MWERKS__ policies().advance(iter(), -n); #else policies().advance(iter(), -n); #endif return *this; } iterator_type base() const { return m_iter_p.first(); } private: typedef Policies policies_type; compressed_pair m_iter_p; public: // too many compilers have trouble when these are private. Policies& policies() { return m_iter_p.second(); } const Policies& policies() const { return m_iter_p.second(); } Iterator& iter() { return m_iter_p.first(); } const Iterator& iter() const { return m_iter_p.first(); } }; template iterator_adaptor operator-(iterator_adaptor p, const typename Traits::difference_type x) { return p -= x; } template iterator_adaptor operator+(iterator_adaptor p, typename Traits::difference_type x) { return p += x; } template iterator_adaptor operator+(typename Traits::difference_type x, iterator_adaptor p) { return p += x; } template typename Traits1::difference_type operator-( const iterator_adaptor& x, const iterator_adaptor& y ) { typedef typename Traits1::difference_type difference_type; return x.policies().distance(type(), y.iter(), x.iter()); } #ifndef BOOST_RELOPS_AMBIGUITY_BUG template inline bool operator==(const iterator_adaptor& x, const iterator_adaptor& y) { return x.policies().equal(x.iter(), y.iter()); } template inline bool operator<(const iterator_adaptor& x, const iterator_adaptor& y) { return x.policies().less(x.iter(), y.iter()); } template inline bool operator>(const iterator_adaptor& x, const iterator_adaptor& y) { return x.policies().less(y.iter(), x.iter()); } template inline bool operator>=(const iterator_adaptor& x, const iterator_adaptor& y) { return !x.policies().less(x.iter(), y.iter()); } template inline bool operator<=(const iterator_adaptor& x, const iterator_adaptor& y) { return !x.policies().less(y.iter(), x.iter()); } template inline bool operator!=(const iterator_adaptor& x, const iterator_adaptor& y) { return !x.policies().equal(x.iter(), y.iter()); } #endif //============================================================================= // iterator_adaptors - A type generator that simplifies creating // mutable/const pairs of iterator adaptors. template , class ConstTraits = std::iterator_traits, #endif class Policies = default_iterator_policies> class iterator_adaptors { public: typedef iterator_adaptor iterator; typedef iterator_adaptor const_iterator; }; //============================================================================= // Transform Iterator Adaptor template struct transform_iterator_policies : public default_iterator_policies { transform_iterator_policies() { } transform_iterator_policies(const AdaptableUnaryFunction& f) : m_f(f) { } template Reference dereference(type, const Iterator& x) const { return m_f(*x); } AdaptableUnaryFunction m_f; }; template struct transform_iterator_traits { typedef typename AdaptableUnaryFunction::result_type value_type; typedef value_type reference; typedef value_type* pointer; typedef typename IteratorTraits::difference_type difference_type; typedef typename IteratorTraits::iterator_category iterator_category; }; template #else class Traits #endif > struct transform_iterator { typedef transform_iterator_traits TransTraits; typedef iterator_adaptor, TransTraits> type; }; //============================================================================= // Indirect Iterators Adaptor // Tried implementing this with transform_iterator, but that required // using boost::remove_ref, which is not compiler portable. struct indirect_iterator_policies : public default_iterator_policies { template Reference dereference(type, const Iterator& x) const { return **x; } }; template , class InnerTraits = std::iterator_traits #endif > struct indirect_traits { typedef typename OuterTraits::difference_type difference_type; typedef typename InnerTraits::value_type value_type; typedef typename InnerTraits::pointer pointer; typedef typename InnerTraits::reference reference; typedef typename OuterTraits::iterator_category iterator_category; }; template , class InnerTraits = std::iterator_traits #endif > struct indirect_iterator { typedef iterator_adaptor > type; }; template , class InnerTraits = std::iterator_traits, class ConstInnerTraits = std::iterator_traits #endif > struct indirect_iterators { typedef iterator_adaptors, indirect_traits, indirect_iterator_policies > Adaptors; typedef typename Adaptors::iterator iterator; typedef typename Adaptors::const_iterator const_iterator; }; //============================================================================= // Reverse Iterators Adaptor struct reverse_iterator_policies { template Reference dereference(type, const Iterator& x) const { return *boost::prior(x); } template void increment(Iterator& x) const { --x; } template void decrement(Iterator& x) const { ++x; } template void advance(Iterator& x, DifferenceType n) const { x -= n; } template Difference distance(type, const Iterator1& x, const Iterator2& y) const { return x - y; } template bool equal(const Iterator1& x, const Iterator2& y) const { return x == y; } template bool less(const Iterator1& x, const Iterator2& y) const { return y < x; } }; template #else class Traits #endif > struct reverse_iterator { typedef iterator_adaptor type; }; template #else class ConstTraits #endif > struct const_reverse_iterator { typedef iterator_adaptor type; }; template , class ConstTraits = std::iterator_traits #else class Traits, class ConstTraits #endif > struct reverse_iterators { typedef iterator_adaptors Adaptor; typedef typename Adaptor::iterator iterator; typedef typename Adaptor::const_iterator const_iterator; }; //============================================================================= // Projection Iterators Adaptor template struct projection_iterator_policies : public default_iterator_policies { template Reference dereference (type, Iterator const& it) const { return AdaptableUnaryFunction()(*it); } }; template struct projection_iterator_traits { typedef typename AdaptableUnaryFunction::result_type value_type; typedef value_type& reference; typedef value_type* pointer; typedef typename Traits::difference_type difference_type; typedef typename Traits::iterator_category iterator_category; }; template struct const_projection_iterator_traits { typedef typename AdaptableUnaryFunction::result_type value_type; typedef value_type const& reference; typedef value_type const* pointer; typedef typename Traits::difference_type difference_type; typedef typename Traits::iterator_category iterator_category; }; template #else class Traits #endif > struct projection_iterator { typedef projection_iterator_traits Projection_Traits; typedef iterator_adaptor, Projection_Traits> type; }; template #else class Traits #endif > struct const_projection_iterator { typedef const_projection_iterator_traits Projection_Traits; typedef iterator_adaptor, Projection_Traits> type; }; template , class ConstTraits = std::iterator_traits #else class Traits, class ConstTraits #endif > struct projection_iterators { typedef projection_iterator_traits Projection_Traits; typedef const_projection_iterator_traits Const_Projection_Traits; typedef iterator_adaptors > Adaptors; typedef typename Adaptors::iterator iterator; typedef typename Adaptors::const_iterator const_iterator; }; } // namespace boost #endif