1 // Copyright Daniel Wallin 2006. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 
5 #ifndef BOOST_PARAMETER_CAST_060902_HPP
6 # define BOOST_PARAMETER_CAST_060902_HPP
7 
8 # include <boost/detail/workaround.hpp>
9 
10 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
11 #  include <boost/type_traits/add_reference.hpp>
12 #  include <boost/type_traits/remove_const.hpp>
13 # endif
14 
15 namespace boost { namespace parameter { namespace aux {
16 
17 struct use_default_tag {};
18 
19 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
20 
21 #  define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value
22 
23 # else
24 
25 // Handles possible implicit casts. Used by preprocessor.hpp to
26 // normalize user input.
27 //
28 // cast<void*>::execute() is identity
29 // cast<void*(X)>::execute() is identity
30 // cast<void(X)>::execute() casts to X
31 //
32 // preprocessor.hpp uses this like this:
33 //
34 //   #define X(value, predicate)
35 //      cast<void predicate>::execute(value)
36 //
37 //   X(something, *)
38 //   X(something, *(predicate))
39 //   X(something, (int))
40 
41 template <class T, class Args>
42 struct cast;
43 
44 template <class Args>
45 struct cast<void*, Args>
46 {
executeboost::parameter::aux::cast47     static use_default_tag execute(use_default_tag)
48     {
49         return use_default_tag();
50     }
51 
remove_constboost::parameter::aux::cast52     static use_default_tag remove_const(use_default_tag)
53     {
54         return use_default_tag();
55     }
56 
57     template <class U>
executeboost::parameter::aux::cast58     static U& execute(U& value)
59     {
60         return value;
61     }
62 
63     template <class U>
remove_constboost::parameter::aux::cast64     static U& remove_const(U& x)
65     {
66         return x;
67     }
68 };
69 
70 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
71 
72 typedef void* voidstar;
73 
74 template <class T, class Args>
75 struct cast<voidstar(T), Args>
76   : cast<void*, Args>
77 {
78 };
79 
80 #else
81 
82 template <class T, class Args>
83 struct cast<void*(T), Args>
84   : cast<void*, Args>
85 {
86 };
87 
88 #endif
89 
90 // This is a hack used in cast<> to turn the user supplied type,
91 // which may or may not be a placeholder expression into one, so
92 // that it will be properly evaluated by mpl::apply.
93 template <class T, class Dummy = mpl::_1>
94 struct as_placeholder_expr
95 {
96     typedef T type;
97 };
98 
99 template <class T, class Args>
100 struct cast<void(T), Args>
101 {
102     typedef typename mpl::apply2<
103         as_placeholder_expr<T>, Args, Args>::type type0;
104 
105     typedef typename boost::add_reference<
106         typename boost::remove_const<type0>::type
107     >::type reference;
108 
executeboost::parameter::aux::cast109     static use_default_tag execute(use_default_tag)
110     {
111         return use_default_tag();
112     }
113 
remove_constboost::parameter::aux::cast114     static use_default_tag remove_const(use_default_tag)
115     {
116         return use_default_tag();
117     }
118 
executeboost::parameter::aux::cast119     static type0 execute(type0 value)
120     {
121         return value;
122     }
123 
124     template <class U>
remove_constboost::parameter::aux::cast125     static reference remove_const(U const& x)
126     {
127         return const_cast<reference>(x);
128     }
129 };
130 
131 #  define BOOST_PARAMETER_FUNCTION_CAST(value, predicate, args) \
132     boost::parameter::aux::cast<void predicate, args>::remove_const( \
133         boost::parameter::aux::cast<void predicate, args>::execute(value) \
134     )
135 
136 # endif
137 
138 }}} // namespace boost::parameter::aux
139 
140 #endif // BOOST_PARAMETER_CAST_060902_HPP
141 
142