From d924f56ad85299f48e99a311f76bffb36283f94d Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Thu, 8 Mar 2001 16:33:14 +0000 Subject: [PATCH] added support for optional named template parameters [SVN r9487] --- include/boost/iterator_adaptors.hpp | 171 ++++++++++++++++++++++++---- 1 file changed, 151 insertions(+), 20 deletions(-) diff --git a/include/boost/iterator_adaptors.hpp b/include/boost/iterator_adaptors.hpp index e0af582..a93c842 100644 --- a/include/boost/iterator_adaptors.hpp +++ b/include/boost/iterator_adaptors.hpp @@ -12,6 +12,8 @@ // // Revision History: +// 08 Mar 2001 Jeremy Siek +// Added support for optional named template parameters. // 19 Feb 2001 David Abrahams // Rolled back reverse_iterator_pair_generator again, as it doesn't // save typing on a conforming compiler. @@ -104,6 +106,7 @@ # include # include # include +# include // I was having some problems with VC6. I couldn't tell whether our hack for // stock GCC was causing problems so I needed an easy way to turn it on and @@ -220,6 +223,9 @@ struct default_iterator_policies void initialize(Base&) { } + // The "type" parameter is a portable mechanism for + // the iterator_adaptor class to tell this member function what + // the Reference type is, which is needed for the return type. template Reference dereference(type, const Base& x) const { return *x; } @@ -429,8 +435,111 @@ namespace detail { }; # endif + + //=========================================================================== + // Specify the defaults for iterator_adaptor's template parameters + + struct default_value_type { + template + struct bind { + typedef typename boost::detail::iterator_traits::value_type type; + }; + }; + struct default_difference_type { + template + struct bind { + typedef typename boost::detail::iterator_traits::difference_type type; + }; + }; + struct default_iterator_category { + template + struct bind { + typedef typename boost::detail::iterator_traits::iterator_category type; + }; + }; + struct default_pointer { + template + struct bind { + typedef typename Traits::value_type Value; + typedef typename boost::detail::iterator_defaults::pointer + type; + }; + }; + struct default_reference { + template + struct bind { + typedef typename Traits::value_type Value; + typedef typename boost::detail::iterator_defaults::reference + type; + }; + }; + + //=========================================================================== + // Support for named template parameters + +#if !defined(__BORLANDC__) + // Borland C++ thinks the nested recursive inheritance here is illegal. + + template + struct iter_traits_gen : public named_template_param_base { + template + struct value_type : public iter_traits_gen { }; + template + struct reference : public iter_traits_gen { }; + template + struct pointer : public iter_traits_gen { }; + template + struct iterator_category : public iter_traits_gen{}; + template + struct difference_type : public iter_traits_gen { }; + + typedef boost::iterator traits; + }; +#endif + + BOOST_NAMED_TEMPLATE_PARAM(value_type); + BOOST_NAMED_TEMPLATE_PARAM(reference); + BOOST_NAMED_TEMPLATE_PARAM(pointer); + BOOST_NAMED_TEMPLATE_PARAM(iterator_category); + BOOST_NAMED_TEMPLATE_PARAM(difference_type); + + template + class iterator_adaptor_traits_gen + { + typedef boost::iterator + Traits0; + + typedef typename get_value_type::type, Traits0 + >::type value_type; + typedef typename get_difference_type::type + difference_type; + typedef typename get_iterator_category::type + iterator_category; + + typedef boost::iterator Traits1; + + typedef typename get_pointer::type pointer; + typedef typename get_reference::type reference; + public: + typedef boost::iterator type; + }; + } // namespace detail + +#if !defined(__BORLANDC__) +struct iterator_traits_generator + : public detail::iter_traits_gen<> { }; +#endif + // This macro definition is only temporary in this file # if !defined(BOOST_MSVC) # define BOOST_ARG_DEPENDENT_TYPENAME typename @@ -469,29 +578,40 @@ template struct undefined; // Distance - the difference_type of the resulting iterator. If not // supplied, iterator_traits::difference_type is used. template ::value_type, class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::reference, class Pointer = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults::pointer, class Category = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits::iterator_category, class Distance = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits::difference_type +#else + class Value = detail::default_argument, + class Reference = detail::default_argument, + class Pointer = detail::default_argument, + class Category = detail::default_argument, + class Distance = detail::default_argument +#endif > struct iterator_adaptor : #ifdef BOOST_RELOPS_AMBIGUITY_BUG iterator_comparisons< iterator_adaptor, -#endif - boost::iterator -#ifdef BOOST_RELOPS_AMBIGUITY_BUG -> + typename detail::iterator_adaptor_traits_gen::type + > +#else + detail::iterator_adaptor_traits_gen::type #endif { typedef iterator_adaptor self; public: - typedef Distance difference_type; - typedef typename boost::remove_const::type value_type; - typedef Pointer pointer; - typedef Reference reference; - typedef Category iterator_category; + typedef typename detail::iterator_adaptor_traits_gen::type Traits; + + typedef typename Traits::difference_type difference_type; + typedef typename Traits::value_type value_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + typedef typename Traits::iterator_category iterator_category; + typedef Base base_type; typedef Policies policies_type; @@ -501,16 +621,19 @@ struct iterator_adaptor : || boost::is_convertible::value)); // Iterators should satisfy one of the known categories +#if 0 BOOST_STATIC_ASSERT(is_input_or_output_iter); +#endif // Iterators >= ForwardIterator must produce real references. +#if 0 BOOST_STATIC_CONSTANT(bool, forward_iter_with_real_reference = (!boost::is_convertible::value || boost::is_same::value || boost::is_same::value)); BOOST_STATIC_ASSERT(forward_iter_with_real_reference); - +#endif public: iterator_adaptor() { } @@ -545,9 +668,9 @@ struct iterator_adaptor : # pragma warning( disable : 4284 ) #endif - typename boost::detail::operator_arrow_result_generator::type + typename boost::detail::operator_arrow_result_generator::type operator->() const - { return detail::operator_arrow(*this, Category()); } + { return detail::operator_arrow(*this, iterator_category()); } #ifdef _MSC_VER # pragma warning(pop) @@ -590,7 +713,7 @@ struct iterator_adaptor : // Moved from global scope to avoid ambiguity with the operator-() which // subtracts iterators from one another. - self operator-(Distance x) const + self operator-(difference_type x) const { self result(*this); return result -= x; } private: compressed_pair m_iter_p; @@ -626,11 +749,14 @@ operator+( template -Distance operator-( +typename iterator_adaptor::difference_type +operator-( const iterator_adaptor& x, const iterator_adaptor& y) { - return x.policies().distance(type(), y.iter(), x.iter()); + typedef typename iterator_adaptor::difference_type difference_type; + return x.policies().distance(type(), y.iter(), x.iter()); } #ifndef BOOST_RELOPS_AMBIGUITY_BUG @@ -967,14 +1093,19 @@ public: { return x == y; } private: - void satisfy_predicate(Iterator& iter) - { - while (m_end != iter && !m_predicate(*iter)) - ++iter; - } + void satisfy_predicate(Iterator& iter); Predicate m_predicate; Iterator m_end; }; +template +void filter_iterator_policies +::satisfy_predicate(Iterator& iter) +{ + while (m_end != iter && !m_predicate(*iter)) + ++iter; +} + + namespace detail { // A type generator returning Base if T is derived from Base, and T otherwise.