// (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 #include // for is_reference #include #if defined(__BORLANDC__) #include #endif 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 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 type_traits::no_type type; }; template <> struct is_default { enum { value = true }; typedef 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; }; }; #if defined(__BORLANDC__) template struct choose_arg_or_default { typedef choose_arg type; }; template <> struct choose_arg_or_default { typedef choose_default type; }; #else template struct choose_arg_or_default { typedef choose_arg type; }; template <> struct choose_arg_or_default { typedef choose_default type; }; #endif template class resolve_default { #if defined(__BORLANDC__) typedef typename choose_arg_or_default::type>::type Selector; #else // This usually works for Borland, but I'm seeing weird errors in // iterator_adaptor_test.cpp when using this method. enum { is_def = is_default::value }; typedef typename choose_arg_or_default::type Selector; #endif public: typedef typename Selector ::template bind::type type; }; template struct is_named_param_list { enum { value = is_convertible::value }; }; struct choose_named_params { template struct bind { typedef Prev type; }; }; struct choose_default_arg { template struct bind { typedef detail::default_argument type; }; }; template struct choose_default_dispatch { }; template <> struct choose_default_dispatch { typedef choose_named_params type; }; template <> struct choose_default_dispatch { typedef choose_default_arg type; }; template struct choose_default_argument { enum { is_named = is_named_param_list::value }; typedef typename choose_default_dispatch::type Selector; 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) \ 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; }; }; } //namespace detail template struct find_param { typedef typename detail::find_param_impl::template bind::type type; }; template struct param_p { typedef T type; typedef Tag tag; }; 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