diff --git a/include/boost/iterator/detail/categories.hpp b/include/boost/iterator/detail/categories.hpp index da8ed48..11efbcd 100644 --- a/include/boost/iterator/detail/categories.hpp +++ b/include/boost/iterator/detail/categories.hpp @@ -9,9 +9,12 @@ #include #include -#include +#include +#include +#include #include #include +#include #include #if BOOST_WORKAROUND(__MWERKS__, <=0x2407) @@ -207,7 +210,7 @@ namespace boost { // // The nested is_category template class are used for // minimum category detection in iterator_adaptors. - // They are basically a pore mans is_derived replacement. + // They are basically a poore mans is_derived replacement. // // A implementation may look like this // @@ -392,6 +395,70 @@ namespace boost { #endif + // + // I bet this is defined somewhere else. Let's wait and see. + // + struct error_type; + +#ifdef BOOST_NO_IS_CONVERTIBLE + template + struct minimum_return_category + : mpl::if_< is_return_category< Cat1 >::template is_category< Cat2 >, + Cat1, + mpl::if_< is_return_category::template is_category, + Cat2, + error_type + > + > {}; + + template + struct minimum_traversal_category + : mpl::if_< is_traversal_category< Cat1 >::template is_category< Cat2 >, + Cat1, + mpl::if_< is_traversal_category::template is_category, + Cat2, + error_type + > + > {}; + + template + struct minimum_category_select + : mpl::if_< is_same< typename T1::type, error_type >, + T2, + T1 > + {}; +#endif + + template + struct is_base_or_same : + mpl::logical_or< is_same< Base, Derived >, + is_base_and_derived< Base, Derived > > + {}; + + // + // Returns the minimum category type or error_type + // if T1 and T2 are unrelated. + // + // For compilers not supporting is_convertible this only + // works with the new boost return and traversal category + // types. The exect boost _types_ are required. No derived types + // will work. + // + // + template + struct minimum_category : +#ifndef BOOST_NO_IS_CONVERTIBLE + mpl::if_< is_base_or_same< T1, T2 >, + T1, + mpl::if_< is_base_or_same< T2, T1 >, + T2, + error_type > > +#else + minimum_category_select< minimum_return_category, + minimum_traversal_category > +#endif + {}; + } // namespace detail } // namespace boost diff --git a/include/boost/iterator/detail/config_def.hpp b/include/boost/iterator/detail/config_def.hpp new file mode 100644 index 0000000..f1699c2 --- /dev/null +++ b/include/boost/iterator/detail/config_def.hpp @@ -0,0 +1,43 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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. + +// no include guard multiple inclusion intended + +// +// This is a temporary workaround until the bulk of this is +// available in boost config. +// 23/02/03 thw +// + +#include // for prior +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \ + || BOOST_WORKAROUND(__MWERKS__, <= 0x3000) +# define BOOST_NO_SFINAE // "Substitution Failure Is Not An Error not implemented" +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, <=1200) +# define BOOST_ARG_DEP_TYPENAME +#else +# define BOOST_ARG_DEP_TYPENAME typename +#endif + +#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) +# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't always work" +#endif + +#if BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \ + || BOOST_WORKAROUND(__MWERKS__, <= 0x2407) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +# define BOOST_NO_MPL_AUX_HAS_XXX // "MPL's has_xxx facility doesn't work" +#endif + +// no include guard multiple inclusion intended diff --git a/include/boost/iterator/detail/config_undef.hpp b/include/boost/iterator/detail/config_undef.hpp new file mode 100644 index 0000000..17a9089 --- /dev/null +++ b/include/boost/iterator/detail/config_undef.hpp @@ -0,0 +1,20 @@ +// (C) Copyright Thomas Witt 2002. +// 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. + +// no include guard multiple inclusion intended + +// +// This is a temporary workaround until the bulk of this is +// available in boost config. +// 23/02/03 thw +// + +# undef BOOST_NO_SFINAE +# undef BOOST_ARG_DEP_TYPENAME +# undef BOOST_NO_IS_CONVERTIBLE +# undef BOOST_NO_MPL_AUX_HAS_XXX + diff --git a/include/boost/iterator/detail/enable_if.hpp b/include/boost/iterator/detail/enable_if.hpp new file mode 100644 index 0000000..7b22b90 --- /dev/null +++ b/include/boost/iterator/detail/enable_if.hpp @@ -0,0 +1,88 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_ENABLE_IF_23022003THW_HPP +#define BOOST_ENABLE_IF_23022003THW_HPP + +#include +#include + +#include + +// +// Boost iterators uses its own enable_if cause we need +// special semantics for deficient compilers. +// 23/02/03 thw +// + +namespace boost +{ + + namespace detail + { + // + // Base machinery for all kinds of enable if + // + template + struct enabled + { + template + struct base + { + typedef T type; + }; + }; + + // + // For compilers that don't support "Substitution Failure Is Not An Error" + // enable_if falls back to always enabled. See comments + // on operator implementation for consequences. + // + template<> + struct enabled + { + template + struct base + { +#ifdef BOOST_NO_SFINAE + + typedef T type; + + // This way to do it would give a nice error message containing + // invalid overload, but has the big disadvantage that + // there is no reference to user code in the error message. + // + // struct invalid_overload; + // typedef invalid_overload type; + // +#endif + }; + }; + + + template + struct enable_if +# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE) + : enabled::template base +# else + : mpl::identity +# endif + { +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + typedef Return type; +# endif + }; + + } // namespace detail + +} // namespace boost + +#include + +#endif // BOOST_ENABLE_IF_23022003THW_HPP diff --git a/include/boost/iterator/filter_iterator.hpp b/include/boost/iterator/filter_iterator.hpp new file mode 100644 index 0000000..4a219e2 --- /dev/null +++ b/include/boost/iterator/filter_iterator.hpp @@ -0,0 +1,102 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_FILTER_ITERATOR_23022003THW_HPP +#define BOOST_FILTER_ITERATOR_23022003THW_HPP + +#include +#include +#include + +namespace boost +{ + + namespace detail { + + template + struct filter_iterator_traits + : iterator_traits + { + typedef iterator_tag< + typename return_category::type + , minimum_category< forward_traversal_tag + ,typename traversal_category::type >::type + > iterator_category; + }; + + } // namespace detail + + template + class filter_iterator + : public iterator_adaptor< + filter_iterator, Iterator + , detail::filter_iterator_traits + > + { + typedef iterator_adaptor< + filter_iterator, Iterator + , detail::filter_iterator_traits + > super_t; + + friend class iterator_core_access; + + public: + filter_iterator() { } + + filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) + : super_t(x), m_predicate(f), m_end(end) + { + satisfy_predicate(); + } + + filter_iterator(Iterator x, Iterator end = Iterator()) + : super_t(x), m_predicate(), m_end(end) + { + satisfy_predicate(); + } + + template + filter_iterator( + filter_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {} + + Predicate predicate() const { return m_predicate; } + + Iterator end() const { return m_end; } + + private: + void increment() + { + super_t::increment(); + satisfy_predicate(); + } + + void satisfy_predicate() + { + while (this->base() != this->m_end && !this->m_predicate(*this->base())) + super_t::increment(); + } + + // Probably should be the initial base class so it can be + // optimized away via EBO if it is an empty class. + Predicate m_predicate; + Iterator m_end; + }; + + template + filter_iterator + make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) + { + return filter_iterator(f,x,end); + } + +} // namespace boost + +#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/indirect_iterator.hpp b/include/boost/iterator/indirect_iterator.hpp new file mode 100644 index 0000000..efff795 --- /dev/null +++ b/include/boost/iterator/indirect_iterator.hpp @@ -0,0 +1,164 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_INDIRECT_ITERATOR_23022003THW_HPP +#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP + +#include +#include + +#include + +#ifdef BOOST_NO_MPL_AUX_HAS_XXX +# include +# include +# include +#endif + +namespace boost +{ + + namespace detail + { + struct unspecified {}; + + // + // Detection for whether a type has a nested `element_type' + // typedef. Used to detect smart pointers. For compilers not + // supporting mpl's has_xxx, we supply specializations. However, we + // really ought to have a specializable is_pointer template which + // can be used instead with something like + // boost/python/pointee.hpp to find the value_type. + // +# if !defined BOOST_NO_MPL_AUX_HAS_XXX + namespace aux + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) + } + + template + struct has_element_type + : mpl::if_< + is_class + , aux::has_element_type + , mpl::false_c + >::type + { + }; +# else + template + struct has_element_type + : mpl::false_c {}; + + template + struct has_element_type > + : mpl::true_c {}; + + template + struct has_element_type > + : mpl::true_c {}; + + template + struct has_element_type > + : mpl::true_c {}; +# endif + + // Metafunction returning the nested element_type typedef + template + struct smart_pointer_traits + { + typedef typename remove_const< + typename T::element_type + >::type value_type; + + typedef typename T::element_type& reference; + typedef typename T::element_type* pointer; + }; + + // If the Value parameter is unspecified, we use this metafunction + // to deduce the default types + template + struct indirect_defaults + : mpl::if_< + has_element_type::value_type> + , smart_pointer_traits::value_type> + , iterator_traits::value_type> + >::type + { + typedef typename iterator_traits::iterator_category iterator_category; + typedef typename iterator_traits::difference_type difference_type; + }; + + // The traits to use for indirect iterator, by default. Whatever + // is supplied gets passed through traits_iterator<...> so that it + // is ultimately derived from boost::iterator<...> + template + struct indirect_traits + : mpl::if_< + is_same + , indirect_defaults + , Traits + >::type + { + }; + } // namespace detail + + template + class indirect_iterator : + public iterator_adaptor< + indirect_iterator + , Iterator + , detail::indirect_traits > + { + typedef iterator_adaptor< + indirect_iterator + , Iterator + , detail::indirect_traits + > super_t; + + friend class iterator_core_access; + + public: + indirect_iterator() {} + + indirect_iterator(Iterator iter) + : super_t(iter) {} + + template + indirect_iterator( + indirect_iterator const& y + , typename enable_if_convertible::type* = 0 + ) + : super_t(y.base()) + {} + + private: + typename super_t::reference dereference() const { return **this->base(); } + + }; + + template + inline + indirect_iterator make_indirect_iterator(Iter x) + { + return indirect_iterator(x); + } + + template + inline + indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) + { + return indirect_iterator(x); + } + +} // namespace boost + +#include + +#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/interoperable.hpp b/include/boost/iterator/interoperable.hpp new file mode 100644 index 0000000..377c8c1 --- /dev/null +++ b/include/boost/iterator/interoperable.hpp @@ -0,0 +1,52 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_INTEROPERABLE_23022003THW_HPP +#define BOOST_INTEROPERABLE_23022003THW_HPP + +#include +#include + +#include + +#include + +namespace boost +{ + + // + // Meta function that determines whether two + // iterator types are considered interoperable. + // + // Two iterator types A,B are considered interoperable if either + // A is convertible to B or vice versa. + // This interoperability definition is in sync with the + // standards requirements on constant/mutable container + // iterators (23.1 [lib.container.requirements]). + // + // For compilers that don't support is_convertible + // is_interoperable gives false positives. See comments + // on operator implementation for consequences. + // + template + struct is_interoperable +#if defined(BOOST_NO_IS_CONVERTIBLE) + : mpl::true_c +#else + : mpl::logical_or< + is_convertible< A, B > + , is_convertible< B, A > > +#endif + { + }; + +} // namespace boost + +#include + +#endif // BOOST_INTEROPERABLE_23022003THW_HPP diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp new file mode 100644 index 0000000..c9e13ab --- /dev/null +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -0,0 +1,206 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_23022003THW_HPP +#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +namespace boost +{ + + namespace detail + { + template + struct same_category_and_difference + : mpl::logical_and< + is_same< + typename Traits::iterator_category + , typename Other::iterator_category + > + , is_same< + typename Traits::iterator_category + , typename Other::iterator_category + > + > + {}; + + + // + // Result type used in enable_if_convertible meta function. + // This can be an incomplete type, as only pointers to + // enable_if_convertible< ... >::type are used. + // We could have used void for this, but conversion to + // void* is just to easy. + // + struct enable_type; + } + + + // + // enable_if for use in adapted iterators constructors. + // + // In order to provide interoperability between adapted constant and + // mutable iterators, adapted iterators will usually provide templated + // conversion constructors of the following form + // + // template + // class adapted_iterator : + // public iterator_adaptor< adapted_iterator, Iterator > + // { + // public: + // + // ... + // + // template + // adapted_iterator(OtherIterator const& it, + // typename enable_if_convertible::type* = 0); + // + // ... + // }; + // + // enable_if_convertible is used to remove those overloads from the overload + // set that cannot be instantiated. For all practical purposes only overloads + // for constant/mutable interaction will remain. This has the advantage that + // meta functions like boost::is_convertible do not return false positives, + // as they can only look at the signature of the conversion constructor + // and not at the actual instantiation. + // + // enable_if_interoperable can be safely used in user code. It falls back to + // always enabled for compilers that don't support enable_if or is_convertible. + // There is no need for compiler specific workarounds in user code. + // + // The operators implementation relies on boost::is_convertible not returning + // false positives for user/library defined iterator types. See comments + // on operator implementation for consequences. + // + template< + typename From + , typename To> + struct enable_if_convertible + { + // Borland 551 and vc6 have a problem with the use of base class + // forwarding in this template, so we write it all out here +# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) + typedef detail::enable_type type; +# else + typedef typename detail::enable_if< +# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292) && BOOST_MSVC > 1300) + // For some reason vc7.1 needs us to "cut off" instantiation + // of is_convertible in the case where From == To. + mpl::logical_or, is_convertible > +# else + ::boost::is_convertible +# endif + ,detail::enable_type >::type type; +# endif + }; + + // + // iterator_traits_adaptor can be used to create new iterator traits by adapting + // the traits of a given iterator type. Together with iterator_adaptor it simplifies + // the creation of adapted iterator types. Therefore the ordering the template + // argument ordering is different from the std::iterator template, so that default + // arguments can be used effectivly. + // + template ::value_type, + class Reference = ValueType&, + class Pointer = ValueType*, + class IteratorCategory = typename detail::iterator_traits::iterator_category, + class DifferenceType = typename detail::iterator_traits::difference_type > + struct iterator_traits_adaptor + : iterator + { + }; + + // + // + // + template < + class Derived + , class Iterator + , class Traits = detail::iterator_traits + > + class iterator_adaptor + : public iterator_facade + { + friend class iterator_core_access; + + public: + iterator_adaptor() {} + + explicit iterator_adaptor(Iterator iter) + : m_iterator(iter) + { + } + + Iterator base() const { return m_iterator; } + + protected: + // Core iterator interface for iterator_facade + // + + typename Traits::reference dereference() const { return *m_iterator; } + + template < + class OtherDerived, class OtherIterator, class OtherTraits + > + bool equal(iterator_adaptor const& x) const + { + BOOST_STATIC_ASSERT( + (detail::same_category_and_difference::value) + ); + return m_iterator == x.base(); + } + + void advance(typename Traits::difference_type n) + { + m_iterator += n; + } + + void increment() { ++m_iterator; } + void decrement() { --m_iterator; } + + template + typename Traits::difference_type distance_to( + iterator_adaptor const& y) const + { + BOOST_STATIC_ASSERT( + (detail::same_category_and_difference::value) + ); + return y.base() - m_iterator; + } + + private: // data members + Iterator m_iterator; + + }; + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP diff --git a/include/boost/iterator/iterator_adaptors.hpp b/include/boost/iterator/iterator_adaptors.hpp deleted file mode 100644 index 0aaa809..0000000 --- a/include/boost/iterator/iterator_adaptors.hpp +++ /dev/null @@ -1,1100 +0,0 @@ -#ifndef BOOST_ITERATOR_ADAPTORS_HPP -#define BOOST_ITERATOR_ADAPTORS_HPP - -#include // for prior -#include -#include // for prior -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "boost/type_traits/detail/bool_trait_def.hpp" - -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ - || BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \ - || BOOST_WORKAROUND(__MWERKS__, <= 0x3000) -# define BOOST_NO_SFINAE // "Substitution Failure Is Not An Error not implemented" -#endif - -#if BOOST_WORKAROUND(BOOST_MSVC, <=1200) -# define BOOST_ARG_DEP_TYPENAME -#else -# define BOOST_ARG_DEP_TYPENAME typename -#endif - -#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) -# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't always work" -#endif - -#if BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \ - || BOOST_WORKAROUND(__MWERKS__, <= 0x2407) \ - || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) -# define BOOST_NO_MPL_AUX_HAS_XXX // "MPL's has_xxx facility doesn't work" -#endif - -#ifdef BOOST_NO_MPL_AUX_HAS_XXX -# include -# include -# include -#endif - - -namespace boost -{ - - namespace detail - { - // - // Base machinery for all kinds of enable if - // - template - struct enabled - { - template - struct base - { - typedef T type; - }; - }; - - // - // For compilers that don't support "Substitution Failure Is Not An Error" - // enable_if falls back to always enabled. See comments - // on operator implementation for consequences. - // - template<> - struct enabled - { - template - struct base - { -#ifdef BOOST_NO_SFINAE - - typedef T type; - - // This way to do it would give a nice error messages containing - // invalid overload, but has the big disadvantage that - // there is no reference to user code in the error message. - // - // struct invalid_overload; - // typedef invalid_overload type; - // -#endif - }; - }; - - // - // Meta function that determines whether two - // iterator types are considered interoperable. - // - // Two iterator types A,B are considered interoperable if either - // A is convertible to B or vice versa. - // This interoperability definition is in sync with the - // standards requirements on constant/mutable container - // iterators (23.1 [lib.container.requirements]). - // - // For compilers that don't support is_convertible - // is_interoperable gives false positives. See comments - // on operator implementation for consequences. - // - template - struct is_interoperable -#if defined(BOOST_NO_IS_CONVERTIBLE) - : mpl::true_c -#else - : mpl::logical_or< - is_convertible< A, B > - , is_convertible< B, A > > -#endif - { - }; - - // - // enable if for use in operator implementation. - // - // enable_if_interoperable falls back to always enabled for compilers - // that don't support enable_if or is_convertible. - // - template - struct enable_if_interoperable -# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE) - : detail::enabled< - ::boost::detail::is_interoperable::value - >::template base -# else - : mpl::identity -# endif - { -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) - typedef Return type; -# endif - }; - - // - // Result type used in enable_if_convertible meta function. - // This can be an incomplete type, as only pointers to - // enable_if_convertible< ... >::type are used. - // We could have used void for this, but conversion to - // void* is just to easy. - // - struct enable_type; - -#if 0 - // traits_iterator has two important properties: - // - // 1. It is derived from boost::iterator<...>, which is - // important for standard library interoperability of - // iterator types on some (broken) implementations. - // - // 2. The associated types are taken from iterator_traits. - // - // It might arguably be better to arrange for - // boost::detail::iterator_traits to be derived from - // boost::iterator<...>, then we could use - // boost::detail::iterator_traits directly. - template - struct traits_iterator - : iterator< - typename iterator_traits::iterator_category - , typename iterator_traits::value_type - , typename iterator_traits::difference_type - , typename iterator_traits::pointer - , typename iterator_traits::reference - > - { - }; -#endif - - template - struct std_iterator_from_traits - : iterator< - typename Traits::iterator_category - , typename Traits::value_type - , typename Traits::difference_type - , typename Traits::pointer - , typename Traits::reference - > - { - }; - - // - // I bet this is defined somewhere else. Let's wait and see. - // - struct error_type; - -#ifdef BOOST_NO_IS_CONVERTIBLE - template - struct minimum_return_category - : mpl::if_< is_return_category< Cat1 >::template is_category< Cat2 >, - Cat1, - mpl::if_< is_return_category::template is_category, - Cat2, - error_type - > - > {}; - - template - struct minimum_traversal_category - : mpl::if_< is_traversal_category< Cat1 >::template is_category< Cat2 >, - Cat1, - mpl::if_< is_traversal_category::template is_category, - Cat2, - error_type - > - > {}; - - template - struct minimum_category_select - : mpl::if_< is_same< typename T1::type, error_type >, - T2, - T1 > - {}; -#endif - - // - // Returns the minimum category type or error_type - // if T1 and T2 are unrelated. - // - // For compilers not supporting is_convertible this only - // works with the new boost return and traversal category - // types. The exect boost _types_ are required. No derived types - // will work. - // - // - template - struct minimum_category : -#ifndef BOOST_NO_IS_CONVERTIBLE - // We may need a VC7.1 is_same shortcut here - mpl::if_< is_base_and_derived< T1, T2 >, - T1, - mpl::if_< is_base_and_derived< T2, T1 >, - T2, - error_type > > -#else - minimum_category_select< minimum_return_category, - minimum_traversal_category > -#endif - {}; - - } // namespace detail - - // - // enable_if for use in adapted iterators constructors. - // - // In order to provide interoperability between adapted constant and - // mutable iterators, adapted iterators will usually provide templated - // conversion constructors of the following form - // - // template - // class adapted_iterator : - // public iterator_adaptor< adapted_iterator, Iterator > - // { - // public: - // - // ... - // - // template - // adapted_iterator(OtherIterator const& it, - // typename enable_if_convertible::type* = 0); - // - // ... - // }; - // - // enable_if_convertible is used to remove those overloads from the overload - // set that cannot be instantiated. For all practical purposes only overloads - // for constant/mutable interaction will remain. This has the advantage that - // meta functions like boost::is_convertible do not return false positives, - // as they can only look at the signature of the conversion constructor - // and not at the actual instantiation. - // - // enable_if_interoperable can be safely used in user code. It falls back to - // always enabled for compilers that don't support enable_if or is_convertible. - // There is no need for compiler specific workarounds in user code. - // - // The operators implementation relies on boost::is_convertible not returning - // false positives for user/library defined iterator types. See comments - // on operator implementation for consequences. - // - template< - typename From - , typename To> - struct enable_if_convertible - { - // Borland 551 and vc6 have a problem with the use of base class - // forwarding in this template, so we write it all out here -# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) - typedef detail::enable_type type; -# else - typedef typename detail::enabled< -# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292) && BOOST_MSVC > 1300) - // For some reason vc7.1 needs us to "cut off" instantiation - // of is_convertible in the case where From == To. - mpl::logical_or, is_convertible >::value -# else - ::boost::is_convertible::value -# endif - >::template base::type type; -# endif - }; - - // - // Helper class for granting access to the iterator core interface. - // - // The simple core interface is used by iterator_facade. The core - // interface of a user/library defined iterator type should not be made public - // so that it does not clutter the public interface. Instead iterator_core_access - // should be made friend so that iterator_facade can access the core - // interface through iterator_core_access. - // - struct iterator_core_access - { - template - static typename Facade::reference dereference(Facade const& f) - { - return f.dereference(); - } - - template - static void increment(Facade& f) - { - f.increment(); - } - - template - static void decrement(Facade& f) - { - f.decrement(); - } - - template - static bool equal(Facade1 const& f1, Facade2 const& f2, Facade1* = 0, Facade2* = 0) - { - return f1.equal(f2); - } - - template - static void advance(Facade& f, typename Facade::difference_type n) - { - f.advance(n); - } - - template - static typename Facade1::difference_type distance_to(Facade1 const& f1, - Facade2 const& f2, - Facade1* = 0, - Facade2* = 0) - { - return f1.distance_to(f2); - } - }; - - namespace detail - { - struct empty_base {}; - } - - // Encapsulates the "Curiously Recursive Template" pattern. - // Derived should be a class derived from this instantiation, and - // Base will be inserted as a base class. - template - class downcastable - : public Base - { - public: - typedef Derived derived_t; - - Derived& derived() - { - return static_cast(*this); - } - - Derived const& derived() const - { - return static_cast(*this); - } - }; - - template - class iterator_comparisons - : public Base - { - }; - - // - // Operator implementation. The library supplied operators - // enables the user to provide fully interoperable constant/mutable - // iterator types. I.e. the library provides all operators - // for all mutable/constant iterator combinations. - // - // Note though that this kind of interoperability for constant/mutable - // iterators is not required by the standard for container iterators. - // All the standard asks for is a conversion mutable -> constant. - // Most standard library implementations nowadays provide fully interoperable - // iterator implementations, but there are still heavily used implementations - // that do not provide them. (Actually it's even worse, they do not provide - // them for only a few iterators.) - // - // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should - // enable the user to turn off mixed type operators - // - // The library takes care to provide only the right operator overloads. - // I.e. - // - // bool operator==(Iterator, Iterator); - // bool operator==(ConstIterator, Iterator); - // bool operator==(Iterator, ConstIterator); - // bool operator==(ConstIterator, ConstIterator); - // - // ... - // - // In order to do so it uses c++ idioms that are not yet widely supported - // by current compiler releases. The library is designed to degrade gracefully - // in the face of compiler deficiencies. In general compiler - // deficiencies result in less strict error checking and more obscure - // error messages, functionality is not affected. - // - // For full operation compiler support for "Substitution Failure Is Not An Error" - // (aka. enable_if) and boost::is_convertible is required. - // - // The following problems occur if support is lacking. - // - // Pseudo code - // - // --------------- - // AdaptorA a1; - // AdaptorA a2; - // - // // This will result in a no such overload error in full operation - // // If enable_if or is_convertible is not supported - // // The instantiation will fail with an error hopefully indicating that - // // there is no operator== for Iterator1, Iterator2 - // // The same will happen if no enable_if is used to remove - // // false overloads from the templated conversion constructor - // // of AdaptorA. - // - // a1 == a2; - // ---------------- - // - // AdaptorA a; - // AdaptorB b; - // - // // This will result in a no such overload error in full operation - // // If enable_if is not supported the static assert used - // // in the operator implementation will fail. - // // This will accidently work if is_convertible is not supported. - // - // a == b; - // ---------------- - // - template - inline - typename detail::enable_if_interoperable::type - operator==(iterator_comparisons const& lhs, - iterator_comparisons const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - return iterator_core_access::equal(lhs.derived(), - rhs.derived()); - } - - template - inline - typename detail::enable_if_interoperable::type - operator!=(iterator_comparisons const& lhs, - iterator_comparisons const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - return !iterator_core_access::equal(lhs.derived(), - rhs.derived()); - } - - template - inline - typename detail::enable_if_interoperable::type - operator<(iterator_comparisons const& lhs, - iterator_comparisons const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - return iterator_core_access::distance_to(lhs.derived(), - rhs.derived()) > 0; - } - - template - inline - typename detail::enable_if_interoperable::type - operator>(iterator_comparisons const& lhs, - iterator_comparisons const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - return iterator_core_access::distance_to(lhs.derived(), - rhs.derived()) < 0; - } - - template - inline - typename detail::enable_if_interoperable::type - operator<=(iterator_comparisons const& lhs, - iterator_comparisons const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - return iterator_core_access::distance_to(lhs.derived(), - rhs.derived()) >= 0; - } - - template - inline - typename detail::enable_if_interoperable::type - operator>=(iterator_comparisons const& lhs, - iterator_comparisons const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - return iterator_core_access::distance_to(lhs.derived(), - rhs.derived()) <= 0; - } - - - template - class iterator_arith : - public Base - { - }; - - template - inline - typename Base::derived_t operator+(iterator_arith const& i, - typename Base::difference_type n) - { - typename Base::derived_t tmp(i.derived()); - return tmp += n; - } - - template - inline - typename Base::derived_t operator+(typename Base::difference_type n, - iterator_arith const& i) - { - typename Base::derived_t tmp(i.derived()); - return tmp += n; - } - - template - inline - typename detail::enable_if_interoperable< - typename Base1::derived_t - , typename Base2::derived_t - , typename Base1::difference_type - >::type - operator-(iterator_arith const& lhs, - iterator_arith const& rhs) - { - // For those compilers that do not support enable_if - BOOST_STATIC_ASSERT((detail::is_interoperable< - BOOST_ARG_DEP_TYPENAME Base1::derived_t, - BOOST_ARG_DEP_TYPENAME Base2::derived_t >::value)); - - BOOST_STATIC_ASSERT((is_same::value)); - - return iterator_core_access::distance_to(rhs.derived(), - lhs.derived()); - } - - // - // - // iterator_facade applies iterator_traits_adaptor to it's traits argument. - // The net effect is that iterator_facade is derived from std::iterator. This - // is important for standard library interoperability of iterator types on some - // (broken) implementations. - // - template < - class Derived - , class Traits - > - class iterator_facade - : public iterator_arith< - iterator_comparisons< - downcastable > > > - { - typedef iterator_arith< - iterator_comparisons< - downcastable > > > super_t; - public: - typedef typename super_t::reference reference; - typedef typename super_t::difference_type difference_type; - typedef typename super_t::pointer pointer; - - reference operator*() const - { return iterator_core_access::dereference(this->derived()); } - - // Needs eventual help for input iterators - pointer operator->() const { return &iterator_core_access::dereference(this->derived()); } - - reference operator[](difference_type n) const - { return *(*this + n); } - - Derived& operator++() - { iterator_core_access::increment(this->derived()); return this->derived(); } - - Derived operator++(int) - { Derived tmp(this->derived()); ++*this; return tmp; } - - Derived& operator--() - { iterator_core_access::decrement(this->derived()); return this->derived(); } - - Derived operator--(int) - { Derived tmp(this->derived()); --*this; return tmp; } - - Derived& operator+=(difference_type n) - { iterator_core_access::advance(this->derived(), n); return this->derived(); } - - Derived& operator-=(difference_type n) - { iterator_core_access::advance(this->derived(), -n); return this->derived(); } - - Derived operator-(difference_type x) const - { Derived result(this->derived()); return result -= x; } - }; - - namespace detail - { - template - struct same_category_and_difference - : mpl::logical_and< - is_same< - typename Traits::iterator_category - , typename Other::iterator_category - > - , is_same< - typename Traits::iterator_category - , typename Other::iterator_category - > - > - {}; - } - - // - // iterator_traits_adaptor can be used to create new iterator traits by adapting - // the traits of a given iterator type. Together with iterator_adaptor it simplifies - // the creation of adapted iterator types. Therefore the ordering the template - // argument ordering is different from the std::iterator template, so that default - // arguments can be used effectivly. - // - template ::value_type, - class Reference = ValueType&, - class Pointer = ValueType*, - class IteratorCategory = typename detail::iterator_traits::iterator_category, - class DifferenceType = typename detail::iterator_traits::difference_type > - struct iterator_traits_adaptor - : iterator - { - }; - - // - // - // - template < - class Derived - , class Iterator - , class Traits = detail::iterator_traits - > - class iterator_adaptor - : public iterator_facade - { - friend class iterator_core_access; - - public: - iterator_adaptor() {} - - explicit iterator_adaptor(Iterator iter) - : m_iterator(iter) - { - } - - Iterator base() const { return m_iterator; } - - protected: - // Core iterator interface for iterator_facade - // - - typename Traits::reference dereference() const { return *m_iterator; } - - template < - class OtherDerived, class OtherIterator, class OtherTraits - > - bool equal(iterator_adaptor const& x) const - { - BOOST_STATIC_ASSERT( - (detail::same_category_and_difference::value) - ); - return m_iterator == x.base(); - } - - void advance(typename Traits::difference_type n) - { - m_iterator += n; - } - - void increment() { ++m_iterator; } - void decrement() { --m_iterator; } - - template - typename Traits::difference_type distance_to( - iterator_adaptor const& y) const - { - BOOST_STATIC_ASSERT( - (detail::same_category_and_difference::value) - ); - return y.base() - m_iterator; - } - - private: // data members - Iterator m_iterator; - - }; - - // - // - // - template - class reverse_iterator : - public iterator_adaptor< reverse_iterator, Iterator > - { - typedef iterator_adaptor< reverse_iterator, Iterator > super_t; - - friend class iterator_core_access; - - public: - reverse_iterator() {} - - explicit reverse_iterator(Iterator x) - : super_t(x) {} - - template - reverse_iterator( - reverse_iterator const& r - , typename enable_if_convertible::type* = 0 - ) - : super_t(r.base()) {} - - private: - typename super_t::reference dereference() const { return *boost::prior(this->base()); } - - void increment() { super_t::decrement(); } - void decrement() { super_t::increment(); } - - void advance(typename super_t::difference_type n) - { - super_t::advance(-n); - } - - template - typename super_t::difference_type - distance_to(reverse_iterator const& y) const - { - return -super_t::distance_to(y); - } - }; - - template - reverse_iterator make_reverse_iterator(BidirectionalIterator x) - { - return reverse_iterator(x); - } - - // Given the transform iterator's transformation and iterator, this - // is the type used as its traits. - template - struct transform_iterator_traits - : iterator_traits_adaptor::type > > - { - }; - - // - template - class transform_iterator - : public iterator_adaptor< - transform_iterator - , Iterator - , transform_iterator_traits - > - { - typedef iterator_adaptor< - transform_iterator - , Iterator - , transform_iterator_traits - > super_t; - - friend class iterator_core_access; - - public: - transform_iterator() { } - - transform_iterator(Iterator const& x, - AdaptableUnaryFunction f) - : super_t(x), m_f(f) { } - - template - transform_iterator( - transform_iterator const& t - , typename enable_if_convertible::type* = 0 - ) - : super_t(t.base()), m_f(t.functor()) {} - - AdaptableUnaryFunction functor() const { return m_f; } - - private: - typename super_t::value_type dereference() const { return m_f(super_t::dereference()); } - - // Probably should be the initial base class so it can be - // optimized away via EBO if it is an empty class. - AdaptableUnaryFunction m_f; - }; - - struct unspecified {}; - - namespace detail - { - // - // Detection for whether a type has a nested `element_type' - // typedef. Used to detect smart pointers. For compilers not - // supporting mpl's has_xxx, we supply specializations. However, we - // really ought to have a specializable is_pointer template which - // can be used instead with something like - // boost/python/pointee.hpp to find the value_type. - // -# if !defined BOOST_NO_MPL_AUX_HAS_XXX - namespace aux - { - BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) - } - - template - struct has_element_type - : mpl::if_< - is_class - , aux::has_element_type - , mpl::false_c - >::type - { - }; -# else - template - struct has_element_type - : mpl::false_c {}; - - template - struct has_element_type > - : mpl::true_c {}; - - template - struct has_element_type > - : mpl::true_c {}; - - template - struct has_element_type > - : mpl::true_c {}; -# endif - - // Metafunction returning the nested element_type typedef - template - struct smart_pointer_traits - { - typedef typename remove_const< - typename T::element_type - >::type value_type; - - typedef typename T::element_type& reference; - typedef typename T::element_type* pointer; - }; - - // If the Value parameter is unspecified, we use this metafunction - // to deduce the default types - template - struct indirect_defaults - : mpl::if_< - has_element_type::value_type> - , smart_pointer_traits::value_type> - , iterator_traits::value_type> - >::type - { - typedef typename iterator_traits::iterator_category iterator_category; - typedef typename iterator_traits::difference_type difference_type; - }; - - // The traits to use for indirect iterator, by default. Whatever - // is supplied gets passed through traits_iterator<...> so that it - // is ultimately derived from boost::iterator<...> - template - struct indirect_traits - : mpl::if_< - is_same - , indirect_defaults - , Traits - >::type - { - }; - } // namespace detail - - template - class indirect_iterator : - public iterator_adaptor< - indirect_iterator - , Iterator - , detail::indirect_traits > - { - typedef iterator_adaptor< - indirect_iterator - , Iterator - , detail::indirect_traits - > super_t; - - friend class iterator_core_access; - - public: - indirect_iterator() {} - - indirect_iterator(Iterator iter) - : super_t(iter) {} - - template - indirect_iterator( - indirect_iterator const& y - , typename enable_if_convertible::type* = 0 - ) - : super_t(y.base()) - {} - - private: - typename super_t::reference dereference() const { return **this->base(); } - - }; - - template - inline - indirect_iterator make_indirect_iterator(Iter x) - { - return indirect_iterator(x); - } - - template - inline - indirect_iterator make_indirect_iterator(Iter x, Traits* = 0) - { - return indirect_iterator(x); - } - - namespace detail { - - template - struct filter_iterator_traits - : iterator_traits - { - typedef iterator_tag< - typename return_category::type - , minimum_category< forward_traversal_tag - ,typename traversal_category::type >::type - > iterator_category; - }; - - } // namespace detail - - template - class filter_iterator - : public iterator_adaptor< - filter_iterator, Iterator - , detail::filter_iterator_traits - > - { - typedef iterator_adaptor< - filter_iterator, Iterator - , detail::filter_iterator_traits - > super_t; - - friend class iterator_core_access; - - public: - filter_iterator() { } - - filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) - : super_t(x), m_predicate(f), m_end(end) - { - satisfy_predicate(); - } - - filter_iterator(Iterator x, Iterator end = Iterator()) - : super_t(x), m_predicate(), m_end(end) - { - satisfy_predicate(); - } - - template - filter_iterator( - filter_iterator const& t - , typename enable_if_convertible::type* = 0 - ) - : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {} - - Predicate predicate() const { return m_predicate; } - - Iterator end() const { return m_end; } - - private: - void increment() - { - super_t::increment(); - satisfy_predicate(); - } - - void satisfy_predicate() - { - while (this->base() != this->m_end && !this->m_predicate(*this->base())) - super_t::increment(); - } - - // Probably should be the initial base class so it can be - // optimized away via EBO if it is an empty class. - Predicate m_predicate; - Iterator m_end; - }; - - template - filter_iterator - make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) - { - return filter_iterator(f,x,end); - } -} // namespace boost - -// -// clean up local workaround macros -// - -# undef BOOST_NO_SFINAE -# undef BOOST_ARG_DEP_TYPENAME -# undef BOOST_NO_IS_CONVERTIBLE -# undef BOOST_NO_MPL_AUX_HAS_XXX - -#endif // BOOST_ITERATOR_ADAPTORS_HPP diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp new file mode 100644 index 0000000..a2cc1f4 --- /dev/null +++ b/include/boost/iterator/iterator_facade.hpp @@ -0,0 +1,411 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_FACADE_23022003THW_HPP +#define BOOST_ITERATOR_FACADE_23022003THW_HPP + +#include +#include +#include +#include + +#include +#include + +#include + +namespace boost +{ + + namespace detail + { + + // + // enable if for use in operator implementation. + // + // enable_if_interoperable falls back to always enabled for compilers + // that don't support enable_if or is_convertible. + // + template + struct enable_if_interoperable : + ::boost::detail::enable_if< is_convertible< Facade1, Facade2 > + , Return > + { +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) + typedef Return type; +# endif + }; + + + // + // Type generator. + // Generates the corresponding std::iterator specialization + // from the given iterator traits type + // + template + struct std_iterator_from_traits + : iterator< + typename Traits::iterator_category + , typename Traits::value_type + , typename Traits::difference_type + , typename Traits::pointer + , typename Traits::reference + > + { + }; + + + } // namespace detail + + + // + // Helper class for granting access to the iterator core interface. + // + // The simple core interface is used by iterator_facade. The core + // interface of a user/library defined iterator type should not be made public + // so that it does not clutter the public interface. Instead iterator_core_access + // should be made friend so that iterator_facade can access the core + // interface through iterator_core_access. + // + struct iterator_core_access + { + template + static typename Facade::reference dereference(Facade const& f) + { + return f.dereference(); + } + + template + static void increment(Facade& f) + { + f.increment(); + } + + template + static void decrement(Facade& f) + { + f.decrement(); + } + + template + static bool equal(Facade1 const& f1, Facade2 const& f2, Facade1* = 0, Facade2* = 0) + { + return f1.equal(f2); + } + + template + static void advance(Facade& f, typename Facade::difference_type n) + { + f.advance(n); + } + + template + static typename Facade1::difference_type distance_to(Facade1 const& f1, + Facade2 const& f2, + Facade1* = 0, + Facade2* = 0) + { + return f1.distance_to(f2); + } + + private: + // objects of this class are useless + iterator_core_access(); //undefined + }; + + // + // + // iterator_facade applies iterator_traits_adaptor to it's traits argument. + // The net effect is that iterator_facade is derived from std::iterator. This + // is important for standard library interoperability of iterator types on some + // (broken) implementations. + // + template < + class Derived + , class Traits + > + class iterator_facade + : detail::std_iterator_from_traits + { + typedef detail::std_iterator_from_traits super_t; + + public: + // + // CRT interface. There is no simple way to remove this + // from the public interface without template friends + // + typedef Derived derived_t; + + Derived& derived() + { + return static_cast(*this); + } + + Derived const& derived() const + { + return static_cast(*this); + } + + + typedef typename super_t::reference reference; + typedef typename super_t::difference_type difference_type; + typedef typename super_t::pointer pointer; + + reference operator*() const + { return iterator_core_access::dereference(this->derived()); } + + // Needs eventual help for input iterators + pointer operator->() const { return &iterator_core_access::dereference(this->derived()); } + + reference operator[](difference_type n) const + { return *(*this + n); } + + Derived& operator++() + { iterator_core_access::increment(this->derived()); return this->derived(); } + + Derived operator++(int) + { Derived tmp(this->derived()); ++*this; return tmp; } + + Derived& operator--() + { iterator_core_access::decrement(this->derived()); return this->derived(); } + + Derived operator--(int) + { Derived tmp(this->derived()); --*this; return tmp; } + + Derived& operator+=(difference_type n) + { iterator_core_access::advance(this->derived(), n); return this->derived(); } + + Derived& operator-=(difference_type n) + { iterator_core_access::advance(this->derived(), -n); return this->derived(); } + + Derived operator-(difference_type x) const + { Derived result(this->derived()); return result -= x; } + }; + + // + // Operator implementation. The library supplied operators + // enables the user to provide fully interoperable constant/mutable + // iterator types. I.e. the library provides all operators + // for all mutable/constant iterator combinations. + // + // Note though that this kind of interoperability for constant/mutable + // iterators is not required by the standard for container iterators. + // All the standard asks for is a conversion mutable -> constant. + // Most standard library implementations nowadays provide fully interoperable + // iterator implementations, but there are still heavily used implementations + // that do not provide them. (Actually it's even worse, they do not provide + // them for only a few iterators.) + // + // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should + // enable the user to turn off mixed type operators + // + // The library takes care to provide only the right operator overloads. + // I.e. + // + // bool operator==(Iterator, Iterator); + // bool operator==(ConstIterator, Iterator); + // bool operator==(Iterator, ConstIterator); + // bool operator==(ConstIterator, ConstIterator); + // + // ... + // + // In order to do so it uses c++ idioms that are not yet widely supported + // by current compiler releases. The library is designed to degrade gracefully + // in the face of compiler deficiencies. In general compiler + // deficiencies result in less strict error checking and more obscure + // error messages, functionality is not affected. + // + // For full operation compiler support for "Substitution Failure Is Not An Error" + // (aka. enable_if) and boost::is_convertible is required. + // + // The following problems occur if support is lacking. + // + // Pseudo code + // + // --------------- + // AdaptorA a1; + // AdaptorA a2; + // + // // This will result in a no such overload error in full operation + // // If enable_if or is_convertible is not supported + // // The instantiation will fail with an error hopefully indicating that + // // there is no operator== for Iterator1, Iterator2 + // // The same will happen if no enable_if is used to remove + // // false overloads from the templated conversion constructor + // // of AdaptorA. + // + // a1 == a2; + // ---------------- + // + // AdaptorA a; + // AdaptorB b; + // + // // This will result in a no such overload error in full operation + // // If enable_if is not supported the static assert used + // // in the operator implementation will fail. + // // This will accidently work if is_convertible is not supported. + // + // a == b; + // ---------------- + // + template + inline + typename detail::enable_if_interoperable::type + operator==(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + return iterator_core_access::equal(lhs.derived(), + rhs.derived()); + } + + template + inline + typename detail::enable_if_interoperable::type + operator!=(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + return !iterator_core_access::equal(lhs.derived(), + rhs.derived()); + } + + template + inline + typename detail::enable_if_interoperable::type + operator<(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) > 0; + } + + template + inline + typename detail::enable_if_interoperable::type + operator>(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) < 0; + } + + template + inline + typename detail::enable_if_interoperable::type + operator<=(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) >= 0; + } + + template + inline + typename detail::enable_if_interoperable::type + operator>=(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + return iterator_core_access::distance_to(lhs.derived(), + rhs.derived()) <= 0; + } + + template + inline + Derived operator+(iterator_facade const& i, + typename Traits::difference_type n) + { + Derived tmp(i.derived()); + return tmp += n; + } + + template + inline + Derived operator+(typename Traits::difference_type n, + iterator_facade const& i) + { + Derived tmp(i.derived()); + return tmp += n; + } + + template + inline + typename detail::enable_if_interoperable::type + operator-(iterator_facade const& lhs, + iterator_facade const& rhs) + { + // For those compilers that do not support enable_if + BOOST_STATIC_ASSERT((is_interoperable< Derived1, Derived2 >::value)); + + BOOST_STATIC_ASSERT((is_same::value)); + + return iterator_core_access::distance_to(rhs.derived(), + lhs.derived()); + } + +} // namespace boost + +#include + +#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP diff --git a/include/boost/iterator/reverse_iterator.hpp b/include/boost/iterator/reverse_iterator.hpp new file mode 100644 index 0000000..85cb394 --- /dev/null +++ b/include/boost/iterator/reverse_iterator.hpp @@ -0,0 +1,70 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_REVERSE_ITERATOR_23022003THW_HPP +#define BOOST_REVERSE_ITERATOR_23022003THW_HPP + +#include +#include +#include + +namespace boost +{ + + // + // + // + template + class reverse_iterator : + public iterator_adaptor< reverse_iterator, Iterator > + { + typedef iterator_adaptor< reverse_iterator, Iterator > super_t; + + friend class iterator_core_access; + + public: + reverse_iterator() {} + + explicit reverse_iterator(Iterator x) + : super_t(x) {} + + template + reverse_iterator( + reverse_iterator const& r + , typename enable_if_convertible::type* = 0 + ) + : super_t(r.base()) {} + + private: + typename super_t::reference dereference() const { return *boost::prior(this->base()); } + + void increment() { super_t::decrement(); } + void decrement() { super_t::increment(); } + + void advance(typename super_t::difference_type n) + { + super_t::advance(-n); + } + + template + typename super_t::difference_type + distance_to(reverse_iterator const& y) const + { + return -super_t::distance_to(y); + } + }; + + template + reverse_iterator make_reverse_iterator(BidirectionalIterator x) + { + return reverse_iterator(x); + } + +} // namespace boost + +#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP diff --git a/include/boost/iterator/transform_iterator.hpp b/include/boost/iterator/transform_iterator.hpp new file mode 100644 index 0000000..b5602c3 --- /dev/null +++ b/include/boost/iterator/transform_iterator.hpp @@ -0,0 +1,80 @@ +// (C) Copyright David Abrahams 2002. +// (C) Copyright Jeremy Siek 2002. +// (C) Copyright Thomas Witt 2002. +// 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_TRANSFORM_ITERATOR_23022003THW_HPP +#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP + +#include +#include +#include + +namespace boost +{ + + namespace detail + { + + // Given the transform iterator's transformation and iterator, this + // is the type used as its traits. + template + struct transform_iterator_traits + : iterator_traits_adaptor::type > > + { + }; + + } // transform_iterator_traits + + // + template + class transform_iterator + : public iterator_adaptor< + transform_iterator + , Iterator + , detail::transform_iterator_traits + > + { + typedef iterator_adaptor< + transform_iterator + , Iterator + , detail::transform_iterator_traits + > super_t; + + friend class iterator_core_access; + + public: + transform_iterator() { } + + transform_iterator(Iterator const& x, + AdaptableUnaryFunction f) + : super_t(x), m_f(f) { } + + template + transform_iterator( + transform_iterator const& t + , typename enable_if_convertible::type* = 0 + ) + : super_t(t.base()), m_f(t.functor()) {} + + AdaptableUnaryFunction functor() const { return m_f; } + + private: + typename super_t::value_type dereference() const { return m_f(super_t::dereference()); } + + // Probably should be the initial base class so it can be + // optimized away via EBO if it is an empty class. + AdaptableUnaryFunction m_f; + }; + +} // namespace boost + +#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP diff --git a/test/filter_iterator_test.cpp b/test/filter_iterator_test.cpp index b1f285d..ea34b6d 100644 --- a/test/filter_iterator_test.cpp +++ b/test/filter_iterator_test.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include diff --git a/test/indirect_iterator_test.cpp b/test/indirect_iterator_test.cpp index ffbfb85..1708e1e 100644 --- a/test/indirect_iterator_test.cpp +++ b/test/indirect_iterator_test.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/test/interoperable_fail.cpp b/test/interoperable_fail.cpp index f7920c4..ca5bae5 100644 --- a/test/interoperable_fail.cpp +++ b/test/interoperable_fail.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include #include diff --git a/test/is_convertible_fail.cpp b/test/is_convertible_fail.cpp index 933ff38..3411a31 100644 --- a/test/is_convertible_fail.cpp +++ b/test/is_convertible_fail.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/test/iterator_adaptor_cc.cpp b/test/iterator_adaptor_cc.cpp index 3cb3342..b4a472c 100644 --- a/test/iterator_adaptor_cc.cpp +++ b/test/iterator_adaptor_cc.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/test/iterator_adaptor_test.cpp b/test/iterator_adaptor_test.cpp index 24476bb..d72725b 100644 --- a/test/iterator_adaptor_test.cpp +++ b/test/iterator_adaptor_test.cpp @@ -62,7 +62,7 @@ #include #endif -#include +#include #include #include diff --git a/test/transform_iterator_test.cpp b/test/transform_iterator_test.cpp index ceba3dc..de3f496 100644 --- a/test/transform_iterator_test.cpp +++ b/test/transform_iterator_test.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include