src/sysc/packages/boost/detail/named_template_params.hpp

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

Generated on Wed Apr 25 13:53:28 2007 for SystemC by  doxygen 1.5.1