From 8e5b8025d8fa05c72403b946d6748c86923431b0 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 6 Jun 2014 00:56:20 +0100 Subject: [PATCH] Revert changes that were merged to master. Reverted: 2e099caceb9..21102938e8ccb I'm going to reapply some of them soon, but it's easier to revert them all first, as there are conflicts. Also the number of changes that were inserted since then, mean that there would be a huge gap between related changes. --- doc/iterator_facade_ref.rst | 2 +- include/boost/iterator/detail/config_def.hpp | 19 +- .../boost/iterator/detail/config_undef.hpp | 1 + include/boost/iterator/detail/enable_if.hpp | 3 + .../detail/facade_iterator_category.hpp | 15 +- .../iterator/detail/minimum_category.hpp | 26 ++- include/boost/iterator/filter_iterator.hpp | 6 +- include/boost/iterator/iterator_adaptor.hpp | 21 +- .../boost/iterator/iterator_archetypes.hpp | 53 +++-- .../boost/iterator/iterator_categories.hpp | 16 ++ include/boost/iterator/iterator_facade.hpp | 217 +++++++++++++++--- include/boost/iterator/iterator_traits.hpp | 48 +++- include/boost/iterator/transform_iterator.hpp | 17 ++ include/boost/iterator/zip_iterator.hpp | 15 ++ include/boost/pending/iterator_tests.hpp | 3 + test/Jamfile.v2 | 3 +- test/indirect_iter_member_types.cpp | 4 +- test/indirect_iterator_test.cpp | 3 + test/is_lvalue_iterator.cpp | 4 + test/is_readable_iterator.cpp | 3 + test/iterator_adaptor_test.cpp | 2 + test/pointee.cpp | 1 + test/unit_tests.cpp | 3 + 23 files changed, 417 insertions(+), 68 deletions(-) mode change 100644 => 100755 include/boost/iterator/detail/facade_iterator_category.hpp mode change 100644 => 100755 include/boost/iterator/detail/minimum_category.hpp mode change 100644 => 100755 test/is_lvalue_iterator.cpp mode change 100644 => 100755 test/is_readable_iterator.cpp mode change 100644 => 100755 test/pointee.cpp diff --git a/doc/iterator_facade_ref.rst b/doc/iterator_facade_ref.rst index 87c032a..c1baf9b 100644 --- a/doc/iterator_facade_ref.rst +++ b/doc/iterator_facade_ref.rst @@ -106,7 +106,7 @@ The ``iterator_category`` member of ``iterator_facade`` is .. parsed-literal:: - *iterator-category*\ (CategoryOrTraversal, reference, value_type) + *iterator-category*\ (CategoryOrTraversal, value_type, reference) where *iterator-category* is defined as follows: diff --git a/include/boost/iterator/detail/config_def.hpp b/include/boost/iterator/detail/config_def.hpp index 5101e84..fa8d667 100644 --- a/include/boost/iterator/detail/config_def.hpp +++ b/include/boost/iterator/detail/config_def.hpp @@ -26,7 +26,7 @@ // libs/iterator/test/constant_iterator_arrow.cpp fails to compile // because the operator-> return is improperly deduced as a non-const // pointer. -#if 1 \ +#if 1 || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) // Recall that in general, compilers without partial specialization @@ -46,7 +46,8 @@ #endif -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x5A0)) \ +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x5A0)) \ || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \ || BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) \ || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) @@ -87,7 +88,8 @@ # define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types" #endif -#if BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \ +#if BOOST_WORKAROUND(__GNUC__, == 2) \ + || BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) # define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile: @@ -114,9 +116,16 @@ # define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY #endif -# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# define BOOST_ARG_DEPENDENT_TYPENAME typename +# else +# define BOOST_ARG_DEPENDENT_TYPENAME +# endif -// GCC-2.95 (obsolete) eagerly instantiates templated constructors and conversion +# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +// GCC-2.95 eagerly instantiates templated constructors and conversion // operators in convertibility checks, causing premature errors. // // Borland's problems are harder to diagnose due to lack of an diff --git a/include/boost/iterator/detail/config_undef.hpp b/include/boost/iterator/detail/config_undef.hpp index bf1b8d7..9dcd1d5 100644 --- a/include/boost/iterator/detail/config_undef.hpp +++ b/include/boost/iterator/detail/config_undef.hpp @@ -14,6 +14,7 @@ #undef BOOST_NO_IS_CONVERTIBLE #undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE #undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY +#undef BOOST_ARG_DEPENDENT_TYPENAME #undef BOOST_NO_LVALUE_RETURN_DETECTION #undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP diff --git a/include/boost/iterator/detail/enable_if.hpp b/include/boost/iterator/detail/enable_if.hpp index dee66ba..0fd36fc 100644 --- a/include/boost/iterator/detail/enable_if.hpp +++ b/include/boost/iterator/detail/enable_if.hpp @@ -72,6 +72,9 @@ namespace boost : mpl::identity # endif { +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + typedef Return type; +# endif }; } // namespace iterators diff --git a/include/boost/iterator/detail/facade_iterator_category.hpp b/include/boost/iterator/detail/facade_iterator_category.hpp old mode 100644 new mode 100755 index 31915e3..2c4771d --- a/include/boost/iterator/detail/facade_iterator_category.hpp +++ b/include/boost/iterator/detail/facade_iterator_category.hpp @@ -73,8 +73,15 @@ struct iterator_writability_disabled // Convert an iterator_facade's traversal category, Value parameter, // and ::reference type to an appropriate old-style category. // -// Due to changeset 21683, this now never results in a category convertible -// to output_iterator_tag. +// If writability has been disabled per the above metafunction, the +// result will not be convertible to output_iterator_tag. +// +// Otherwise, if Traversal == single_pass_traversal_tag, the following +// conditions will result in a tag that is convertible both to +// input_iterator_tag and output_iterator_tag: +// +// 1. Reference is a reference to non-const +// 2. Reference is not a reference and is convertible to Value // template struct iterator_facade_default_category @@ -131,6 +138,7 @@ template struct iterator_category_with_traversal : Category, Traversal { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // Make sure this isn't used to build any categories where // convertibility to Traversal is redundant. Should just use the // Category element in that case. @@ -146,6 +154,7 @@ struct iterator_category_with_traversal # if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) BOOST_MPL_ASSERT((is_iterator_traversal)); # endif +# endif }; // Computes an iterator_category tag whose traversal is Traversal and @@ -153,7 +162,9 @@ struct iterator_category_with_traversal template struct facade_iterator_category_impl { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) BOOST_MPL_ASSERT_NOT((is_iterator_category)); +# endif typedef typename iterator_facade_default_category< Traversal,ValueParam,Reference diff --git a/include/boost/iterator/detail/minimum_category.hpp b/include/boost/iterator/detail/minimum_category.hpp old mode 100644 new mode 100755 index 1f4444f..96501dd --- a/include/boost/iterator/detail/minimum_category.hpp +++ b/include/boost/iterator/detail/minimum_category.hpp @@ -21,7 +21,17 @@ namespace boost { namespace detail { // // template -struct minimum_category_impl; +struct minimum_category_impl +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +{ + template struct apply + { + typedef T2 type; + }; + typedef void type; +} +# endif +; template struct error_not_related_by_convertibility; @@ -67,8 +77,14 @@ template struct minimum_category { typedef minimum_category_impl< +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround + is_same::value || +# endif ::boost::is_convertible::value , ::boost::is_convertible::value +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround + || is_same::value +# endif > outer; typedef typename outer::template apply inner; @@ -86,6 +102,14 @@ struct minimum_category BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2)) }; + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround +template <> +struct minimum_category +{ + typedef int type; +}; +# endif }} // namespace boost::detail diff --git a/include/boost/iterator/filter_iterator.hpp b/include/boost/iterator/filter_iterator.hpp index 4282acc..14d640b 100644 --- a/include/boost/iterator/filter_iterator.hpp +++ b/include/boost/iterator/filter_iterator.hpp @@ -121,7 +121,11 @@ namespace boost is_class , Iterator >::type x - , Iterator end = Iterator()) + , Iterator end = Iterator() +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + , Predicate* = 0 +#endif + ) { return filter_iterator(x,end); } diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp index 19f6774..9f2fbb0 100644 --- a/include/boost/iterator/iterator_adaptor.hpp +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -38,12 +38,14 @@ namespace boost // explicitly in order to specify that the default should be used. struct use_default; +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // the incompleteness of use_default causes massive problems for // is_convertible (naturally). This workaround is fortunately not // needed for vc6/vc7. template struct is_convertible : mpl::false_ {}; +# endif namespace detail { @@ -97,7 +99,22 @@ namespace boost // false positives for user/library defined iterator types. See comments // on operator implementation for consequences. // -# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + + template + struct enable_if_convertible + { + typedef typename mpl::if_< + mpl::or_< + is_same + , is_convertible + > + , boost::detail::enable_type + , int& + >::type type; + }; + +# elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) template struct enable_if_convertible @@ -105,7 +122,7 @@ namespace boost typedef boost::detail::enable_type type; }; -# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) +# elif 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 a few cases. diff --git a/include/boost/iterator/iterator_archetypes.hpp b/include/boost/iterator/iterator_archetypes.hpp index ef60d9c..039de1c 100644 --- a/include/boost/iterator/iterator_archetypes.hpp +++ b/include/boost/iterator/iterator_archetypes.hpp @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -118,24 +119,26 @@ namespace detail template struct operator_brackets - : mpl::eval_if< - is_convertible - , mpl::eval_if< - iterator_archetypes::has_access< - AccessCategory - , iterator_archetypes::writable_iterator_t - > - , mpl::identity > - , mpl::if_< + : mpl::aux::msvc_eti_base< + typename mpl::eval_if< + is_convertible + , mpl::eval_if< iterator_archetypes::has_access< AccessCategory - , iterator_archetypes::readable_iterator_t + , iterator_archetypes::writable_iterator_t + > + , mpl::identity > + , mpl::if_< + iterator_archetypes::has_access< + AccessCategory + , iterator_archetypes::readable_iterator_t + > + , readable_operator_brackets + , no_operator_brackets > - , readable_operator_brackets - , no_operator_brackets > - > - , mpl::identity + , mpl::identity + >::type >::type {}; @@ -151,7 +154,9 @@ namespace detail template struct traversal_archetype_ - : traversal_archetype_impl::template archetype + : mpl::aux::msvc_eti_base< + typename traversal_archetype_impl::template archetype + >::type { typedef typename traversal_archetype_impl::template archetype @@ -200,6 +205,12 @@ namespace detail bool operator==(traversal_archetype_ const&, traversal_archetype_ const&) { return true; } +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + // doesn't seem to pick up != from equality_comparable + template + bool operator!=(traversal_archetype_ const&, + traversal_archetype_ const&) { return true; } +#endif template <> struct traversal_archetype_impl { @@ -298,9 +309,11 @@ struct iterator_access_archetype_impl template struct iterator_access_archetype - : iterator_access_archetype_impl< - AccessCategory - >::template archetype + : mpl::aux::msvc_eti_base< + typename iterator_access_archetype_impl< + AccessCategory + >::template archetype + >::type { }; @@ -330,7 +343,9 @@ struct iterator_access_archetype_impl< template struct archetype { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) BOOST_STATIC_ASSERT(!is_const::value); +# endif typedef void value_type; typedef void reference; typedef void pointer; @@ -381,7 +396,9 @@ struct iterator_access_archetype_impl { +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) BOOST_STATIC_ASSERT((!is_const::value)); +# endif }; }; diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index 24bf4e2..1740d98 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -97,6 +97,14 @@ namespace detail > {}; +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template <> + struct old_category_to_traversal + { + typedef int type; + }; +# endif + template struct pure_traversal_tag : mpl::eval_if< @@ -123,6 +131,14 @@ namespace detail { }; +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template <> + struct pure_traversal_tag + { + typedef int type; + }; +# endif + } // namespace detail diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index 582f687..d84b402 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -1,7 +1,6 @@ // (C) Copyright David Abrahams 2002. // (C) Copyright Jeremy Siek 2002. // (C) Copyright Thomas Witt 2002. -// (C) copyright Jeffrey Lee Hellrung, Jr. 2012. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -14,7 +13,6 @@ #include #include -#include #include #include @@ -67,6 +65,18 @@ namespace boost , class Return > struct enable_if_interoperable +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + { + typedef typename mpl::if_< + mpl::or_< + is_convertible + , is_convertible + > + , Return + , int[3] + >::type type; + }; +#else : ::boost::iterators::enable_if< mpl::or_< is_convertible @@ -75,6 +85,7 @@ namespace boost , Return > {}; +#endif // // Generates associated types for an iterator_facade with the @@ -83,7 +94,7 @@ namespace boost template < class ValueParam , class CategoryOrTraversal - , class Reference + , class Reference , class Difference > struct iterator_facade_types @@ -91,17 +102,20 @@ namespace boost typedef typename facade_iterator_category< CategoryOrTraversal, ValueParam, Reference >::type iterator_category; - + typedef typename remove_const::type value_type; - + // Not the real associated pointer type typedef typename mpl::eval_if< boost::detail::iterator_writability_disabled , add_pointer , add_pointer >::type pointer; - -# if BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \ + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ + || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ + || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \ || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310) // To interoperate with some broken library/compiler @@ -143,7 +157,7 @@ namespace boost private: mutable value_type stored_value; }; - + // // In general, we can't determine that such an iterator isn't // writable -- we also need to store a copy of the old iterator so @@ -195,12 +209,39 @@ namespace boost { return stored_iterator; } - + private: mutable value_type stored_value; Iterator stored_iterator; }; +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct is_non_proxy_reference_impl + { + static Reference r; + + template + static typename mpl::if_< + is_convertible< + R const volatile* + , Value const volatile* + > + , char[1] + , char[2] + >::type& helper(R const&); + + BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1); + }; + + template + struct is_non_proxy_reference + : mpl::bool_< + is_non_proxy_reference_impl::value + > + {}; +# else template struct is_non_proxy_reference : is_convertible< @@ -209,7 +250,8 @@ namespace boost , Value const volatile* > {}; - +# endif + // A metafunction to choose the result type of postfix ++ // // Because the C++98 input iterator requirements say that *r++ has @@ -231,7 +273,7 @@ namespace boost mpl::and_< // A proxy is only needed for readable iterators is_convertible - + // No multipass iterator can have values that disappear // before positions can be re-visited , mpl::not_< @@ -254,7 +296,7 @@ namespace boost // standard's requirements. If *i is not a reference type, we must still // produce an lvalue to which a pointer can be formed. We do that by // returning a proxy object containing an instance of the reference object. - template + template struct operator_arrow_dispatch // proxy references { struct proxy @@ -273,16 +315,92 @@ namespace boost } }; - template - struct operator_arrow_dispatch // "real" references + template + struct operator_arrow_dispatch // "real" references { - typedef T* result_type; + typedef Pointer result_type; static result_type apply(T& x) { return boost::addressof(x); } }; +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // Deal with ETI + template<> + struct operator_arrow_dispatch + { + typedef int result_type; + }; +# endif + + // A proxy return type for operator[], needed to deal with + // iterators that may invalidate referents upon destruction. + // Consider the temporary iterator in *(a + n) + template + class operator_brackets_proxy + { + // Iterator is actually an iterator_facade, so we do not have to + // go through iterator_traits to access the traits. + typedef typename Iterator::reference reference; + typedef typename Iterator::value_type value_type; + + public: + operator_brackets_proxy(Iterator const& iter) + : m_iter(iter) + {} + + operator reference() const + { + return *m_iter; + } + + operator_brackets_proxy& operator=(value_type const& val) + { + *m_iter = val; + return *this; + } + + private: + Iterator m_iter; + }; + + // A metafunction that determines whether operator[] must return a + // proxy, or whether it can simply return a copy of the value_type. + template + struct use_operator_brackets_proxy + : mpl::not_< + mpl::and_< + // Really we want an is_copy_constructible trait here, + // but is_POD will have to suffice in the meantime. + boost::is_POD + , iterator_writability_disabled + > + > + {}; + + template + struct operator_brackets_result + { + typedef typename mpl::if_< + use_operator_brackets_proxy + , operator_brackets_proxy + , Value + >::type type; + }; + + template + operator_brackets_proxy make_operator_brackets_result(Iterator const& iter, mpl::true_) + { + return operator_brackets_proxy(iter); + } + + template + typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_) + { + return *iter; + } + struct choose_difference_type { template @@ -290,13 +408,19 @@ namespace boost : # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP iterator_difference -# else +# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300) + mpl::if_< + is_convertible + , typename I1::difference_type + , typename I2::difference_type + > +# else mpl::eval_if< is_convertible , iterator_difference , iterator_difference > -# endif +# endif {}; }; @@ -314,7 +438,7 @@ namespace boost operator op( \ iterator_facade const& lhs \ , iterator_facade const& rhs) -# else +# else # define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ template < \ class Derived1, class V1, class TC1, class Reference1, class Difference1 \ @@ -327,7 +451,7 @@ namespace boost operator op( \ iterator_facade const& lhs \ , iterator_facade const& rhs) -# endif +# endif # define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \ template \ @@ -344,12 +468,12 @@ namespace boost // class iterator_core_access { -# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) +# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) // Tasteless as this may seem, making all members public allows member templates // to work in the absence of member template friends. public: # else - + template friend class iterator_facade; # define BOOST_ITERATOR_FACADE_RELATION(op) \ @@ -492,15 +616,14 @@ namespace boost > associated_types; typedef boost::detail::operator_arrow_dispatch< - Reference> operator_arrow_dispatch_; - - typedef typename boost::detail::operator_brackets_dispatch< - Derived, Value, Reference>::type operator_brackets_dispatch_; + Reference + , typename associated_types::pointer + > operator_arrow_dispatch_; protected: // For use by derived classes typedef iterator_facade iterator_facade_; - + public: typedef typename associated_types::value_type value_type; @@ -520,11 +643,16 @@ namespace boost { return operator_arrow_dispatch_::apply(*this->derived()); } - - typename operator_brackets_dispatch_::result_type + + typename boost::detail::operator_brackets_result::type operator[](difference_type n) const { - return operator_brackets_dispatch_::apply(this->derived() + n); + typedef boost::detail::use_operator_brackets_proxy use_proxy; + + return boost::detail::make_operator_brackets_result( + this->derived() + n + , use_proxy() + ); } Derived& operator++() @@ -533,6 +661,17 @@ namespace boost return this->derived(); } +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + typename boost::detail::postfix_increment_result::type + operator++(int) + { + typename boost::detail::postfix_increment_result::type + tmp(this->derived()); + ++*this; + return tmp; + } +# endif + Derived& operator--() { iterator_core_access::decrement(this->derived()); @@ -563,8 +702,21 @@ namespace boost Derived result(this->derived()); return result -= x; } + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // There appears to be a bug which trashes the data of classes + // derived from iterator_facade when they are assigned unless we + // define this assignment operator. This bug is only revealed + // (so far) in STLPort debug mode, but it's clearly a codegen + // problem so we apply the workaround for all MSVC6. + iterator_facade& operator=(iterator_facade const&) + { + return *this; + } +# endif }; +# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) template inline typename boost::detail::postfix_increment_result::type operator++( @@ -574,13 +726,14 @@ namespace boost { typename boost::detail::postfix_increment_result::type tmp(*static_cast(&i)); - + ++i; - + return tmp; } +# endif - + // // Comparison operator implementation. The library supplied operators // enables the user to provide fully interoperable constant/mutable diff --git a/include/boost/iterator/iterator_traits.hpp b/include/boost/iterator/iterator_traits.hpp index 856641c..960970e 100644 --- a/include/boost/iterator/iterator_traits.hpp +++ b/include/boost/iterator/iterator_traits.hpp @@ -10,8 +10,18 @@ namespace boost { -// Obsolete. Remove. -#define BOOST_ITERATOR_CATEGORY iterator_category +// Unfortunately, g++ 2.95.x chokes when we define a class template +// iterator_category which has the same name as its +// std::iterator_category() function, probably due in part to the +// "std:: is visible globally" hack it uses. Use +// BOOST_ITERATOR_CATEGORY to write code that's portable to older +// GCCs. + +# if BOOST_WORKAROUND(__GNUC__, <= 2) +# define BOOST_ITERATOR_CATEGORY iterator_category_ +# else +# define BOOST_ITERATOR_CATEGORY iterator_category +# endif template @@ -40,11 +50,43 @@ struct iterator_difference }; template -struct iterator_category +struct BOOST_ITERATOR_CATEGORY { typedef typename boost::detail::iterator_traits::iterator_category type; }; +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +template <> +struct iterator_value +{ + typedef void type; +}; + +template <> +struct iterator_reference +{ + typedef void type; +}; + +template <> +struct iterator_pointer +{ + typedef void type; +}; + +template <> +struct iterator_difference +{ + typedef void type; +}; + +template <> +struct BOOST_ITERATOR_CATEGORY +{ + typedef void type; +}; +# endif + } // namespace boost::iterator #endif // ITERATOR_TRAITS_DWA200347_HPP diff --git a/include/boost/iterator/transform_iterator.hpp b/include/boost/iterator/transform_iterator.hpp index 5d21369..b79a440 100644 --- a/include/boost/iterator/transform_iterator.hpp +++ b/include/boost/iterator/transform_iterator.hpp @@ -140,14 +140,31 @@ namespace boost // function pointer in the iterator be 0, leading to a runtime // crash. template +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + typename mpl::if_< +#else typename iterators::enable_if< +#endif is_class // We should probably find a cheaper test than is_class<> , transform_iterator +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + , int[3] +#endif >::type make_transform_iterator(Iterator it) { return transform_iterator(it, UnaryFunc()); } + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + transform_iterator< Return (*)(Argument), Iterator, Return> + make_transform_iterator(Iterator it, Return (*fun)(Argument)) + { + return transform_iterator(it, fun); + } +#endif + } // namespace boost #include diff --git a/include/boost/iterator/zip_iterator.hpp b/include/boost/iterator/zip_iterator.hpp index cc30388..a468070 100644 --- a/include/boost/iterator/zip_iterator.hpp +++ b/include/boost/iterator/zip_iterator.hpp @@ -166,7 +166,14 @@ namespace boost { > struct tuple_meta_accumulate : mpl::eval_if< +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + mpl::or_< +#endif boost::is_same +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + , boost::is_same + > +#endif , mpl::identity , tuple_meta_accumulate_impl< Tuple @@ -359,6 +366,14 @@ namespace boost { , random_access_traversal_tag >::type type; }; + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround + template <> + struct minimum_traversal_category_in_iterator_tuple + { + typedef int type; + }; +#endif // We need to call tuple_meta_accumulate with mpl::and_ as the // accumulating functor. To this end, we need to wrap it into diff --git a/include/boost/pending/iterator_tests.hpp b/include/boost/pending/iterator_tests.hpp index f9d6e9c..dd5fe2d 100644 --- a/include/boost/pending/iterator_tests.hpp +++ b/include/boost/pending/iterator_tests.hpp @@ -25,6 +25,7 @@ # include # include // for detail::dummy_constructor # include +# include namespace boost { @@ -40,6 +41,8 @@ struct dummyT { } +BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT) + namespace boost { // Tests whether type Iterator satisfies the requirements for a diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 739fdc7..023a826 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -44,6 +44,5 @@ test-suite iterator [ run permutation_iterator_test.cpp : : : # on ] [ run function_input_iterator_test.cpp ] - [ run generator_iterator_test.cpp ] - + ; diff --git a/test/indirect_iter_member_types.cpp b/test/indirect_iter_member_types.cpp index c61a46e..84dcaeb 100644 --- a/test/indirect_iter_member_types.cpp +++ b/test/indirect_iter_member_types.cpp @@ -27,6 +27,8 @@ struct my_ptr { // typedef boost::no_traversal_tag iterator_category; }; +BOOST_TT_BROKEN_COMPILER_SPEC(my_ptr) +BOOST_TT_BROKEN_COMPILER_SPEC(zow) // Borland 5.6.4 and earlier drop const all over the place, so this // test will fail in the lines marked with (**) @@ -80,7 +82,7 @@ int main() typedef boost::indirect_iterator Iter; STATIC_ASSERT_SAME(Iter::value_type, int); STATIC_ASSERT_SAME(Iter::reference, long&); - STATIC_ASSERT_SAME(Iter::pointer, long*); + STATIC_ASSERT_SAME(Iter::pointer, int*); STATIC_ASSERT_SAME(Iter::difference_type, short); } return 0; diff --git a/test/indirect_iterator_test.cpp b/test/indirect_iterator_test.cpp index c689673..8cea482 100644 --- a/test/indirect_iterator_test.cpp +++ b/test/indirect_iterator_test.cpp @@ -27,6 +27,8 @@ #include +#include + #include #include @@ -51,6 +53,7 @@ template struct see_val; struct my_iterator_tag : public std::random_access_iterator_tag { }; using boost::dummyT; +BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr) typedef std::vector storage; typedef std::vector pointer_ra_container; diff --git a/test/is_lvalue_iterator.cpp b/test/is_lvalue_iterator.cpp old mode 100644 new mode 100755 index a3f7b6f..fdace52 --- a/test/is_lvalue_iterator.cpp +++ b/test/is_lvalue_iterator.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ struct v ~v(); }; +BOOST_TT_BROKEN_COMPILER_SPEC(v) struct value_iterator : boost::iterator { @@ -81,6 +83,8 @@ struct constant_lvalue_iterator constant_lvalue_iterator operator++(int); }; +BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy) +BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy) int main() { diff --git a/test/is_readable_iterator.cpp b/test/is_readable_iterator.cpp old mode 100644 new mode 100755 index ee58089..15ed099 --- a/test/is_readable_iterator.cpp +++ b/test/is_readable_iterator.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ struct v ~v(); }; +BOOST_TT_BROKEN_COMPILER_SPEC(v) struct value_iterator : boost::iterator { @@ -69,6 +71,7 @@ struct proxy_iterator2 : boost::iterator proxy operator*() const; }; +BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy) int main() { diff --git a/test/iterator_adaptor_test.cpp b/test/iterator_adaptor_test.cpp index 5b5e0c3..e339fe1 100644 --- a/test/iterator_adaptor_test.cpp +++ b/test/iterator_adaptor_test.cpp @@ -19,6 +19,8 @@ #endif #include +# include + # include #include diff --git a/test/pointee.cpp b/test/pointee.cpp old mode 100644 new mode 100755 index 71d1d04..b39fce1 --- a/test/pointee.cpp +++ b/test/pointee.cpp @@ -35,6 +35,7 @@ struct X { template operator T&() const; }; +BOOST_TT_BROKEN_COMPILER_SPEC(X) int main() { diff --git a/test/unit_tests.cpp b/test/unit_tests.cpp index c53627d..2434310 100644 --- a/test/unit_tests.cpp +++ b/test/unit_tests.cpp @@ -7,10 +7,13 @@ #include "static_assert_same.hpp" +#include + #include struct X { int a; }; +BOOST_TT_BROKEN_COMPILER_SPEC(X) struct Xiter : boost::iterator_adaptor {