diff --git a/include/boost/detail/named_template_params.hpp b/include/boost/detail/named_template_params.hpp new file mode 100644 index 0000000..10cdba4 --- /dev/null +++ b/include/boost/detail/named_template_params.hpp @@ -0,0 +1,122 @@ +// (C) Copyright Jeremy Siek 2001. 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. + +#ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP +#define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP + +#include +#include + +namespace boost { + namespace detail { + + struct default_argument { }; + + struct dummy_default_gen { + 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; + }; + + template struct is_default { + enum { value = false }; + typedef boost::type_traits::no_type type; + }; + template <> struct is_default { + enum { value = true }; + typedef boost::type_traits::yes_type type; + }; + + struct choose_default { + template + struct bind { + typedef typename default_generator::type Gen; + typedef typename Gen::template bind::type type; + }; + }; + struct choose_arg { + template + struct bind { + 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< + is_default::type + >::type Selector; + public: + typedef typename Selector + ::template bind::type type; + }; + + // To differentiate an unnamed parameter from a traits generator + // we use is_convertible. + struct named_template_param_base { }; + + // 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::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_convertible::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 +} // namespace boost + +#endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP