From aa0a32aa337f9c3f13c56ca992f8245ce4248505 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Apr 2003 13:40:42 +0000 Subject: [PATCH] fixes and cleanups [SVN r1141] --- include/boost/iterator/detail/categories.hpp | 13 ++- include/boost/iterator/detail/config_def.hpp | 71 +++++++++++++++-- .../boost/iterator/detail/config_undef.hpp | 13 ++- include/boost/iterator/indirect_iterator.hpp | 79 +++++++++---------- include/boost/iterator/interoperable.hpp | 18 ++--- include/boost/iterator/iterator_adaptor.hpp | 55 +++++++------ include/boost/iterator/iterator_facade.hpp | 19 +++-- include/boost/iterator/new_iterator_tests.hpp | 4 +- include/boost/iterator/reverse_iterator.hpp | 7 +- test/Jamfile | 6 +- test/is_convertible_fail.cpp | 8 +- test/iterator_adaptor_test.cpp | 2 +- test/reverse_iterator_test.cpp | 60 ++++++++------ 13 files changed, 218 insertions(+), 137 deletions(-) diff --git a/include/boost/iterator/detail/categories.hpp b/include/boost/iterator/detail/categories.hpp index 5722fa0..9f00f18 100644 --- a/include/boost/iterator/detail/categories.hpp +++ b/include/boost/iterator/detail/categories.hpp @@ -8,21 +8,22 @@ #define BOOST_ITERATOR_DETAIL_CATEGORIES_HPP #include +#include + #include + #include #include #include + #include #include #include #include #include #include -#include -#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) -# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working" -#endif +#include namespace boost { @@ -296,8 +297,6 @@ namespace boost } // namespace boost -#ifdef BOOST_NO_IS_CONVERTIBLE -# undef BOOST_NO_IS_CONVERTIBLE -#endif +#include #endif // BOOST_ITERATOR_DETAIL_CATEGORIES_HPP diff --git a/include/boost/iterator/detail/config_def.hpp b/include/boost/iterator/detail/config_def.hpp index f1699c2..e68e78d 100644 --- a/include/boost/iterator/detail/config_def.hpp +++ b/include/boost/iterator/detail/config_def.hpp @@ -18,26 +18,81 @@ #include // for prior #include +#define BOOST_ITERATOR_CONFIG_DEF // if you get an error here, you have nested config_def #inclusion. + #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \ - || BOOST_WORKAROUND(__MWERKS__, <= 0x3000) + || BOOST_WORKAROUND(__MWERKS__, <= 0x3000) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) # 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 +# if 0 // test code + template + struct bar + { + typedef int type; + }; + + template <> + struct bar + { + }; + + + template + struct foo : bar<(sizeof(T) == 1)> + { + }; + + template + char* f(int, typename foo::type = 0) { return 0; } + + template + int f(...) { return 0; } + + char* x = f(0); + int y = f(0); + + int main() + { + return 0; + } +# endif + #endif #if BOOST_WORKAROUND(__MWERKS__, <=0x2407) -# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't always work" +# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types" +#endif + +#if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(3)) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile: + +# if 0 // test code + template + struct foo + { + foo(T); + + template + foo(foo const& other) : p(other.p) { } + + T p; + }; + + bool x = boost::is_convertible, foo >::value; +# endif + #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" +# define BOOST_ITERATOR_NO_MPL_AUX_HAS_XXX // "MPL's has_xxx facility doesn't work" +#endif + +#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE) +# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY #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 index 17a9089..24c4717 100644 --- a/include/boost/iterator/detail/config_undef.hpp +++ b/include/boost/iterator/detail/config_undef.hpp @@ -13,8 +13,13 @@ // 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 +#undef BOOST_NO_SFINAE +#undef BOOST_NO_IS_CONVERTIBLE +#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE +#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY +#ifdef BOOST_ITERATOR_CONFIG_DEF +# undef BOOST_ITERATOR_CONFIG_DEF +#else +# error missing or nested #include config_def +#endif diff --git a/include/boost/iterator/indirect_iterator.hpp b/include/boost/iterator/indirect_iterator.hpp index 58d0143..372dc5d 100644 --- a/include/boost/iterator/indirect_iterator.hpp +++ b/include/boost/iterator/indirect_iterator.hpp @@ -12,11 +12,11 @@ #include #include -#include #include #include #include +#include #ifdef BOOST_NO_MPL_AUX_HAS_XXX # include @@ -25,6 +25,8 @@ # include #endif +#include // must be last #include + namespace boost { template @@ -42,7 +44,7 @@ namespace boost // can be used instead with something like // boost/python/pointee.hpp to find the value_type. // -# if !defined BOOST_NO_MPL_AUX_HAS_XXX +# ifndef BOOST_NO_MPL_AUX_HAS_XXX namespace aux { BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) @@ -136,13 +138,13 @@ namespace boost >::type cv_value_type; typedef iterator_adaptor< - indirect_iterator - , Iter - , cv_value_type - , Category - , Reference - , Pointer - , Difference + indirect_iterator + , Iter + , cv_value_type + , Category + , Reference + , Pointer + , Difference > type; }; @@ -152,48 +154,42 @@ namespace boost template < class Iterator - , class Value = not_specified - , class Category = not_specified - , class Reference = not_specified - , class Pointer = not_specified - , class Difference = not_specified + , class Value = not_specified + , class Category = not_specified + , class Reference = not_specified + , class Pointer = not_specified + , class Difference = not_specified > class indirect_iterator : public detail::indirect_base< - Iterator - , Value - , Category - , Reference - , Pointer - , Difference + Iterator, Value, Category, Reference, Pointer, Difference >::type { - typedef typename detail::indirect_base< - Iterator - , Value - , Category - , Reference - , Pointer - , Difference - >::type super_t; + typedef typename detail::indirect_base< + Iterator, Value, Category, Reference, Pointer, Difference + >::type super_t; - friend class iterator_core_access; + friend class iterator_core_access; - public: - indirect_iterator() {} + public: + indirect_iterator() {} - indirect_iterator(Iterator iter) - : super_t(iter) {} + indirect_iterator(Iterator iter) + : super_t(iter) {} - template - indirect_iterator( - indirect_iterator const& y - , typename enable_if_convertible::type* = 0 - ) - : super_t(y.base()) + template < + class Iterator2, class Value2, class Category2 + , class Reference2, class Pointer2, class Difference2 + > + indirect_iterator( + indirect_iterator< + Iterator2, Value2, Category2, Reference2, Pointer2, Difference2 + > const& y + , typename enable_if_convertible::type* = 0 + ) + : super_t(y.base()) {} - + private: typename super_t::reference dereference() const { @@ -203,7 +199,6 @@ namespace boost return **this->base(); # endif } - }; template diff --git a/include/boost/iterator/interoperable.hpp b/include/boost/iterator/interoperable.hpp index 2e9ae06..b326250 100644 --- a/include/boost/iterator/interoperable.hpp +++ b/include/boost/iterator/interoperable.hpp @@ -7,14 +7,14 @@ // "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 +# define BOOST_INTEROPERABLE_23022003THW_HPP -#include -#include +# include +# include -#include +# include -#include +# include // must appear last namespace boost { @@ -35,18 +35,18 @@ namespace boost // template struct is_interoperable -#if defined(BOOST_NO_IS_CONVERTIBLE) +# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY : mpl::true_ -#else +# else : mpl::or_< is_convertible< A, B > , is_convertible< B, A > > -#endif +# endif { }; } // namespace boost -#include +# include #endif // BOOST_INTEROPERABLE_23022003THW_HPP diff --git a/include/boost/iterator/iterator_adaptor.hpp b/include/boost/iterator/iterator_adaptor.hpp index 3508adb..1ab1d8b 100644 --- a/include/boost/iterator/iterator_adaptor.hpp +++ b/include/boost/iterator/iterator_adaptor.hpp @@ -97,29 +97,40 @@ namespace boost // false positives for user/library defined iterator types. See comments // on operator implementation for consequences. // - template< - typename From - , typename To> +# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE) + + template 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::or_, is_convertible > -# else - ::boost::is_convertible -# endif - , detail::enable_type - >::type type; -# endif }; - + +# 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. + template + struct enable_if_convertible + : detail::enable_if< + mpl::or_< + is_same + , is_convertible + > + , detail::enable_type + > + {}; + +# else + + template + struct enable_if_convertible + : detail::enable_if< + is_convertible + , detail::enable_type + > + {}; + +# endif // // iterator_traits_adaptor can be used to create new iterator traits by adapting @@ -201,9 +212,9 @@ namespace boost class Derived , class Base , class Value = not_specified - , class Category = not_specified - , class Reference = not_specified - , class Pointer = not_specified + , class Category = not_specified + , class Reference = not_specified + , class Pointer = not_specified , class Difference = not_specified > class iterator_adaptor diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index 018a35d..5b72414 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -20,9 +20,11 @@ #include #include -#include #include +#include + +#include // this goes last namespace boost { @@ -44,14 +46,19 @@ namespace boost , class Return > struct enable_if_interoperable +#ifndef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY : ::boost::detail::enable_if< - is_convertible + mpl::or_< + is_convertible + , is_convertible + > , Return > +#endif { -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) +#ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY typedef Return type; -# endif +#endif }; @@ -483,8 +490,8 @@ namespace boost - , typename Derived1::difference_type , (is_same< - BOOST_ARG_DEP_TYPENAME Derived1::difference_type - , BOOST_ARG_DEP_TYPENAME Derived2::difference_type + BOOST_DEDUCED_TYPENAME Derived1::difference_type + , BOOST_DEDUCED_TYPENAME Derived2::difference_type >::value) , return , distance_to ) diff --git a/include/boost/iterator/new_iterator_tests.hpp b/include/boost/iterator/new_iterator_tests.hpp index 9814d2a..759f8de 100644 --- a/include/boost/iterator/new_iterator_tests.hpp +++ b/include/boost/iterator/new_iterator_tests.hpp @@ -45,8 +45,8 @@ void readable_iterator_test(const Iterator i1, T v) T v2 = r2; assert(v1 == v); assert(v2 == v); - typename access_category::type result_category; - is_readable(result_category); + typedef typename access_category::type result_category; + is_readable(result_category()); } template diff --git a/include/boost/iterator/reverse_iterator.hpp b/include/boost/iterator/reverse_iterator.hpp index 85cb394..606b52c 100644 --- a/include/boost/iterator/reverse_iterator.hpp +++ b/include/boost/iterator/reverse_iterator.hpp @@ -36,9 +36,10 @@ namespace boost template reverse_iterator( reverse_iterator const& r - , typename enable_if_convertible::type* = 0 - ) - : super_t(r.base()) {} + , typename enable_if_convertible::type* = 0 + ) + : super_t(r.base()) + {} private: typename super_t::reference dereference() const { return *boost::prior(this->base()); } diff --git a/test/Jamfile b/test/Jamfile index ed1a5fd..2f3de81 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -2,9 +2,11 @@ SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; include testing.jam ; run concept_tests.cpp ; run iterator_adaptor_cc.cpp ; -run counting_iterator_test.cpp ; +run iterator_adaptor_test.cpp ; run transform_iterator_test.cpp ; run indirect_iterator_test.cpp ; run filter_iterator_test.cpp ; +run reverse_iterator_test.cpp ; +run counting_iterator_test.cpp ; +run is_convertible_fail.cpp ; # test changed to expected success, so that we catch compilation failures. compile-fail interoperable_fail.cpp ; -compile-fail is_convertible_fail.cpp ; \ No newline at end of file diff --git a/test/is_convertible_fail.cpp b/test/is_convertible_fail.cpp index 3411a31..7d3c9b1 100644 --- a/test/is_convertible_fail.cpp +++ b/test/is_convertible_fail.cpp @@ -1,15 +1,11 @@ #include -#include #include int main() { - { typedef boost::reverse_iterator rev_iter1; typedef boost::reverse_iterator rev_iter2; - BOOST_STATIC_ASSERT((boost::is_convertible::value)); - } - - return boost::exit_success; + return boost::is_convertible::value + ? boost::exit_failure : boost::exit_success; } diff --git a/test/iterator_adaptor_test.cpp b/test/iterator_adaptor_test.cpp index bdfa37f..ce40d70 100644 --- a/test/iterator_adaptor_test.cpp +++ b/test/iterator_adaptor_test.cpp @@ -113,7 +113,7 @@ public: template ptr_iterator( const ptr_iterator& x - , typename boost::enable_if_convertible::type* = 0 + , typename boost::enable_if_convertible::type* = 0 ) : super_t(x.base()) {} diff --git a/test/reverse_iterator_test.cpp b/test/reverse_iterator_test.cpp index d94e746..8b3e9b6 100755 --- a/test/reverse_iterator_test.cpp +++ b/test/reverse_iterator_test.cpp @@ -6,46 +6,54 @@ #include #include +#include +#include + +using boost::dummyT; + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost +{ + namespace detail + { + template<> struct iterator_traits + : ptr_iter_traits {}; + template<> struct iterator_traits + : ptr_iter_traits {}; + } +} +#endif // Test reverse iterator int main() { -#if 0 + dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), + dummyT(3), dummyT(4), dummyT(5) }; + const int N = sizeof(array)/sizeof(dummyT); + // Test reverse_iterator_generator { dummyT reversed[N]; std::copy(array, array + N, reversed); std::reverse(reversed, reversed + N); - typedef boost::reverse_iterator_generator::type reverse_iterator; + typedef boost::reverse_iterator reverse_iterator; reverse_iterator i(reversed + N); boost::random_access_iterator_test(i, N, array); -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); -#endif - typedef boost::reverse_iterator_generator::type const_reverse_iterator; + typedef boost::reverse_iterator const_reverse_iterator; const_reverse_iterator j(reversed + N); boost::random_access_iterator_test(j, N, array); const dummyT* const_reversed = reversed; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); -#endif - boost::const_nonconst_iterator_test(i, ++j); + boost::const_nonconst_iterator_test(i, ++j); } // Test reverse_iterator_generator again, with traits fully deducible on all platforms @@ -55,10 +63,10 @@ int main() const std::deque::iterator reversed = reversed_container.begin(); - typedef boost::reverse_iterator_generator< - std::deque::iterator>::type reverse_iterator; - typedef boost::reverse_iterator_generator< - std::deque::const_iterator, const dummyT>::type const_reverse_iterator; + typedef boost::reverse_iterator< + std::deque::iterator> reverse_iterator; + typedef boost::reverse_iterator< + std::deque::const_iterator> const_reverse_iterator; // MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation // (e.g. "reversed + N") is used in the constructor below. @@ -76,12 +84,14 @@ int main() // Many compilers' builtin deque iterators don't interoperate well, though // STLport fixes that problem. -#if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && (!defined(BOOST_MSVC) || BOOST_MSVC > 1200) +#if defined(__SGI_STL_PORT) \ + || !BOOST_WORKAROUND(__GNUC__, <= 2) \ + && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) \ + && !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1) + boost::const_nonconst_iterator_test(i, ++j); + #endif } - -#endif - - + return 0; }