diff --git a/include/boost/detail/named_template_params.hpp b/include/boost/detail/named_template_params.hpp index 4648dc6..0a9a745 100644 --- a/include/boost/detail/named_template_params.hpp +++ b/include/boost/detail/named_template_params.hpp @@ -4,31 +4,90 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +// Revision History: +// +// 27 June 2001 Jeremy Siek +// Simplified the mechanism. +// 08 Mar 2001 Jeremy Siek +// Initial version. + #ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP #define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP #include +#include #include // for is_reference +#include #if defined(__BORLANDC__) #include #endif +/* + template + struct find_param; + + This searches through a compile-time associative "List" of types + to find the value (which is a type) associated with key specified + by "Tag". The list is a lisp-style cons list using std::pair. + The first_type of each pair must be a type that has a + "type" and "tag" member, where "type" is the value and "tag" + is the key that will match with the "Tag". The *_is classes + in boost/iterator_adaptors.hpp (like value_type_is) are + example of such types. + + + struct named_template_param_base; + template struct wrap_param; + + The named_template_param_base can be used to distinguish + normal arguments from named arguments, the *_is classes + inherit from named_template_param_base. The wrap_param + class returns named arguments unchanged and returns + normal arguments wrapped with the param_is type so + that it will fit into the associative list. + + + template + class resolve_default; + + This class figures out what the argument type of a parameter is + based on the argument passed in (which might be the + default_argument type), a default generator, and an Info type, + + The DefaultGen type should have a single member class template + named "bind" with one template parameter for the Info type. The + bind class should have a single typedef named "type" that produces + the default. See boost/iterator_adaptors.hpp for example usage. + + The Info type is any type that might be useful in computing the + default inside of the "bind" member class. + +*/ + + namespace boost { + + // To differentiate an unnamed parameter from a traits generator + // we use is_convertible. + struct named_template_param_base { }; + namespace detail { struct default_argument { }; struct dummy_default_gen { - template + template struct bind { typedef default_argument type; }; }; - // This class template is a workaround for MSVC. - template struct default_generator { - typedef detail::dummy_default_gen type; - }; + // Specializations of this class template are used as a workaround + // for MSVC. For other compilers this unspecialized version is + // used (which doesn't really do anything). + template struct default_generator { + typedef Gen type; + }; template struct is_default { enum { value = false }; @@ -40,14 +99,14 @@ namespace boost { }; struct choose_default { - template + template struct bind { typedef typename default_generator::type Gen; - typedef typename Gen::template bind::type type; + typedef typename Gen::template bind::type type; }; }; struct choose_arg { - template + template struct bind { typedef Arg type; }; @@ -69,7 +128,7 @@ namespace boost { }; #endif - template + template class resolve_default { #if defined(__BORLANDC__) typedef typename choose_arg_or_default::type>::type Selector; @@ -81,13 +140,9 @@ namespace boost { #endif public: typedef typename Selector - ::template bind::type type; + ::template bind::type type; }; - // To differentiate an unnamed parameter from a traits generator - // we use is_convertible. - struct named_template_param_base { }; - template struct is_named_param_list { enum { value = is_convertible::value }; @@ -118,54 +173,52 @@ namespace boost { typedef typename Selector::template bind::type type; }; - // This macro assumes that there is a class named default_##TYPE - // defined before the application of the macro. This class should - // have a single member class template named "bind" with two - // template parameters: the type of the class being created (e.g., - // the iterator_adaptor type when creating iterator adaptors) and - // a traits class. The bind class should have a single typedef - // named "type" that produces the default for TYPE. See - // boost/iterator_adaptors.hpp for an example usage. Also, - // applications of this macro must be placed in namespace - // boost::detail. - -#define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \ - struct get_##TYPE##_from_named { \ - template \ - struct bind { \ - typedef typename NamedParams::traits NamedTraits; \ - typedef typename NamedTraits::TYPE TYPE; \ - typedef typename resolve_default::type type; \ - }; \ - }; \ - struct pass_thru_##TYPE { \ - template struct bind { \ - typedef typename resolve_default::type type; \ - };\ - }; \ - template \ - struct get_##TYPE##_dispatch { }; \ - template <> struct get_##TYPE##_dispatch<1> { \ - typedef get_##TYPE##_from_named type; \ - }; \ - template <> struct get_##TYPE##_dispatch<0> { \ - typedef pass_thru_##TYPE type; \ - }; \ - template \ - class get_##TYPE { \ - enum { is_named = is_named_param_list::value }; \ - typedef typename get_##TYPE##_dispatch::type Selector; \ - public: \ - typedef typename Selector::template bind::type type; \ - }; \ - template <> struct default_generator { \ - typedef default_##TYPE type; \ - } - - } // namespace detail + + struct list_end_type { }; + + namespace detail { + template + struct find_param_impl { + template class bind { + typedef typename List::first_type Param; + typedef typename List::second_type Rest; + typedef typename find_param_impl::template bind::type + RestType; + enum { is_same_tag = is_same::value }; + public: + typedef typename ct_if::type type; + }; + }; + template <> + struct find_param_impl { + template struct bind { + typedef default_argument type; + }; + }; + + template + struct param_is { + typedef T type; + typedef Tag tag; + }; + + } //namespace detail + + template struct find_param { + typedef typename detail::find_param_impl::template bind::type + type; + }; + + template + struct wrap_param { + enum { is_named_param = + is_convertible::value }; + typedef typename ct_if >::type type; + }; + } // namespace boost #endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP