Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
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>
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
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
00082
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
00092
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
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
00128
00129
00130
00131
00132
00133
00134
00135
00136
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 }
00175 }
00176
00177 #endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP