1 | // - casts.hpp -- BLambda Library ------------- |
2 | // |
3 | // Copyright (C) 2000 Gary Powell (powellg@amazon.com) |
4 | // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) |
5 | // |
6 | // Distributed under the Boost Software License, Version 1.0. (See |
7 | // accompanying file LICENSE_1_0.txt or copy at |
8 | // http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | // For more information, see http://www.boost.org |
11 | |
12 | // ----------------------------------------------- |
13 | |
14 | #if !defined(BOOST_LAMBDA_CASTS_HPP) |
15 | #define BOOST_LAMBDA_CASTS_HPP |
16 | |
17 | #include "boost/lambda/detail/suppress_unused.hpp" |
18 | #include "boost/lambda/core.hpp" |
19 | |
20 | #include <typeinfo> |
21 | |
22 | namespace boost { |
23 | namespace lambda { |
24 | |
25 | template<class Act, class Args> |
26 | struct return_type_N; |
27 | |
28 | template<class T> class cast_action; |
29 | |
30 | template<class T> class static_cast_action; |
31 | template<class T> class dynamic_cast_action; |
32 | template<class T> class const_cast_action; |
33 | template<class T> class reinterpret_cast_action; |
34 | |
35 | class typeid_action; |
36 | class sizeof_action; |
37 | |
38 | // Cast actions |
39 | |
40 | template<class T> class cast_action<static_cast_action<T> > |
41 | { |
42 | public: |
43 | template<class RET, class Arg1> |
44 | static RET apply(Arg1 &a1) { |
45 | return static_cast<RET>(a1); |
46 | } |
47 | }; |
48 | |
49 | template<class T> class cast_action<dynamic_cast_action<T> > { |
50 | public: |
51 | template<class RET, class Arg1> |
52 | static RET apply(Arg1 &a1) { |
53 | return dynamic_cast<RET>(a1); |
54 | } |
55 | }; |
56 | |
57 | template<class T> class cast_action<const_cast_action<T> > { |
58 | public: |
59 | template<class RET, class Arg1> |
60 | static RET apply(Arg1 &a1) { |
61 | return const_cast<RET>(a1); |
62 | } |
63 | }; |
64 | |
65 | template<class T> class cast_action<reinterpret_cast_action<T> > { |
66 | public: |
67 | template<class RET, class Arg1> |
68 | static RET apply(Arg1 &a1) { |
69 | return reinterpret_cast<RET>(a1); |
70 | } |
71 | }; |
72 | |
73 | // typeid action |
74 | class typeid_action { |
75 | public: |
76 | template<class RET, class Arg1> |
77 | static RET apply(Arg1 &a1) { |
78 | detail::suppress_unused_variable_warnings(a1); |
79 | return typeid(a1); |
80 | } |
81 | }; |
82 | |
83 | // sizeof action |
84 | class sizeof_action |
85 | { |
86 | public: |
87 | template<class RET, class Arg1> |
88 | static RET apply(Arg1 &a1) { |
89 | return sizeof(a1); |
90 | } |
91 | }; |
92 | |
93 | |
94 | // return types of casting lambda_functors (all "T" type.) |
95 | |
96 | template<template <class> class cast_type, class T, class A> |
97 | struct return_type_N<cast_action< cast_type<T> >, A> { |
98 | typedef T type; |
99 | }; |
100 | |
101 | // return type of typeid_action |
102 | template<class A> |
103 | struct return_type_N<typeid_action, A> { |
104 | typedef std::type_info const & type; |
105 | }; |
106 | |
107 | // return type of sizeof_action |
108 | |
109 | template<class A> |
110 | struct return_type_N<sizeof_action, A> { |
111 | typedef std::size_t type; |
112 | }; |
113 | |
114 | |
115 | // the four cast & typeid overloads. |
116 | // casts can take ordinary variables (not just lambda functors) |
117 | |
118 | // static_cast |
119 | template <class T, class Arg1> |
120 | inline const lambda_functor< |
121 | lambda_functor_base< |
122 | action<1, cast_action<static_cast_action<T> > >, |
123 | tuple<typename const_copy_argument <const Arg1>::type> |
124 | > |
125 | > |
126 | ll_static_cast(const Arg1& a1) { |
127 | return |
128 | lambda_functor_base< |
129 | action<1, cast_action<static_cast_action<T> > >, |
130 | tuple<typename const_copy_argument <const Arg1>::type> |
131 | > |
132 | ( tuple<typename const_copy_argument <const Arg1>::type>(a1)); |
133 | } |
134 | |
135 | // dynamic_cast |
136 | template <class T, class Arg1> |
137 | inline const lambda_functor< |
138 | lambda_functor_base< |
139 | action<1, cast_action<dynamic_cast_action<T> > >, |
140 | tuple<typename const_copy_argument <const Arg1>::type> |
141 | > |
142 | > |
143 | ll_dynamic_cast(const Arg1& a1) { |
144 | return |
145 | lambda_functor_base< |
146 | action<1, cast_action<dynamic_cast_action<T> > >, |
147 | tuple<typename const_copy_argument <const Arg1>::type> |
148 | > |
149 | ( tuple<typename const_copy_argument <const Arg1>::type>(a1)); |
150 | } |
151 | |
152 | // const_cast |
153 | template <class T, class Arg1> |
154 | inline const lambda_functor< |
155 | lambda_functor_base< |
156 | action<1, cast_action<const_cast_action<T> > >, |
157 | tuple<typename const_copy_argument <const Arg1>::type> |
158 | > |
159 | > |
160 | ll_const_cast(const Arg1& a1) { |
161 | return |
162 | lambda_functor_base< |
163 | action<1, cast_action<const_cast_action<T> > >, |
164 | tuple<typename const_copy_argument <const Arg1>::type> |
165 | > |
166 | ( tuple<typename const_copy_argument <const Arg1>::type>(a1)); |
167 | } |
168 | |
169 | // reinterpret_cast |
170 | template <class T, class Arg1> |
171 | inline const lambda_functor< |
172 | lambda_functor_base< |
173 | action<1, cast_action<reinterpret_cast_action<T> > >, |
174 | tuple<typename const_copy_argument <const Arg1>::type> |
175 | > |
176 | > |
177 | ll_reinterpret_cast(const Arg1& a1) { |
178 | return |
179 | lambda_functor_base< |
180 | action<1, cast_action<reinterpret_cast_action<T> > >, |
181 | tuple<typename const_copy_argument <const Arg1>::type> |
182 | > |
183 | ( tuple<typename const_copy_argument <const Arg1>::type>(a1)); |
184 | } |
185 | |
186 | // typeid |
187 | // can be applied to a normal variable as well (can refer to a polymorphic |
188 | // class object) |
189 | template <class Arg1> |
190 | inline const lambda_functor< |
191 | lambda_functor_base< |
192 | action<1, typeid_action>, |
193 | tuple<typename const_copy_argument <const Arg1>::type> |
194 | > |
195 | > |
196 | ll_typeid(const Arg1& a1) { |
197 | return |
198 | lambda_functor_base< |
199 | action<1, typeid_action>, |
200 | tuple<typename const_copy_argument <const Arg1>::type> |
201 | > |
202 | ( tuple<typename const_copy_argument <const Arg1>::type>(a1)); |
203 | } |
204 | |
205 | // sizeof(expression) |
206 | // Always takes a lambda expression (if not, built in sizeof will do) |
207 | template <class Arg1> |
208 | inline const lambda_functor< |
209 | lambda_functor_base< |
210 | action<1, sizeof_action>, |
211 | tuple<lambda_functor<Arg1> > |
212 | > |
213 | > |
214 | ll_sizeof(const lambda_functor<Arg1>& a1) { |
215 | return |
216 | lambda_functor_base< |
217 | action<1, sizeof_action>, |
218 | tuple<lambda_functor<Arg1> > |
219 | > |
220 | ( tuple<lambda_functor<Arg1> >(a1)); |
221 | } |
222 | |
223 | } // namespace lambda |
224 | } // namespace boost |
225 | |
226 | #endif |
227 | |