Revert "Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work."
[dyninst.git] / external / boost / detail / named_template_params.hpp
1 // (C) Copyright Jeremy Siek 2001.\r
2 // Distributed under the Boost Software License, Version 1.0. (See\r
3 // accompanying file LICENSE_1_0.txt or copy at\r
4 // http://www.boost.org/LICENSE_1_0.txt)\r
5 \r
6 // Revision History:\r
7 \r
8 // 04 Oct 2001   David Abrahams\r
9 //      Changed name of "bind" to "select" to avoid problems with MSVC.\r
10 \r
11 #ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP\r
12 #define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP\r
13 \r
14 #include <boost/type_traits/conversion_traits.hpp>\r
15 #include <boost/type_traits/composite_traits.hpp> // for is_reference\r
16 #if defined(__BORLANDC__)\r
17 #include <boost/type_traits/ice.hpp>\r
18 #endif\r
19 \r
20 namespace boost {\r
21   namespace detail {\r
22     \r
23     struct default_argument { };\r
24 \r
25     struct dummy_default_gen {\r
26       template <class Base, class Traits>\r
27       struct select {\r
28         typedef default_argument type;\r
29       };\r
30     };\r
31 \r
32    // This class template is a workaround for MSVC.\r
33    template <class Gen> struct default_generator {\r
34      typedef detail::dummy_default_gen type;\r
35    };\r
36 \r
37     template <class T> struct is_default { \r
38       enum { value = false };  \r
39       typedef type_traits::no_type type;\r
40     };\r
41     template <> struct is_default<default_argument> { \r
42       enum { value = true }; \r
43       typedef type_traits::yes_type type;\r
44     };\r
45 \r
46     struct choose_default {\r
47       template <class Arg, class DefaultGen, class Base, class Traits>\r
48       struct select {\r
49         typedef typename default_generator<DefaultGen>::type Gen;\r
50         typedef typename Gen::template select<Base,Traits>::type type;\r
51       };\r
52     };\r
53     struct choose_arg {\r
54       template <class Arg, class DefaultGen, class Base, class Traits>\r
55       struct select {\r
56         typedef Arg type;\r
57       };\r
58     };\r
59 \r
60 #if defined(__BORLANDC__)\r
61     template <class UseDefault>\r
62     struct choose_arg_or_default { typedef choose_arg type; };\r
63     template <>\r
64     struct choose_arg_or_default<type_traits::yes_type> {\r
65       typedef choose_default type;\r
66     };\r
67 #else\r
68     template <bool UseDefault>\r
69     struct choose_arg_or_default { typedef choose_arg type; };\r
70     template <>\r
71     struct choose_arg_or_default<true> {\r
72       typedef choose_default type;\r
73     };\r
74 #endif\r
75     \r
76     template <class Arg, class DefaultGen, class Base, class Traits>\r
77     class resolve_default {\r
78 #if defined(__BORLANDC__)\r
79       typedef typename choose_arg_or_default<typename is_default<Arg>::type>::type Selector;\r
80 #else\r
81       // This usually works for Borland, but I'm seeing weird errors in\r
82       // iterator_adaptor_test.cpp when using this method.\r
83       enum { is_def = is_default<Arg>::value };\r
84       typedef typename choose_arg_or_default<is_def>::type Selector;\r
85 #endif\r
86     public:\r
87       typedef typename Selector\r
88         ::template select<Arg, DefaultGen, Base, Traits>::type type;\r
89     };\r
90 \r
91     // To differentiate an unnamed parameter from a traits generator\r
92     // we use is_convertible<X, iter_traits_gen_base>.\r
93     struct named_template_param_base { };\r
94 \r
95     template <class X>\r
96     struct is_named_param_list {\r
97       enum { value  = is_convertible<X, named_template_param_base>::value };\r
98     };\r
99     \r
100     struct choose_named_params {\r
101       template <class Prev> struct select { typedef Prev type; };\r
102     };\r
103     struct choose_default_arg {\r
104       template <class Prev> struct select { \r
105         typedef detail::default_argument type;\r
106       };\r
107     };\r
108 \r
109     template <bool Named> struct choose_default_dispatch_;\r
110     template <> struct choose_default_dispatch_<true> {\r
111       typedef choose_named_params type;\r
112     };\r
113     template <> struct choose_default_dispatch_<false> {\r
114       typedef choose_default_arg type;\r
115     };\r
116     // The use of inheritance here is a Solaris Forte 6 workaround.\r
117     template <bool Named> struct choose_default_dispatch\r
118       : public choose_default_dispatch_<Named> { };\r
119 \r
120     template <class PreviousArg>\r
121     struct choose_default_argument {\r
122       enum { is_named = is_named_param_list<PreviousArg>::value };\r
123       typedef typename choose_default_dispatch<is_named>::type Selector;\r
124       typedef typename Selector::template select<PreviousArg>::type type;\r
125     };\r
126 \r
127     // This macro assumes that there is a class named default_##TYPE\r
128     // defined before the application of the macro.  This class should\r
129     // have a single member class template named "select" with two\r
130     // template parameters: the type of the class being created (e.g.,\r
131     // the iterator_adaptor type when creating iterator adaptors) and\r
132     // a traits class. The select class should have a single typedef\r
133     // named "type" that produces the default for TYPE.  See\r
134     // boost/iterator_adaptors.hpp for an example usage.  Also,\r
135     // applications of this macro must be placed in namespace\r
136     // boost::detail.\r
137 \r
138 #define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \\r
139     struct get_##TYPE##_from_named { \\r
140       template <class Base, class NamedParams, class Traits> \\r
141       struct select { \\r
142           typedef typename NamedParams::traits NamedTraits; \\r
143           typedef typename NamedTraits::TYPE TYPE; \\r
144           typedef typename resolve_default<TYPE, \\r
145             default_##TYPE, Base, NamedTraits>::type type; \\r
146       }; \\r
147     }; \\r
148     struct pass_thru_##TYPE { \\r
149       template <class Base, class Arg, class Traits> struct select { \\r
150           typedef typename resolve_default<Arg, \\r
151             default_##TYPE, Base, Traits>::type type; \\r
152       };\\r
153     }; \\r
154     template <int NamedParam> \\r
155     struct get_##TYPE##_dispatch { }; \\r
156     template <> struct get_##TYPE##_dispatch<1> { \\r
157       typedef get_##TYPE##_from_named type; \\r
158     }; \\r
159     template <> struct get_##TYPE##_dispatch<0> { \\r
160       typedef pass_thru_##TYPE type; \\r
161     }; \\r
162     template <class Base, class X, class Traits>  \\r
163     class get_##TYPE { \\r
164       enum { is_named = is_named_param_list<X>::value }; \\r
165       typedef typename get_##TYPE##_dispatch<is_named>::type Selector; \\r
166     public: \\r
167       typedef typename Selector::template select<Base, X, Traits>::type type; \\r
168     }; \\r
169     template <> struct default_generator<default_##TYPE> { \\r
170       typedef default_##TYPE type; \\r
171     }\r
172 \r
173     \r
174   } // namespace detail\r
175 } // namespace boost\r
176 \r
177 #endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP\r