named_template_params.hpp
Go to the documentation of this file.
00001 // (C) Copyright Jeremy Siek 2001.
00002 // Distributed under the Boost Software License, Version 1.0. (See
00003 // accompanying file LICENSE_1_0.txt or copy at
00004 // http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 // Revision History:
00007 
00008 // 04 Oct 2001   David Abrahams
00009 //      Changed name of "bind" to "select" to avoid problems with MSVC.
00010 
00011 #ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP
00012 #define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP
00013 
00014 #include <boost/type_traits/conversion_traits.hpp>
00015 #include <boost/type_traits/composite_traits.hpp> // for is_reference
00016 #if defined(__BORLANDC__)
00017 #include <boost/type_traits/ice.hpp>
00018 #endif
00019 
00020 namespace boost {
00021   namespace detail {
00022     
00023     struct default_argument { };
00024 
00025     struct dummy_default_gen {
00026       template <class Base, class Traits>
00027       struct select {
00028         typedef default_argument type;
00029       };
00030     };
00031 
00032    // This class template is a workaround for MSVC.
00033    template <class Gen> struct default_generator {
00034      typedef detail::dummy_default_gen type;
00035    };
00036 
00037     template <class T> struct is_default { 
00038       enum { value = false };  
00039       typedef type_traits::no_type type;
00040     };
00041     template <> struct is_default<default_argument> { 
00042       enum { value = true }; 
00043       typedef type_traits::yes_type type;
00044     };
00045 
00046     struct choose_default {
00047       template <class Arg, class DefaultGen, class Base, class Traits>
00048       struct select {
00049         typedef typename default_generator<DefaultGen>::type Gen;
00050         typedef typename Gen::template select<Base,Traits>::type type;
00051       };
00052     };
00053     struct choose_arg {
00054       template <class Arg, class DefaultGen, class Base, class Traits>
00055       struct select {
00056         typedef Arg type;
00057       };
00058     };
00059 
00060 #if defined(__BORLANDC__)
00061     template <class UseDefault>
00062     struct choose_arg_or_default { typedef choose_arg type; };
00063     template <>
00064     struct choose_arg_or_default<type_traits::yes_type> {
00065       typedef choose_default type;
00066     };
00067 #else
00068     template <bool UseDefault>
00069     struct choose_arg_or_default { typedef choose_arg type; };
00070     template <>
00071     struct choose_arg_or_default<true> {
00072       typedef choose_default type;
00073     };
00074 #endif
00075     
00076     template <class Arg, class DefaultGen, class Base, class Traits>
00077     class resolve_default {
00078 #if defined(__BORLANDC__)
00079       typedef typename choose_arg_or_default<typename is_default<Arg>::type>::type Selector;
00080 #else
00081       // This usually works for Borland, but I'm seeing weird errors in
00082       // iterator_adaptor_test.cpp when using this method.
00083       enum { is_def = is_default<Arg>::value };
00084       typedef typename choose_arg_or_default<is_def>::type Selector;
00085 #endif
00086     public:
00087       typedef typename Selector
00088         ::template select<Arg, DefaultGen, Base, Traits>::type type;
00089     };
00090 
00091     // To differentiate an unnamed parameter from a traits generator
00092     // we use is_convertible<X, iter_traits_gen_base>.
00093     struct named_template_param_base { };
00094 
00095     template <class X>
00096     struct is_named_param_list {
00097       enum { value  = is_convertible<X, named_template_param_base>::value };
00098     };
00099     
00100     struct choose_named_params {
00101       template <class Prev> struct select { typedef Prev type; };
00102     };
00103     struct choose_default_arg {
00104       template <class Prev> struct select { 
00105         typedef detail::default_argument type;
00106       };
00107     };
00108 
00109     template <bool Named> struct choose_default_dispatch_;
00110     template <> struct choose_default_dispatch_<true> {
00111       typedef choose_named_params type;
00112     };
00113     template <> struct choose_default_dispatch_<false> {
00114       typedef choose_default_arg type;
00115     };
00116     // The use of inheritance here is a Solaris Forte 6 workaround.
00117     template <bool Named> struct choose_default_dispatch
00118       : public choose_default_dispatch_<Named> { };
00119 
00120     template <class PreviousArg>
00121     struct choose_default_argument {
00122       enum { is_named = is_named_param_list<PreviousArg>::value };
00123       typedef typename choose_default_dispatch<is_named>::type Selector;
00124       typedef typename Selector::template select<PreviousArg>::type type;
00125     };
00126 
00127     // This macro assumes that there is a class named default_##TYPE
00128     // defined before the application of the macro.  This class should
00129     // have a single member class template named "select" with two
00130     // template parameters: the type of the class being created (e.g.,
00131     // the iterator_adaptor type when creating iterator adaptors) and
00132     // a traits class. The select class should have a single typedef
00133     // named "type" that produces the default for TYPE.  See
00134     // boost/iterator_adaptors.hpp for an example usage.  Also,
00135     // applications of this macro must be placed in namespace
00136     // boost::detail.
00137 
00138 #define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \
00139     struct get_##TYPE##_from_named { \
00140       template <class Base, class NamedParams, class Traits> \
00141       struct select { \
00142           typedef typename NamedParams::traits NamedTraits; \
00143           typedef typename NamedTraits::TYPE TYPE; \
00144           typedef typename resolve_default<TYPE, \
00145             default_##TYPE, Base, NamedTraits>::type type; \
00146       }; \
00147     }; \
00148     struct pass_thru_##TYPE { \
00149       template <class Base, class Arg, class Traits> struct select { \
00150           typedef typename resolve_default<Arg, \
00151             default_##TYPE, Base, Traits>::type type; \
00152       };\
00153     }; \
00154     template <int NamedParam> \
00155     struct get_##TYPE##_dispatch { }; \
00156     template <> struct get_##TYPE##_dispatch<1> { \
00157       typedef get_##TYPE##_from_named type; \
00158     }; \
00159     template <> struct get_##TYPE##_dispatch<0> { \
00160       typedef pass_thru_##TYPE type; \
00161     }; \
00162     template <class Base, class X, class Traits>  \
00163     class get_##TYPE { \
00164       enum { is_named = is_named_param_list<X>::value }; \
00165       typedef typename get_##TYPE##_dispatch<is_named>::type Selector; \
00166     public: \
00167       typedef typename Selector::template select<Base, X, Traits>::type type; \
00168     }; \
00169     template <> struct default_generator<default_##TYPE> { \
00170       typedef default_##TYPE type; \
00171     }
00172 
00173     
00174   } // namespace detail
00175 } // namespace boost
00176 
00177 #endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29