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