diff --git a/include/boost/iterator/is_lvalue_iterator.hpp b/include/boost/iterator/is_lvalue_iterator.hpp index 20c4f38..e821da9 100644 --- a/include/boost/iterator/is_lvalue_iterator.hpp +++ b/include/boost/iterator/is_lvalue_iterator.hpp @@ -9,10 +9,13 @@ #include #include +#include #include +#include +#include // should be the last #includes -#include +#include #include #ifndef BOOST_NO_IS_CONVERTIBLE @@ -52,7 +55,7 @@ namespace detail // convertible to Value const& struct conversion_eater { - conversion_eater(Value&); + conversion_eater(typename add_lvalue_reference::type); }; static char tester(conversion_eater, int); @@ -134,13 +137,19 @@ namespace detail {}; } // namespace detail -// Define the trait with full mpl lambda capability and various broken -// compiler workarounds -BOOST_TT_AUX_BOOL_TRAIT_DEF1( - is_lvalue_iterator,T,::boost::iterators::detail::is_readable_lvalue_iterator_impl::value) +template< typename T > struct is_lvalue_iterator +: public ::boost::integral_constant::value> +{ +public: + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_lvalue_iterator,(T)) +}; -BOOST_TT_AUX_BOOL_TRAIT_DEF1( - is_non_const_lvalue_iterator,T,::boost::iterators::detail::is_non_const_lvalue_iterator_impl::value) +template< typename T > struct is_non_const_lvalue_iterator +: public ::boost::integral_constant::value> +{ +public: + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T)) +}; } // namespace iterators @@ -152,6 +161,5 @@ using iterators::is_non_const_lvalue_iterator; #endif #include -#include #endif // IS_LVALUE_ITERATOR_DWA2003112_HPP diff --git a/include/boost/iterator/is_readable_iterator.hpp b/include/boost/iterator/is_readable_iterator.hpp index 3f08b92..5bc2339 100644 --- a/include/boost/iterator/is_readable_iterator.hpp +++ b/include/boost/iterator/is_readable_iterator.hpp @@ -5,12 +5,14 @@ # define IS_READABLE_ITERATOR_DWA2003112_HPP #include +#include #include +#include -#include #include // should be the last #include +#include #include #ifndef BOOST_NO_IS_CONVERTIBLE @@ -26,7 +28,7 @@ namespace detail template struct is_readable_iterator_impl { - static char tester(Value&, int); + static char tester(typename add_lvalue_reference::type, int); static char (& tester(any_conversion_eater, ...) )[2]; template @@ -96,10 +98,12 @@ namespace detail {}; } // namespace detail -// Define the trait with full mpl lambda capability and various broken -// compiler workarounds -BOOST_TT_AUX_BOOL_TRAIT_DEF1( - is_readable_iterator,T,::boost::iterators::detail::is_readable_iterator_impl2::value) +template< typename T > struct is_readable_iterator +: public ::boost::integral_constant::value> +{ +public: + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T)) +}; } // namespace iterators diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index 31b2a9d..71202c9 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -168,13 +168,6 @@ struct pure_traversal_tag { }; -// This import is needed for backward compatibility with Boost.Range: -// boost/range/detail/demote_iterator_traversal_tag.hpp -// It should be removed when that header is fixed. -namespace detail { -using iterators::pure_traversal_tag; -} // namespace detail - // // Trait to retrieve one of the iterator traversal tags from the iterator category or traversal. // diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index c08a869..7b11d0a 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -284,7 +285,15 @@ namespace iterators { : mpl::eval_if< mpl::and_< // A proxy is only needed for readable iterators - is_convertible + is_convertible< + Reference + // Use add_lvalue_reference to form `reference to Value` due to + // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject + // 'reference-to-reference' in the template which described in CWG + // DR106. + // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106 + , typename add_lvalue_reference::type + > // No multipass iterator can have values that disappear // before positions can be re-visited diff --git a/test/iterator_facade.cpp b/test/iterator_facade.cpp index 9585298..9200cc1 100644 --- a/test/iterator_facade.cpp +++ b/test/iterator_facade.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -49,14 +50,14 @@ class counter_iterator struct proxy { proxy(int& x) : state(x) {} - + operator int const&() const { return state; } int& operator=(int x) { state = x; return state; } - + int& state; }; @@ -128,6 +129,61 @@ template void same_type(U const&) { BOOST_MPL_ASSERT((boost::is_same)); } +template +struct abstract_iterator + : boost::iterator_facade< + abstract_iterator + , A & + // In order to be value type as a reference, traversal category has + // to satisfy least forward traversal. + , boost::forward_traversal_tag + , A & + > +{ + abstract_iterator(I iter) : iter(iter) {} + + void increment() + { ++iter; } + + A & dereference() const + { return *iter; } + + bool equal(abstract_iterator const& y) const + { return iter == y.iter; } + + I iter; +}; + +struct base +{ + virtual void assign(const base &) = 0; + virtual bool equal(const base &) const = 0; +}; + +struct derived : base +{ + derived(int state) : state(state) { } + derived(const derived &d) : state(d.state) { } + derived(const base &b) { derived::assign(b); } + + virtual void assign(const base &b) + { + state = boost::polymorphic_cast(&b)->state; + } + + virtual bool equal(const base &b) const + { + return state == boost::polymorphic_cast(&b)->state; + } + + int state; +}; + +inline bool operator==(const base &lhs, const base &rhs) +{ + return lhs.equal(rhs); +} + int main() { { @@ -162,5 +218,10 @@ int main() BOOST_TEST(i.m_x == 2); } + { + derived d(1); + boost::readable_iterator_test(abstract_iterator(&d), derived(1)); + } + return boost::report_errors(); }