From d51c5ebf07da6d6fba7dbc97b789dd0cfafcee0e Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 18 Nov 2003 03:04:16 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'simplify'. [SVN r20841] --- .../iterator/detail/any_conversion_eater.hpp | 19 +++ include/boost/iterator/is_lvalue_iterator.hpp | 144 ++++++++++++++++++ .../boost/iterator/is_readable_iterator.hpp | 104 +++++++++++++ test/Jamfile | 50 ++++++ test/Jamfile.v2 | 44 ++++++ test/is_lvalue_iterator.cpp | 87 +++++++++++ test/is_readable_iterator.cpp | 93 +++++++++++ test/iterator_categories.cpp | 91 +++++++++++ 8 files changed, 632 insertions(+) create mode 100755 include/boost/iterator/detail/any_conversion_eater.hpp create mode 100755 include/boost/iterator/is_lvalue_iterator.hpp create mode 100755 include/boost/iterator/is_readable_iterator.hpp create mode 100644 test/Jamfile create mode 100644 test/Jamfile.v2 create mode 100755 test/is_lvalue_iterator.cpp create mode 100755 test/is_readable_iterator.cpp create mode 100755 test/iterator_categories.cpp diff --git a/include/boost/iterator/detail/any_conversion_eater.hpp b/include/boost/iterator/detail/any_conversion_eater.hpp new file mode 100755 index 0000000..25fa644 --- /dev/null +++ b/include/boost/iterator/detail/any_conversion_eater.hpp @@ -0,0 +1,19 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to 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) +#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP +# define ANY_CONVERSION_EATER_DWA20031117_HPP + +namespace boost { namespace detail { + +// This type can be used in traits to "eat" up the one user-defined +// implicit conversion allowed. +struct any_conversion_eater +{ + template + any_conversion_eater(T const&); +}; + +}} // namespace boost::detail + +#endif // ANY_CONVERSION_EATER_DWA20031117_HPP diff --git a/include/boost/iterator/is_lvalue_iterator.hpp b/include/boost/iterator/is_lvalue_iterator.hpp new file mode 100755 index 0000000..d77b977 --- /dev/null +++ b/include/boost/iterator/is_lvalue_iterator.hpp @@ -0,0 +1,144 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to 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) +#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP +# define IS_LVALUE_ITERATOR_DWA2003112_HPP + +#include +#include +#include + +#include +#include + +// should be the last #include +#include + +namespace boost { + +namespace detail +{ +#ifndef BOOST_NO_LVALUE_RETURN_DETECTION + // Calling lvalue_preserver( , 0 ) returns a reference + // to the expression's result if is an lvalue, or + // not_an_lvalue() otherwise. + struct not_an_lvalue {}; + + template + T& lvalue_preserver(T&, int); + + template + not_an_lvalue lvalue_preserver(U const&, ...); + +# define BOOST_LVALUE_PRESERVER(expr) lvalue_preserver(expr,0) + +#else + +# define BOOST_LVALUE_PRESERVER(expr) expr + +#endif + + // Guts of is_lvalue_iterator. Value is the iterator's value_type + // and the result is computed in the nested rebind template. + template + struct is_lvalue_iterator_impl + { + // Eat implicit conversions so we don't report true for things + // convertible to Value const& + struct conversion_eater + { + conversion_eater(Value&); + }; + + static char tester(conversion_eater, int); + static char (& tester(any_conversion_eater, ...) )[2]; + + template + struct rebind + { + static It& x; + + BOOST_STATIC_CONSTANT( + bool + , value = ( + sizeof( + is_lvalue_iterator_impl::tester( + BOOST_LVALUE_PRESERVER(*x), 0 + ) + ) == 1 + ) + ); + }; + }; + +#undef BOOST_LVALUE_PRESERVER + + // + // void specializations to handle std input and output iterators + // + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_lvalue_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; +#endif + + // + // This level of dispatching is required for Borland. We might save + // an instantiation by removing it for others. + // + template + struct is_readable_lvalue_iterator_impl + : is_lvalue_iterator_impl< + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type const + >::template rebind + {}; + + template + struct is_mutable_lvalue_iterator_impl + : is_lvalue_iterator_impl< + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type + >::template rebind + {}; +} // 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::detail::is_readable_lvalue_iterator_impl::value) + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_mutable_lvalue_iterator,T,::boost::detail::is_mutable_lvalue_iterator_impl::value) + +} // namespace boost + +#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 new file mode 100755 index 0000000..52df758 --- /dev/null +++ b/include/boost/iterator/is_readable_iterator.hpp @@ -0,0 +1,104 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to 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) +#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP +# define IS_READABLE_ITERATOR_DWA2003112_HPP + +#include +#include + +#include +#include + +// should be the last #include +#include + +namespace boost { + +namespace detail +{ + // Guts of is_readable_iterator. Value is the iterator's value_type + // and the result is computed in the nested rebind template. + template + struct is_readable_iterator_impl + { + static char tester(Value&, int); + static char (& tester(any_conversion_eater, ...) )[2]; + + template + struct rebind + { + static It& x; + + BOOST_STATIC_CONSTANT( + bool + , value = ( + sizeof( + is_readable_iterator_impl::tester(*x, 1) + ) == 1 + ) + ); + }; + }; + +#undef BOOST_READABLE_PRESERVER + + // + // void specializations to handle std input and output iterators + // + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; + + template <> + struct is_readable_iterator_impl + { + template + struct rebind : boost::mpl::false_ + {}; + }; +#endif + + // + // This level of dispatching is required for Borland. We might save + // an instantiation by removing it for others. + // + template + struct is_readable_iterator_impl2 + : is_readable_iterator_impl< + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type const + >::template rebind + {}; +} // 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::detail::is_readable_iterator_impl2::value) + +} // namespace boost + +#include + +#endif // IS_READABLE_ITERATOR_DWA2003112_HPP diff --git a/test/Jamfile b/test/Jamfile new file mode 100644 index 0000000..1a7b9a1 --- /dev/null +++ b/test/Jamfile @@ -0,0 +1,50 @@ +# Copyright David Abrahams 2003. 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. + +subproject libs/iterator/test ; + +import testing ; + +test-suite iterator + : + # These first two tests will run last, and are expected to fail + # for many less-capable compilers. + + [ compile-fail interoperable_fail.cpp ] + # test uses expected success, so that we catch unrelated + # compilation problems. + [ run is_convertible_fail.cpp ] + + # These tests should work for just about everything. + [ compile is_lvalue_iterator.cpp ] + [ compile is_readable_iterator.cpp ] + + [ run unit_tests.cpp ] + [ run concept_tests.cpp ] + [ run iterator_adaptor_cc.cpp ] + [ run iterator_adaptor_test.cpp ] + [ compile iterator_archetype_cc.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 permutation_iterator_test.cpp : : : # on + ] + [ compile iterator_categories.cpp ] + [ run zip_iterator_test.cpp ] + + [ run ../../utility/iterator_adaptor_examples.cpp ] + [ run ../../utility/counting_iterator_example.cpp ] + [ run ../../utility/filter_iterator_example.cpp ] + [ run ../../utility/fun_out_iter_example.cpp ] + [ run ../../utility/indirect_iterator_example.cpp ] + [ run ../../utility/projection_iterator_example.cpp ] + [ run ../../utility/reverse_iterator_example.cpp ] + [ run ../../utility/transform_iterator_example.cpp ] + [ run ../../utility/iterator_traits_test.cpp ] + +; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 new file mode 100644 index 0000000..4cdb206 --- /dev/null +++ b/test/Jamfile.v2 @@ -0,0 +1,44 @@ +# Copyright David Abrahams 2003. 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. + +import testing ; + +test-suite iterator + : + # These first two tests will run last, and are expected to fail + # for many less-capable compilers. + + [ compile-fail interoperable_fail.cpp ] + # test uses expected success, so that we catch unrelated + # compilation problems. + [ run is_convertible_fail.cpp ] + + # These tests should work for just about everything. + [ run unit_tests.cpp ] + [ run concept_tests.cpp ] + [ run iterator_adaptor_cc.cpp ] + [ run iterator_adaptor_test.cpp ] + [ compile iterator_archetype_cc.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 permutation_iterator_test.cpp : : : # on + ] + [ run zip_iterator_test.cpp ] + + [ run ../../utility/iterator_adaptor_examples.cpp ] + [ run ../../utility/counting_iterator_example.cpp ] + [ run ../../utility/filter_iterator_example.cpp ] + [ run ../../utility/fun_out_iter_example.cpp ] + [ run ../../utility/indirect_iterator_example.cpp ] + [ run ../../utility/projection_iterator_example.cpp ] + [ run ../../utility/reverse_iterator_example.cpp ] + [ run ../../utility/transform_iterator_example.cpp ] + [ run ../../utility/iterator_traits_test.cpp ] + +; diff --git a/test/is_lvalue_iterator.cpp b/test/is_lvalue_iterator.cpp new file mode 100755 index 0000000..9c23c9c --- /dev/null +++ b/test/is_lvalue_iterator.cpp @@ -0,0 +1,87 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to 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) + +#include +#include +#include +#include +#include +#include +#include +#include + +// Last, for BOOST_NO_LVALUE_RETURN_DETECTION +#include + +struct v +{ + v(); + ~v(); +}; + +BOOST_TT_BROKEN_COMPILER_SPEC(v) + +struct value_iterator : boost::iterator +{ + v operator*() const; +}; + +struct noncopyable_iterator : boost::iterator +{ + boost::noncopyable const& operator*() const; +}; + +struct proxy_iterator : boost::iterator +{ +#if BOOST_WORKAROUND(__GNUC__, == 2) + typedef boost::iterator base; + typedef base::iterator_category iterator_category; + typedef base::value_type value_type; + typedef base::difference_type difference_type; + typedef base::pointer pointer; + typedef base::reference reference; +#endif + + struct proxy + { + operator v&() const; + proxy& operator=(v) const; + }; + + proxy operator*() const; +}; + +BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy) + +int main() +{ + BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::value); + BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::value); + BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::iterator>::value); + BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::const_iterator>::value); + BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator > >::value); + BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator >::value); + BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator::value); +#ifndef BOOST_NO_LVALUE_RETURN_DETECTION + BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator::value); +#endif + // Make sure inaccessible copy constructor doesn't prevent + // reference binding + BOOST_STATIC_ASSERT(boost::is_lvalue_iterator::value); + + + BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator::value); + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); + BOOST_STATIC_ASSERT(boost::is_mutable_lvalue_iterator::iterator>::value); + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::const_iterator>::value); + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator > >::value); + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator >::value); + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); +#ifndef BOOST_NO_LVALUE_RETURN_DETECTION + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); +#endif + BOOST_STATIC_ASSERT(!boost::is_mutable_lvalue_iterator::value); + + return 0; +} diff --git a/test/is_readable_iterator.cpp b/test/is_readable_iterator.cpp new file mode 100755 index 0000000..15ed099 --- /dev/null +++ b/test/is_readable_iterator.cpp @@ -0,0 +1,93 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to 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) + +#include +#include +#include +#include +#include +#include +#include +#include + +// Last, for BOOST_NO_LVALUE_RETURN_DETECTION +#include + +struct v +{ + v(); + ~v(); +}; + +BOOST_TT_BROKEN_COMPILER_SPEC(v) + +struct value_iterator : boost::iterator +{ + v operator*() const; +}; + +struct noncopyable_iterator : boost::iterator +{ + boost::noncopyable const& operator*() const; +}; + +struct proxy_iterator : boost::iterator +{ +#if BOOST_WORKAROUND(__GNUC__, == 2) + typedef boost::iterator base; + typedef base::iterator_category iterator_category; + typedef base::value_type value_type; + typedef base::difference_type difference_type; + typedef base::pointer pointer; + typedef base::reference reference; +#endif + + struct proxy + { + operator v&(); + proxy& operator=(v) const; + }; + + proxy operator*() const; +}; + +struct proxy_iterator2 : boost::iterator +{ +#if BOOST_WORKAROUND(__GNUC__, == 2) + typedef boost::iterator base; + typedef base::iterator_category iterator_category; + typedef base::value_type value_type; + typedef base::difference_type difference_type; + typedef base::pointer pointer; + typedef base::reference reference; +#endif + + struct proxy + { + proxy& operator=(v) const; + }; + + proxy operator*() const; +}; + +BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy) + +int main() +{ + BOOST_STATIC_ASSERT(boost::is_readable_iterator::value); + BOOST_STATIC_ASSERT(boost::is_readable_iterator::value); + BOOST_STATIC_ASSERT(boost::is_readable_iterator::iterator>::value); + BOOST_STATIC_ASSERT(boost::is_readable_iterator::const_iterator>::value); + BOOST_STATIC_ASSERT(!boost::is_readable_iterator > >::value); + BOOST_STATIC_ASSERT(!boost::is_readable_iterator >::value); + BOOST_STATIC_ASSERT(boost::is_readable_iterator::value); + BOOST_STATIC_ASSERT(!boost::is_readable_iterator::value); + BOOST_STATIC_ASSERT(boost::is_readable_iterator::value); + + // Make sure inaccessible copy constructor doesn't prevent + // readability + BOOST_STATIC_ASSERT(boost::is_readable_iterator::value); + + return 0; +} diff --git a/test/iterator_categories.cpp b/test/iterator_categories.cpp new file mode 100755 index 0000000..e36f2c9 --- /dev/null +++ b/test/iterator_categories.cpp @@ -0,0 +1,91 @@ +// Copyright David Abrahams 2003. Use, modification and distribution is +// subject to 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) + +#include + +using namespace boost; + +// Utility function which converts an iterator_category into a +// traversal tag +template +typename iterator_category_to_traversal::type c2t(C) +{ + typedef typename iterator_category_to_traversal::type result; + return result(); +} + +struct v +{ + v(); + ~v(); +}; + +// +// Test conversions from iterator_tag<...> to old-style iterator categories +// + +// These "solid" tag types ensure exact matching of iterator +// classification, because unlike the std:: iterator tags, they're not +// inter-convertible +struct output_iter {}; +struct input_iter {}; +struct input_output_iter {}; +struct forward_iter {}; +struct bidirectional_iter {}; +struct random_access_iter{} ; + +// Convert various old-style categories into "solid" tags. +input_iter cat(std::input_iterator_tag); +output_iter cat(std::output_iterator_tag); +input_output_iter cat(boost::detail::input_output_iterator_tag); +forward_iter cat(std::forward_iterator_tag); +bidirectional_iter cat(std::bidirectional_iterator_tag); +random_access_iter cat(std::random_access_iterator_tag); + +random_access_iter x1 = cat(iterator_tag()); +random_access_iter x2 = cat(iterator_tag()); +bidirectional_iter x3 = cat(iterator_tag()); +forward_iter x4 = cat(iterator_tag()); +input_output_iter x5 = cat(iterator_tag()); +input_iter x6 = cat(iterator_tag()); +output_iter x7 = cat(iterator_tag()); + + +// +// Test conversion from old-style iterator categories to traversal categories +// + +// These "solid" tag types ensure exact matching of iterator +// classification, because unlike the traversal tags, they're not +// inter-convertible +struct incrementable_traversal {}; +struct single_pass_traversal {}; +struct forward_traversal {}; +struct bidirectional_traversal {}; +struct random_access_traversal {} ; + +// Convert various traversal categories into "solid" tags +incrementable_traversal trav(incrementable_traversal_tag); +single_pass_traversal trav(single_pass_traversal_tag); +forward_traversal trav(forward_traversal_tag); +bidirectional_traversal trav(bidirectional_traversal_tag); +random_access_traversal trav(random_access_traversal_tag); + +// Show that full types of tags that are already traversal categories +// are preserved +iterator_tag yz1 + = c2t(iterator_tag()); + +// Test traversal extraction from both old-style and new-style tags +random_access_traversal yy1 = trav(c2t(iterator_tag())); +bidirectional_traversal yy2 = trav(c2t(iterator_tag())); +forward_traversal yy3 = trav(c2t(iterator_tag())); +single_pass_traversal yy4 = trav(c2t(iterator_tag())); +incrementable_traversal yy5 = trav(c2t(iterator_tag())); + +random_access_traversal z1 = trav(c2t(std::random_access_iterator_tag())); +bidirectional_traversal z2 = trav(c2t(std::bidirectional_iterator_tag())); +forward_traversal z3 = trav(c2t(std::forward_iterator_tag())); +single_pass_traversal z4 = trav(c2t(std::input_iterator_tag())); +incrementable_traversal z5 = trav(c2t(std::output_iterator_tag()));