1 | // - construct.hpp -- Lambda 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_CONSTRUCT_HPP) |
15 | #define BOOST_LAMBDA_CONSTRUCT_HPP |
16 | |
17 | #include "boost/type_traits/remove_cv.hpp" |
18 | #include "boost/type_traits/is_pointer.hpp" |
19 | |
20 | namespace boost { |
21 | namespace lambda { |
22 | |
23 | // constructor is used together with bind. constructor<A> creates a bindable |
24 | // function object that passes its arguments forward to a constructor call |
25 | // of type A |
26 | |
27 | template<class T> struct constructor { |
28 | |
29 | template <class U> struct sig { typedef T type; }; |
30 | |
31 | T operator()() const { |
32 | return T(); |
33 | } |
34 | |
35 | template<class A1> |
36 | T operator()(A1& a1) const { |
37 | return T(a1); |
38 | } |
39 | |
40 | template<class A1, class A2> |
41 | T operator()(A1& a1, A2& a2) const { |
42 | return T(a1, a2); |
43 | } |
44 | |
45 | template<class A1, class A2, class A3> |
46 | T operator()(A1& a1, A2& a2, A3& a3) const { |
47 | return T(a1, a2, a3); |
48 | } |
49 | |
50 | template<class A1, class A2, class A3, class A4> |
51 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4) const { |
52 | return T(a1, a2, a3, a4); |
53 | } |
54 | |
55 | template<class A1, class A2, class A3, class A4, class A5> |
56 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) const { |
57 | return T(a1, a2, a3, a4, a5); |
58 | } |
59 | |
60 | template<class A1, class A2, class A3, class A4, class A5, class A6> |
61 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) const { |
62 | return T(a1, a2, a3, a4, a5, a6); |
63 | } |
64 | |
65 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
66 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) const { |
67 | return T(a1, a2, a3, a4, a5, a6, a7); |
68 | } |
69 | |
70 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
71 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) const { |
72 | return T(a1, a2, a3, a4, a5, a6, a7, a8); |
73 | } |
74 | |
75 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
76 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) const { |
77 | return T(a1, a2, a3, a4, a5, a6, a7, a8, a9); |
78 | } |
79 | |
80 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> |
81 | T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9, A10& a10) const { |
82 | return T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); |
83 | } |
84 | |
85 | }; |
86 | |
87 | |
88 | namespace detail { |
89 | |
90 | // A standard conforming compiler could disambiguate between |
91 | // A1* and A1&, but not all compilers do that, so we need the |
92 | // helpers |
93 | |
94 | |
95 | template <bool IsPointer> |
96 | struct destructor_helper { |
97 | |
98 | template<class A1> |
99 | static void exec(A1& a1) { |
100 | // remove all the qualifiers, not sure whether it is necessary |
101 | typedef typename boost::remove_cv<A1>::type plainA1; |
102 | a1.~plainA1(); |
103 | } |
104 | }; |
105 | |
106 | template <> |
107 | struct destructor_helper<true> { |
108 | |
109 | template<class A1> |
110 | static void exec(A1* a1) { |
111 | typedef typename boost::remove_cv<A1>::type plainA1; |
112 | (*a1).~plainA1(); |
113 | } |
114 | }; |
115 | |
116 | } |
117 | |
118 | // destructor funtion object |
119 | struct destructor { |
120 | |
121 | template <class T> struct sig { typedef void type; }; |
122 | |
123 | template<class A1> |
124 | void operator()(A1& a1) const { |
125 | typedef typename boost::remove_cv<A1>::type plainA1; |
126 | detail::destructor_helper<boost::is_pointer<plainA1>::value>::exec(a1); |
127 | } |
128 | }; |
129 | |
130 | |
131 | |
132 | // new_ptr is used together with bind. |
133 | |
134 | // note: placement new is not supported |
135 | |
136 | template<class T> struct new_ptr { |
137 | |
138 | template <class U> struct sig { typedef T* type; }; |
139 | |
140 | T* operator()() const { |
141 | return new T(); |
142 | } |
143 | |
144 | template<class A1> |
145 | T* operator()(A1& a1) const { |
146 | return new T(a1); |
147 | } |
148 | |
149 | template<class A1, class A2> |
150 | T* operator()(A1& a1, A2& a2) const { |
151 | return new T(a1, a2); |
152 | } |
153 | |
154 | template<class A1, class A2, class A3> |
155 | T* operator()(A1& a1, A2& a2, A3& a3) const { |
156 | return new T(a1, a2, a3); |
157 | } |
158 | |
159 | template<class A1, class A2, class A3, class A4> |
160 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4) const { |
161 | return new T(a1, a2, a3, a4); |
162 | } |
163 | |
164 | template<class A1, class A2, class A3, class A4, class A5> |
165 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) const { |
166 | return new T(a1, a2, a3, a4, a5); |
167 | } |
168 | |
169 | template<class A1, class A2, class A3, class A4, class A5, class A6> |
170 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) const { |
171 | return new T(a1, a2, a3, a4, a5, a6); |
172 | } |
173 | |
174 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
175 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) const { |
176 | return new T(a1, a2, a3, a4, a5, a6, a7); |
177 | } |
178 | |
179 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
180 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) const { |
181 | return new T(a1, a2, a3, a4, a5, a6, a7, a8); |
182 | } |
183 | |
184 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
185 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) const { |
186 | return new T(a1, a2, a3, a4, a5, a6, a7, a8, a9); |
187 | } |
188 | |
189 | template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> |
190 | T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9, A10& a10) const { |
191 | return new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); |
192 | } |
193 | |
194 | }; |
195 | |
196 | // delete_ptr return void |
197 | |
198 | struct delete_ptr { |
199 | |
200 | template <class U> struct sig { typedef void type; }; |
201 | |
202 | template <class A1> |
203 | void operator()(A1& a1) const { |
204 | delete a1; |
205 | } |
206 | |
207 | }; |
208 | |
209 | |
210 | // new_array is used together with bind. |
211 | |
212 | template<class T> struct new_array { |
213 | |
214 | template <class U> struct sig { typedef T* type; }; |
215 | |
216 | T* operator()(int size) const { |
217 | return new T[size]; |
218 | } |
219 | }; |
220 | |
221 | |
222 | // delete_ptr return void |
223 | |
224 | struct delete_array { |
225 | |
226 | template <class U> struct sig { typedef void type; }; |
227 | |
228 | template <class A1> |
229 | void operator()(A1& a1) const { |
230 | delete[] a1; |
231 | } |
232 | |
233 | }; |
234 | |
235 | |
236 | |
237 | } // namespace lambda |
238 | } // namespace boost |
239 | |
240 | #endif |
241 | |