From 79c6d11694923cf5f5005094ce07e0232e310a70 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Sun, 21 Oct 2001 16:37:25 +0000 Subject: [PATCH] changed named parameters, still need to add suppose for no template part. spec. [SVN r11416] --- include/boost/iterator_adaptors.hpp | 199 +++++++++++++++++++++------- 1 file changed, 153 insertions(+), 46 deletions(-) diff --git a/include/boost/iterator_adaptors.hpp b/include/boost/iterator_adaptors.hpp index 2208d31..9da7fdd 100644 --- a/include/boost/iterator_adaptors.hpp +++ b/include/boost/iterator_adaptors.hpp @@ -114,7 +114,7 @@ # include # 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 @@ -474,71 +474,178 @@ namespace detail { }; }; +} // namespace detail + + //=========================================================================== // Support for named template parameters -#if !defined(__BORLANDC__) - // Borland C++ thinks the nested recursive inheritance here is illegal. +struct named_template_param_base { }; - 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 { }; +namespace detail { + struct value_type_tag { }; + struct reference_tag { }; + struct pointer_tag { }; + struct difference_type_tag { }; + struct iterator_category_tag { }; +} +template struct value_type_is : public named_template_param_base +{ + typedef std::pair type; +}; +template struct reference_is : public named_template_param_base +{ + typedef std::pair type; +}; +template struct pointer_is : public named_template_param_base +{ + typedef std::pair type; +}; +template struct difference_type_is + : public named_template_param_base +{ + typedef std::pair type; +}; +template struct iterator_category_is + : public named_template_param_base +{ + typedef std::pair type; +}; - typedef boost::iterator traits; +namespace detail { + + struct default_argument { }; + + struct end_of_list { }; + + // Given an associative list, find the value with the matching key. + // An associative list is a list of key-value pairs. The list is + // built out of std::pair's and is terminated by end_of_list. + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // UNDER CONSTRUCTION +#else + template struct find_param; + + template + struct find_param { typedef default_argument type; }; + + // Found a matching Key, return the associated Value + template + struct find_param, Rest>, Key> { + typedef Value type; + }; + + // Non-matching keys, continue the search + template + struct find_param, Rest>, Key2> { + typedef typename find_param::type type; }; #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); + struct make_named_arg { + template + struct bind { typedef typename Value::type type; }; + }; + struct make_key_value { + template + struct bind { typedef std::pair type; }; + }; + + template + class make_arg { + enum { is_named = is_convertible::value }; + typedef typename ct_if::type Make; + typedef typename Make::template bind::type type; + }; + + // Mechanism for resolving the default argument for a template parameter. + + template struct is_default { typedef type_traits::no_type type; }; + template <> struct is_default + { typedef type_traits::yes_type type; }; + + struct choose_default { + template + struct select { + typedef typename DefaultGen::template select::type type; + }; + }; + struct choose_arg { + template + struct select { + typedef Arg type; + }; + }; + + template + struct choose_arg_or_default { typedef choose_arg type; }; + template <> struct choose_arg_or_default { + typedef choose_default type; + }; + + template + class resolve_default { + typedef typename choose_arg_or_default::type>::type + Selector; + public: + typedef typename Selector + ::template select::type type; + }; template class iterator_adaptor_traits_gen { + // Form an associative list out of the template parameters + // If the argument is a normal parameter (not named) then make_arg + // creates a key-value pair. If the argument is a named parameter, + // then make_arg extracts the key-value pair defined inside the + // named parameter. + typedef std::pair< typename make_arg::type, + std::pair::type, + std::pair::type, + std::pair::type, + std::pair::type, + end_of_list> > > > > ArgList; + + // Search the list for particular parameters + typedef typename find_param::type Val; + typedef typename find_param::type Diff; + typedef typename find_param::type Cat; + typedef typename find_param::type Ptr; + typedef typename find_param::type Ref; + 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; + // Compute the defaults if necessary + typedef typename resolve_default::type + value_type; + typedef typename resolve_default::type difference_type; + typedef typename resolve_default::type iterator_category; typedef boost::iterator Traits1; - - typedef typename get_pointer::type pointer; - typedef typename get_reference::type reference; + + // Compute the defaults for pointer and reference. This is done as a + // separate step because the defaults for pointer and reference depend + // on value_type. + typedef typename resolve_default::type + pointer; + typedef typename resolve_default::type + reference; public: - typedef boost::iterator type; + typedef boost::iterator::type, + difference_type, pointer, reference> 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) @@ -579,10 +686,10 @@ template struct undefined; // supplied, iterator_traits::difference_type is used. template ::type, - class Pointer = BOOST_ARG_DEPENDENT_TYPENAME detail::choose_default_argument::type, - class Category = BOOST_ARG_DEPENDENT_TYPENAME detail::choose_default_argument::type, - class Distance = BOOST_ARG_DEPENDENT_TYPENAME detail::choose_default_argument::type + class Reference = detail::default_argument, + class Pointer = detail::default_argument, + class Category = detail::default_argument, + class Distance = detail::default_argument > struct iterator_adaptor : #ifdef BOOST_RELOPS_AMBIGUITY_BUG