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
20namespace boost {
21namespace 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
27template<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
88namespace 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
95template <bool IsPointer>
96struct 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
106template <>
107struct 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
119struct 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
136template<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
198struct 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
212template<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
224struct 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