Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/unordered/detail/allocate.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 | |
2 // Copyright 2005-2011 Daniel James. | |
3 // Copyright 2009 Pablo Halpern. | |
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | |
7 // See http://www.boost.org/libs/unordered for documentation | |
8 | |
9 #ifndef BOOST_UNORDERED_ALLOCATE_HPP | |
10 #define BOOST_UNORDERED_ALLOCATE_HPP | |
11 | |
12 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
13 # pragma once | |
14 #endif | |
15 | |
16 #include <boost/unordered/detail/fwd.hpp> | |
17 #include <boost/move/move.hpp> | |
18 #include <boost/preprocessor/cat.hpp> | |
19 #include <boost/preprocessor/inc.hpp> | |
20 #include <boost/preprocessor/dec.hpp> | |
21 #include <boost/preprocessor/repetition/enum.hpp> | |
22 #include <boost/preprocessor/repetition/enum_params.hpp> | |
23 #include <boost/preprocessor/repetition/enum_binary_params.hpp> | |
24 #include <boost/preprocessor/repetition/repeat_from_to.hpp> | |
25 #include <boost/type_traits/is_class.hpp> | |
26 #include <boost/type_traits/add_lvalue_reference.hpp> | |
27 #include <boost/tuple/tuple.hpp> | |
28 #include <boost/utility/enable_if.hpp> | |
29 #include <boost/utility/addressof.hpp> | |
30 #include <boost/detail/select_type.hpp> | |
31 #include <boost/assert.hpp> | |
32 #include <utility> | |
33 | |
34 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) | |
35 #include <tuple> | |
36 #endif | |
37 | |
38 #if defined(BOOST_MSVC) | |
39 #pragma warning(push) | |
40 #pragma warning(disable:4512) // assignment operator could not be generated. | |
41 #pragma warning(disable:4345) // behavior change: an object of POD type | |
42 // constructed with an initializer of the form () | |
43 // will be default-initialized. | |
44 #endif | |
45 | |
46 #define BOOST_UNORDERED_EMPLACE_LIMIT 10 | |
47 | |
48 namespace boost { namespace unordered { namespace detail { | |
49 | |
50 //////////////////////////////////////////////////////////////////////////// | |
51 // Bits and pieces for implementing traits | |
52 | |
53 template <typename T> typename boost::add_lvalue_reference<T>::type make(); | |
54 struct choice9 { typedef char (&type)[9]; }; | |
55 struct choice8 : choice9 { typedef char (&type)[8]; }; | |
56 struct choice7 : choice8 { typedef char (&type)[7]; }; | |
57 struct choice6 : choice7 { typedef char (&type)[6]; }; | |
58 struct choice5 : choice6 { typedef char (&type)[5]; }; | |
59 struct choice4 : choice5 { typedef char (&type)[4]; }; | |
60 struct choice3 : choice4 { typedef char (&type)[3]; }; | |
61 struct choice2 : choice3 { typedef char (&type)[2]; }; | |
62 struct choice1 : choice2 { typedef char (&type)[1]; }; | |
63 choice1 choose(); | |
64 | |
65 typedef choice1::type yes_type; | |
66 typedef choice2::type no_type; | |
67 | |
68 struct private_type | |
69 { | |
70 private_type const &operator,(int) const; | |
71 }; | |
72 | |
73 template <typename T> | |
74 no_type is_private_type(T const&); | |
75 yes_type is_private_type(private_type const&); | |
76 | |
77 struct convert_from_anything { | |
78 template <typename T> | |
79 convert_from_anything(T const&); | |
80 }; | |
81 | |
82 //////////////////////////////////////////////////////////////////////////// | |
83 // emplace_args | |
84 // | |
85 // Either forwarding variadic arguments, or storing the arguments in | |
86 // emplace_args##n | |
87 | |
88 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
89 | |
90 #define BOOST_UNORDERED_EMPLACE_TEMPLATE typename... Args | |
91 #define BOOST_UNORDERED_EMPLACE_ARGS BOOST_FWD_REF(Args)... args | |
92 #define BOOST_UNORDERED_EMPLACE_FORWARD boost::forward<Args>(args)... | |
93 | |
94 #define BOOST_UNORDERED_EMPLACE_ARGS1(a0) a0 | |
95 #define BOOST_UNORDERED_EMPLACE_ARGS2(a0, a1) a0, a1 | |
96 #define BOOST_UNORDERED_EMPLACE_ARGS3(a0, a1, a2) a0, a1, a2 | |
97 | |
98 #else | |
99 | |
100 #define BOOST_UNORDERED_EMPLACE_TEMPLATE typename Args | |
101 #define BOOST_UNORDERED_EMPLACE_ARGS Args const& args | |
102 #define BOOST_UNORDERED_EMPLACE_FORWARD args | |
103 | |
104 #define BOOST_UNORDERED_FWD_PARAM(z, n, a) \ | |
105 BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(a, n) | |
106 | |
107 #define BOOST_UNORDERED_CALL_FORWARD(z, i, a) \ | |
108 boost::forward<BOOST_PP_CAT(A,i)>(BOOST_PP_CAT(a,i)) | |
109 | |
110 #define BOOST_UNORDERED_EARGS(z, n, _) \ | |
111 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \ | |
112 struct BOOST_PP_CAT(emplace_args, n) \ | |
113 { \ | |
114 BOOST_PP_REPEAT_##z(n, BOOST_UNORDERED_EARGS_MEMBER, _) \ | |
115 BOOST_PP_CAT(emplace_args, n) ( \ | |
116 BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, b) \ | |
117 ) : BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_EARGS_INIT, _) \ | |
118 {} \ | |
119 \ | |
120 }; \ | |
121 \ | |
122 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \ | |
123 inline BOOST_PP_CAT(emplace_args, n) < \ | |
124 BOOST_PP_ENUM_PARAMS_Z(z, n, A) \ | |
125 > create_emplace_args( \ | |
126 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, b) \ | |
127 ) \ | |
128 { \ | |
129 BOOST_PP_CAT(emplace_args, n) < \ | |
130 BOOST_PP_ENUM_PARAMS_Z(z, n, A) \ | |
131 > e(BOOST_PP_ENUM_PARAMS_Z(z, n, b)); \ | |
132 return e; \ | |
133 } | |
134 | |
135 #define BOOST_UNORDERED_EMPLACE_ARGS1 create_emplace_args | |
136 #define BOOST_UNORDERED_EMPLACE_ARGS2 create_emplace_args | |
137 #define BOOST_UNORDERED_EMPLACE_ARGS3 create_emplace_args | |
138 | |
139 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
140 | |
141 #define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \ | |
142 typedef BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(Arg, n); \ | |
143 BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n); | |
144 | |
145 #define BOOST_UNORDERED_EARGS_INIT(z, n, _) \ | |
146 BOOST_PP_CAT(a, n)( \ | |
147 boost::forward<BOOST_PP_CAT(A,n)>(BOOST_PP_CAT(b, n))) | |
148 | |
149 #else | |
150 | |
151 #define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \ | |
152 typedef typename boost::add_lvalue_reference<BOOST_PP_CAT(A, n)>::type \ | |
153 BOOST_PP_CAT(Arg, n); \ | |
154 BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n); | |
155 | |
156 #define BOOST_UNORDERED_EARGS_INIT(z, n, _) \ | |
157 BOOST_PP_CAT(a, n)(BOOST_PP_CAT(b, n)) | |
158 | |
159 #endif | |
160 | |
161 BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EARGS, | |
162 _) | |
163 | |
164 #undef BOOST_UNORDERED_DEFINE_EMPLACE_ARGS | |
165 #undef BOOST_UNORDERED_EARGS_MEMBER | |
166 #undef BOOST_UNORDERED_EARGS_INIT | |
167 | |
168 #endif | |
169 | |
170 }}} | |
171 | |
172 //////////////////////////////////////////////////////////////////////////////// | |
173 // | |
174 // Pick which version of allocator_traits to use | |
175 // | |
176 // 0 = Own partial implementation | |
177 // 1 = std::allocator_traits | |
178 // 2 = boost::container::allocator_traits | |
179 | |
180 #if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS) | |
181 # if defined(__GXX_EXPERIMENTAL_CXX0X__) && \ | |
182 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) | |
183 # define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0 | |
184 # elif defined(BOOST_MSVC) | |
185 # if BOOST_MSVC < 1400 | |
186 // Use container's allocator_traits for older versions of Visual | |
187 // C++ as I don't test with them. | |
188 # define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 2 | |
189 # endif | |
190 # endif | |
191 #endif | |
192 | |
193 #if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS) | |
194 # define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0 | |
195 #endif | |
196 | |
197 //////////////////////////////////////////////////////////////////////////////// | |
198 // | |
199 // Some utilities for implementing allocator_traits, but useful elsewhere so | |
200 // they're always defined. | |
201 | |
202 #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) | |
203 # include <type_traits> | |
204 #endif | |
205 | |
206 namespace boost { namespace unordered { namespace detail { | |
207 | |
208 //////////////////////////////////////////////////////////////////////////// | |
209 // Integral_constrant, true_type, false_type | |
210 // | |
211 // Uses the standard versions if available. | |
212 | |
213 #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) | |
214 | |
215 using std::integral_constant; | |
216 using std::true_type; | |
217 using std::false_type; | |
218 | |
219 #else | |
220 | |
221 template <typename T, T Value> | |
222 struct integral_constant { enum { value = Value }; }; | |
223 | |
224 typedef boost::unordered::detail::integral_constant<bool, true> true_type; | |
225 typedef boost::unordered::detail::integral_constant<bool, false> false_type; | |
226 | |
227 #endif | |
228 | |
229 //////////////////////////////////////////////////////////////////////////// | |
230 // Explicitly call a destructor | |
231 | |
232 #if defined(BOOST_MSVC) | |
233 #pragma warning(push) | |
234 #pragma warning(disable:4100) // unreferenced formal parameter | |
235 #endif | |
236 | |
237 namespace func { | |
238 template <class T> | |
239 inline void destroy(T* x) { | |
240 x->~T(); | |
241 } | |
242 } | |
243 | |
244 #if defined(BOOST_MSVC) | |
245 #pragma warning(pop) | |
246 #endif | |
247 | |
248 //////////////////////////////////////////////////////////////////////////// | |
249 // Expression test mechanism | |
250 // | |
251 // When SFINAE expressions are available, define | |
252 // BOOST_UNORDERED_HAS_FUNCTION which can check if a function call is | |
253 // supported by a class, otherwise define BOOST_UNORDERED_HAS_MEMBER which | |
254 // can detect if a class has the specified member, but not that it has the | |
255 // correct type, this is good enough for a passable impression of | |
256 // allocator_traits. | |
257 | |
258 #if !defined(BOOST_NO_SFINAE_EXPR) | |
259 | |
260 template <typename T, unsigned int> struct expr_test; | |
261 template <typename T> struct expr_test<T, sizeof(char)> : T {}; | |
262 | |
263 # define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \ | |
264 template <typename U> \ | |
265 static typename boost::unordered::detail::expr_test< \ | |
266 BOOST_PP_CAT(choice, result), \ | |
267 sizeof(for_expr_test(( \ | |
268 (expression), \ | |
269 0)))>::type test( \ | |
270 BOOST_PP_CAT(choice, count)) | |
271 | |
272 # define BOOST_UNORDERED_DEFAULT_EXPRESSION(count, result) \ | |
273 template <typename U> \ | |
274 static BOOST_PP_CAT(choice, result)::type test( \ | |
275 BOOST_PP_CAT(choice, count)) | |
276 | |
277 # define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \ | |
278 struct BOOST_PP_CAT(has_, name) \ | |
279 { \ | |
280 template <typename U> static char for_expr_test(U const&); \ | |
281 BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, \ | |
282 boost::unordered::detail::make< thing >().name args); \ | |
283 BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \ | |
284 \ | |
285 enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };\ | |
286 } | |
287 | |
288 #else | |
289 | |
290 template <typename T> struct identity { typedef T type; }; | |
291 | |
292 # define BOOST_UNORDERED_CHECK_MEMBER(count, result, name, member) \ | |
293 \ | |
294 typedef typename boost::unordered::detail::identity<member>::type \ | |
295 BOOST_PP_CAT(check, count); \ | |
296 \ | |
297 template <BOOST_PP_CAT(check, count) e> \ | |
298 struct BOOST_PP_CAT(test, count) { \ | |
299 typedef BOOST_PP_CAT(choice, result) type; \ | |
300 }; \ | |
301 \ | |
302 template <class U> static typename \ | |
303 BOOST_PP_CAT(test, count)<&U::name>::type \ | |
304 test(BOOST_PP_CAT(choice, count)) | |
305 | |
306 # define BOOST_UNORDERED_DEFAULT_MEMBER(count, result) \ | |
307 template <class U> static BOOST_PP_CAT(choice, result)::type \ | |
308 test(BOOST_PP_CAT(choice, count)) | |
309 | |
310 # define BOOST_UNORDERED_HAS_MEMBER(name) \ | |
311 struct BOOST_PP_CAT(has_, name) \ | |
312 { \ | |
313 struct impl { \ | |
314 struct base_mixin { int name; }; \ | |
315 struct base : public T, public base_mixin {}; \ | |
316 \ | |
317 BOOST_UNORDERED_CHECK_MEMBER(1, 1, name, int base_mixin::*); \ | |
318 BOOST_UNORDERED_DEFAULT_MEMBER(2, 2); \ | |
319 \ | |
320 enum { value = sizeof(choice2::type) == \ | |
321 sizeof(test<base>(choose())) \ | |
322 }; \ | |
323 }; \ | |
324 \ | |
325 enum { value = impl::value }; \ | |
326 } | |
327 | |
328 #endif | |
329 | |
330 }}} | |
331 | |
332 //////////////////////////////////////////////////////////////////////////////// | |
333 // | |
334 // Allocator traits | |
335 // | |
336 // First our implementation, then later light wrappers around the alternatives | |
337 | |
338 #if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 0 | |
339 | |
340 # include <boost/limits.hpp> | |
341 # include <boost/utility/enable_if.hpp> | |
342 # include <boost/pointer_to_other.hpp> | |
343 # if defined(BOOST_NO_SFINAE_EXPR) | |
344 # include <boost/type_traits/is_same.hpp> | |
345 # endif | |
346 | |
347 # if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ | |
348 !defined(BOOST_NO_SFINAE_EXPR) | |
349 # define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 1 | |
350 # else | |
351 # define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 0 | |
352 # endif | |
353 | |
354 namespace boost { namespace unordered { namespace detail { | |
355 | |
356 // TODO: Does this match std::allocator_traits<Alloc>::rebind_alloc<T>? | |
357 template <typename Alloc, typename T> | |
358 struct rebind_wrap | |
359 { | |
360 typedef typename Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other type; | |
361 }; | |
362 | |
363 # if defined(BOOST_MSVC) && BOOST_MSVC <= 1400 | |
364 | |
365 # define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname) \ | |
366 template <typename Tp, typename Default> \ | |
367 struct default_type_ ## tname { \ | |
368 \ | |
369 template <typename X> \ | |
370 static choice1::type test(choice1, typename X::tname* = 0); \ | |
371 \ | |
372 template <typename X> \ | |
373 static choice2::type test(choice2, void* = 0); \ | |
374 \ | |
375 struct DefaultWrap { typedef Default tname; }; \ | |
376 \ | |
377 enum { value = (1 == sizeof(test<Tp>(choose()))) }; \ | |
378 \ | |
379 typedef typename boost::detail::if_true<value>:: \ | |
380 BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap> \ | |
381 ::type::tname type; \ | |
382 } | |
383 | |
384 # else | |
385 | |
386 template <typename T, typename T2> | |
387 struct sfinae : T2 {}; | |
388 | |
389 # define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname) \ | |
390 template <typename Tp, typename Default> \ | |
391 struct default_type_ ## tname { \ | |
392 \ | |
393 template <typename X> \ | |
394 static typename boost::unordered::detail::sfinae< \ | |
395 typename X::tname, choice1>::type \ | |
396 test(choice1); \ | |
397 \ | |
398 template <typename X> \ | |
399 static choice2::type test(choice2); \ | |
400 \ | |
401 struct DefaultWrap { typedef Default tname; }; \ | |
402 \ | |
403 enum { value = (1 == sizeof(test<Tp>(choose()))) }; \ | |
404 \ | |
405 typedef typename boost::detail::if_true<value>:: \ | |
406 BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap> \ | |
407 ::type::tname type; \ | |
408 } | |
409 | |
410 # endif | |
411 | |
412 # define BOOST_UNORDERED_DEFAULT_TYPE(T,tname, arg) \ | |
413 typename default_type_ ## tname<T, arg>::type | |
414 | |
415 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(pointer); | |
416 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(const_pointer); | |
417 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(void_pointer); | |
418 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(const_void_pointer); | |
419 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(difference_type); | |
420 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(size_type); | |
421 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment); | |
422 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment); | |
423 BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_swap); | |
424 | |
425 # if !defined(BOOST_NO_SFINAE_EXPR) | |
426 | |
427 template <typename T> | |
428 BOOST_UNORDERED_HAS_FUNCTION( | |
429 select_on_container_copy_construction, U const, (), 0 | |
430 ); | |
431 | |
432 template <typename T> | |
433 BOOST_UNORDERED_HAS_FUNCTION( | |
434 max_size, U const, (), 0 | |
435 ); | |
436 | |
437 # if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
438 | |
439 template <typename T, typename ValueType, typename... Args> | |
440 BOOST_UNORDERED_HAS_FUNCTION( | |
441 construct, U, ( | |
442 boost::unordered::detail::make<ValueType*>(), | |
443 boost::unordered::detail::make<Args const>()...), 2 | |
444 ); | |
445 | |
446 # else | |
447 | |
448 template <typename T, typename ValueType> | |
449 BOOST_UNORDERED_HAS_FUNCTION( | |
450 construct, U, ( | |
451 boost::unordered::detail::make<ValueType*>(), | |
452 boost::unordered::detail::make<ValueType const>()), 2 | |
453 ); | |
454 | |
455 # endif | |
456 | |
457 template <typename T, typename ValueType> | |
458 BOOST_UNORDERED_HAS_FUNCTION( | |
459 destroy, U, (boost::unordered::detail::make<ValueType*>()), 1 | |
460 ); | |
461 | |
462 # else | |
463 | |
464 template <typename T> | |
465 BOOST_UNORDERED_HAS_MEMBER(select_on_container_copy_construction); | |
466 | |
467 template <typename T> | |
468 BOOST_UNORDERED_HAS_MEMBER(max_size); | |
469 | |
470 template <typename T, typename ValueType> | |
471 BOOST_UNORDERED_HAS_MEMBER(construct); | |
472 | |
473 template <typename T, typename ValueType> | |
474 BOOST_UNORDERED_HAS_MEMBER(destroy); | |
475 | |
476 # endif | |
477 | |
478 namespace func | |
479 { | |
480 | |
481 template <typename Alloc> | |
482 inline Alloc call_select_on_container_copy_construction(const Alloc& rhs, | |
483 typename boost::enable_if_c< | |
484 boost::unordered::detail:: | |
485 has_select_on_container_copy_construction<Alloc>::value, void* | |
486 >::type = 0) | |
487 { | |
488 return rhs.select_on_container_copy_construction(); | |
489 } | |
490 | |
491 template <typename Alloc> | |
492 inline Alloc call_select_on_container_copy_construction(const Alloc& rhs, | |
493 typename boost::disable_if_c< | |
494 boost::unordered::detail:: | |
495 has_select_on_container_copy_construction<Alloc>::value, void* | |
496 >::type = 0) | |
497 { | |
498 return rhs; | |
499 } | |
500 | |
501 template <typename SizeType, typename Alloc> | |
502 inline SizeType call_max_size(const Alloc& a, | |
503 typename boost::enable_if_c< | |
504 boost::unordered::detail::has_max_size<Alloc>::value, void* | |
505 >::type = 0) | |
506 { | |
507 return a.max_size(); | |
508 } | |
509 | |
510 template <typename SizeType, typename Alloc> | |
511 inline SizeType call_max_size(const Alloc&, typename boost::disable_if_c< | |
512 boost::unordered::detail::has_max_size<Alloc>::value, void* | |
513 >::type = 0) | |
514 { | |
515 return (std::numeric_limits<SizeType>::max)(); | |
516 } | |
517 | |
518 } // namespace func. | |
519 | |
520 template <typename Alloc> | |
521 struct allocator_traits | |
522 { | |
523 typedef Alloc allocator_type; | |
524 typedef typename Alloc::value_type value_type; | |
525 | |
526 typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, pointer, value_type*) | |
527 pointer; | |
528 | |
529 template <typename T> | |
530 struct pointer_to_other : boost::pointer_to_other<pointer, T> {}; | |
531 | |
532 typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_pointer, | |
533 typename pointer_to_other<const value_type>::type) | |
534 const_pointer; | |
535 | |
536 //typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, void_pointer, | |
537 // typename pointer_to_other<void>::type) | |
538 // void_pointer; | |
539 // | |
540 //typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_void_pointer, | |
541 // typename pointer_to_other<const void>::type) | |
542 // const_void_pointer; | |
543 | |
544 typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, difference_type, | |
545 std::ptrdiff_t) difference_type; | |
546 | |
547 typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, size_type, std::size_t) | |
548 size_type; | |
549 | |
550 // TODO: rebind_alloc and rebind_traits | |
551 | |
552 static pointer allocate(Alloc& a, size_type n) | |
553 { return a.allocate(n); } | |
554 | |
555 // I never use this, so I'll just comment it out for now. | |
556 // | |
557 //static pointer allocate(Alloc& a, size_type n, | |
558 // const_void_pointer hint) | |
559 // { return DEFAULT_FUNC(allocate, pointer)(a, n, hint); } | |
560 | |
561 static void deallocate(Alloc& a, pointer p, size_type n) | |
562 { a.deallocate(p, n); } | |
563 | |
564 public: | |
565 | |
566 # if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT | |
567 | |
568 template <typename T, typename... Args> | |
569 static typename boost::enable_if_c< | |
570 boost::unordered::detail::has_construct<Alloc, T, Args...> | |
571 ::value>::type | |
572 construct(Alloc& a, T* p, BOOST_FWD_REF(Args)... x) | |
573 { | |
574 a.construct(p, boost::forward<Args>(x)...); | |
575 } | |
576 | |
577 template <typename T, typename... Args> | |
578 static typename boost::disable_if_c< | |
579 boost::unordered::detail::has_construct<Alloc, T, Args...> | |
580 ::value>::type | |
581 construct(Alloc&, T* p, BOOST_FWD_REF(Args)... x) | |
582 { | |
583 new ((void*) p) T(boost::forward<Args>(x)...); | |
584 } | |
585 | |
586 template <typename T> | |
587 static typename boost::enable_if_c< | |
588 boost::unordered::detail::has_destroy<Alloc, T>::value>::type | |
589 destroy(Alloc& a, T* p) | |
590 { | |
591 a.destroy(p); | |
592 } | |
593 | |
594 template <typename T> | |
595 static typename boost::disable_if_c< | |
596 boost::unordered::detail::has_destroy<Alloc, T>::value>::type | |
597 destroy(Alloc&, T* p) | |
598 { | |
599 boost::unordered::detail::func::destroy(p); | |
600 } | |
601 | |
602 # elif !defined(BOOST_NO_SFINAE_EXPR) | |
603 | |
604 template <typename T> | |
605 static typename boost::enable_if_c< | |
606 boost::unordered::detail::has_construct<Alloc, T>::value>::type | |
607 construct(Alloc& a, T* p, T const& x) | |
608 { | |
609 a.construct(p, x); | |
610 } | |
611 | |
612 template <typename T> | |
613 static typename boost::disable_if_c< | |
614 boost::unordered::detail::has_construct<Alloc, T>::value>::type | |
615 construct(Alloc&, T* p, T const& x) | |
616 { | |
617 new ((void*) p) T(x); | |
618 } | |
619 | |
620 template <typename T> | |
621 static typename boost::enable_if_c< | |
622 boost::unordered::detail::has_destroy<Alloc, T>::value>::type | |
623 destroy(Alloc& a, T* p) | |
624 { | |
625 a.destroy(p); | |
626 } | |
627 | |
628 template <typename T> | |
629 static typename boost::disable_if_c< | |
630 boost::unordered::detail::has_destroy<Alloc, T>::value>::type | |
631 destroy(Alloc&, T* p) | |
632 { | |
633 boost::unordered::detail::func::destroy(p); | |
634 } | |
635 | |
636 # else | |
637 | |
638 // If we don't have SFINAE expressions, only call construct for the | |
639 // copy constructor for the allocator's value_type - as that's | |
640 // the only construct method that old fashioned allocators support. | |
641 | |
642 template <typename T> | |
643 static void construct(Alloc& a, T* p, T const& x, | |
644 typename boost::enable_if_c< | |
645 boost::unordered::detail::has_construct<Alloc, T>::value && | |
646 boost::is_same<T, value_type>::value, | |
647 void*>::type = 0) | |
648 { | |
649 a.construct(p, x); | |
650 } | |
651 | |
652 template <typename T> | |
653 static void construct(Alloc&, T* p, T const& x, | |
654 typename boost::disable_if_c< | |
655 boost::unordered::detail::has_construct<Alloc, T>::value && | |
656 boost::is_same<T, value_type>::value, | |
657 void*>::type = 0) | |
658 { | |
659 new ((void*) p) T(x); | |
660 } | |
661 | |
662 template <typename T> | |
663 static void destroy(Alloc& a, T* p, | |
664 typename boost::enable_if_c< | |
665 boost::unordered::detail::has_destroy<Alloc, T>::value && | |
666 boost::is_same<T, value_type>::value, | |
667 void*>::type = 0) | |
668 { | |
669 a.destroy(p); | |
670 } | |
671 | |
672 template <typename T> | |
673 static void destroy(Alloc&, T* p, | |
674 typename boost::disable_if_c< | |
675 boost::unordered::detail::has_destroy<Alloc, T>::value && | |
676 boost::is_same<T, value_type>::value, | |
677 void*>::type = 0) | |
678 { | |
679 boost::unordered::detail::func::destroy(p); | |
680 } | |
681 | |
682 # endif | |
683 | |
684 static size_type max_size(const Alloc& a) | |
685 { | |
686 return boost::unordered::detail::func:: | |
687 call_max_size<size_type>(a); | |
688 } | |
689 | |
690 // Allocator propagation on construction | |
691 | |
692 static Alloc select_on_container_copy_construction(Alloc const& rhs) | |
693 { | |
694 return boost::unordered::detail::func:: | |
695 call_select_on_container_copy_construction(rhs); | |
696 } | |
697 | |
698 // Allocator propagation on assignment and swap. | |
699 // Return true if lhs is modified. | |
700 typedef BOOST_UNORDERED_DEFAULT_TYPE( | |
701 Alloc, propagate_on_container_copy_assignment, false_type) | |
702 propagate_on_container_copy_assignment; | |
703 typedef BOOST_UNORDERED_DEFAULT_TYPE( | |
704 Alloc,propagate_on_container_move_assignment, false_type) | |
705 propagate_on_container_move_assignment; | |
706 typedef BOOST_UNORDERED_DEFAULT_TYPE( | |
707 Alloc,propagate_on_container_swap,false_type) | |
708 propagate_on_container_swap; | |
709 }; | |
710 }}} | |
711 | |
712 # undef BOOST_UNORDERED_DEFAULT_TYPE_TMPLT | |
713 # undef BOOST_UNORDERED_DEFAULT_TYPE | |
714 | |
715 //////////////////////////////////////////////////////////////////////////////// | |
716 // | |
717 // std::allocator_traits | |
718 | |
719 #elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1 | |
720 | |
721 # include <memory> | |
722 | |
723 # define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 1 | |
724 | |
725 namespace boost { namespace unordered { namespace detail { | |
726 | |
727 template <typename Alloc> | |
728 struct allocator_traits : std::allocator_traits<Alloc> {}; | |
729 | |
730 template <typename Alloc, typename T> | |
731 struct rebind_wrap | |
732 { | |
733 typedef typename std::allocator_traits<Alloc>:: | |
734 template rebind_alloc<T> type; | |
735 }; | |
736 }}} | |
737 | |
738 //////////////////////////////////////////////////////////////////////////////// | |
739 // | |
740 // boost::container::allocator_traits | |
741 | |
742 #elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 2 | |
743 | |
744 # include <boost/container/allocator_traits.hpp> | |
745 | |
746 # define BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT 0 | |
747 | |
748 namespace boost { namespace unordered { namespace detail { | |
749 | |
750 template <typename Alloc> | |
751 struct allocator_traits : | |
752 boost::container::allocator_traits<Alloc> {}; | |
753 | |
754 template <typename Alloc, typename T> | |
755 struct rebind_wrap : | |
756 boost::container::allocator_traits<Alloc>:: | |
757 template portable_rebind_alloc<T> | |
758 {}; | |
759 | |
760 }}} | |
761 | |
762 #else | |
763 | |
764 #error "Invalid BOOST_UNORDERED_USE_ALLOCATOR_TRAITS value." | |
765 | |
766 #endif | |
767 | |
768 | |
769 namespace boost { namespace unordered { namespace detail { namespace func { | |
770 | |
771 //////////////////////////////////////////////////////////////////////////// | |
772 // call_construct | |
773 | |
774 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
775 | |
776 # if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT | |
777 | |
778 template <typename Alloc, typename T, typename... Args> | |
779 inline void call_construct(Alloc& alloc, T* address, | |
780 BOOST_FWD_REF(Args)... args) | |
781 { | |
782 boost::unordered::detail::allocator_traits<Alloc>::construct(alloc, | |
783 address, boost::forward<Args>(args)...); | |
784 } | |
785 | |
786 template <typename Alloc, typename T> | |
787 inline void destroy_value_impl(Alloc& alloc, T* x) { | |
788 boost::unordered::detail::allocator_traits<Alloc>::destroy(alloc, x); | |
789 } | |
790 | |
791 | |
792 # else | |
793 | |
794 template <typename Alloc, typename T, typename... Args> | |
795 inline void call_construct(Alloc&, T* address, | |
796 BOOST_FWD_REF(Args)... args) | |
797 { | |
798 new((void*) address) T(boost::forward<Args>(args)...); | |
799 } | |
800 | |
801 template <typename Alloc, typename T> | |
802 inline void destroy_value_impl(Alloc&, T* x) { | |
803 boost::unordered::detail::func::destroy(x); | |
804 } | |
805 | |
806 | |
807 # endif | |
808 | |
809 #else | |
810 | |
811 template <typename Alloc, typename T> | |
812 inline void destroy_value_impl(Alloc&, T* x) { | |
813 boost::unordered::detail::func::destroy(x); | |
814 } | |
815 | |
816 #endif | |
817 | |
818 //////////////////////////////////////////////////////////////////////////// | |
819 // Construct from tuple | |
820 // | |
821 // Used for piecewise construction. | |
822 | |
823 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
824 | |
825 # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ | |
826 template<typename Alloc, typename T> \ | |
827 void construct_from_tuple(Alloc& alloc, T* ptr, namespace_ tuple<>) \ | |
828 { \ | |
829 boost::unordered::detail::func::call_construct(alloc, ptr); \ | |
830 } \ | |
831 \ | |
832 BOOST_PP_REPEAT_FROM_TO(1, n, \ | |
833 BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_) | |
834 | |
835 # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \ | |
836 template<typename Alloc, typename T, \ | |
837 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \ | |
838 void construct_from_tuple(Alloc& alloc, T* ptr, \ | |
839 namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \ | |
840 { \ | |
841 boost::unordered::detail::func::call_construct(alloc, ptr, \ | |
842 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ | |
843 ); \ | |
844 } | |
845 | |
846 # define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ | |
847 namespace_ get<n>(x) | |
848 | |
849 #elif !defined(__SUNPRO_CC) | |
850 | |
851 # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ | |
852 template<typename Alloc, typename T> \ | |
853 void construct_from_tuple(Alloc&, T* ptr, namespace_ tuple<>) \ | |
854 { \ | |
855 new ((void*) ptr) T(); \ | |
856 } \ | |
857 \ | |
858 BOOST_PP_REPEAT_FROM_TO(1, n, \ | |
859 BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_) | |
860 | |
861 # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \ | |
862 template<typename Alloc, typename T, \ | |
863 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \ | |
864 void construct_from_tuple(Alloc&, T* ptr, \ | |
865 namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \ | |
866 { \ | |
867 new ((void*) ptr) T( \ | |
868 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ | |
869 ); \ | |
870 } | |
871 | |
872 # define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ | |
873 namespace_ get<n>(x) | |
874 | |
875 #else | |
876 | |
877 template <int N> struct length {}; | |
878 | |
879 # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ | |
880 template<typename Alloc, typename T> \ | |
881 void construct_from_tuple_impl( \ | |
882 boost::unordered::detail::length<0>, Alloc&, T* ptr, \ | |
883 namespace_ tuple<>) \ | |
884 { \ | |
885 new ((void*) ptr) T(); \ | |
886 } \ | |
887 \ | |
888 BOOST_PP_REPEAT_FROM_TO(1, n, \ | |
889 BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_) | |
890 | |
891 # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \ | |
892 template<typename Alloc, typename T, \ | |
893 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \ | |
894 void construct_from_tuple_impl( \ | |
895 boost::unordered::detail::length<n>, Alloc&, T* ptr, \ | |
896 namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \ | |
897 { \ | |
898 new ((void*) ptr) T( \ | |
899 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ | |
900 ); \ | |
901 } | |
902 | |
903 # define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ | |
904 namespace_ get<n>(x) | |
905 | |
906 #endif | |
907 | |
908 BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) | |
909 | |
910 #if !defined(__SUNPRO_CC) && !defined(BOOST_NO_CXX11_HDR_TUPLE) | |
911 BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std::) | |
912 #endif | |
913 | |
914 #undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE | |
915 #undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL | |
916 #undef BOOST_UNORDERED_GET_TUPLE_ARG | |
917 | |
918 #if defined(__SUNPRO_CC) | |
919 | |
920 template <typename Alloc, typename T, typename Tuple> | |
921 void construct_from_tuple(Alloc& alloc, T* ptr, Tuple const& x) | |
922 { | |
923 construct_from_tuple_impl( | |
924 boost::unordered::detail::length< | |
925 boost::tuples::length<Tuple>::value>(), | |
926 alloc, ptr, x); | |
927 } | |
928 | |
929 #endif | |
930 | |
931 //////////////////////////////////////////////////////////////////////////// | |
932 // Trait to check for piecewise construction. | |
933 | |
934 template <typename A0> | |
935 struct use_piecewise { | |
936 static choice1::type test(choice1, | |
937 boost::unordered::piecewise_construct_t); | |
938 | |
939 static choice2::type test(choice2, ...); | |
940 | |
941 enum { value = sizeof(choice1::type) == | |
942 sizeof(test(choose(), boost::unordered::detail::make<A0>())) }; | |
943 }; | |
944 | |
945 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
946 | |
947 //////////////////////////////////////////////////////////////////////////// | |
948 // Construct from variadic parameters | |
949 | |
950 // For the standard pair constructor. | |
951 | |
952 template <typename Alloc, typename T, typename... Args> | |
953 inline void construct_value_impl(Alloc& alloc, T* address, | |
954 BOOST_FWD_REF(Args)... args) | |
955 { | |
956 boost::unordered::detail::func::call_construct(alloc, | |
957 address, boost::forward<Args>(args)...); | |
958 } | |
959 | |
960 // Special case for piece_construct | |
961 // | |
962 // TODO: When possible, it might be better to use std::pair's | |
963 // constructor for std::piece_construct with std::tuple. | |
964 | |
965 template <typename Alloc, typename A, typename B, | |
966 typename A0, typename A1, typename A2> | |
967 inline typename enable_if<use_piecewise<A0>, void>::type | |
968 construct_value_impl(Alloc& alloc, std::pair<A, B>* address, | |
969 BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) | |
970 { | |
971 boost::unordered::detail::func::construct_from_tuple(alloc, | |
972 boost::addressof(address->first), boost::forward<A1>(a1)); | |
973 boost::unordered::detail::func::construct_from_tuple(alloc, | |
974 boost::addressof(address->second), boost::forward<A2>(a2)); | |
975 } | |
976 | |
977 #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES | |
978 | |
979 //////////////////////////////////////////////////////////////////////////////// | |
980 // Construct from emplace_args | |
981 | |
982 // Explicitly write out first three overloads for the sake of sane | |
983 // error messages. | |
984 | |
985 template <typename Alloc, typename T, typename A0> | |
986 inline void construct_value_impl(Alloc&, T* address, | |
987 emplace_args1<A0> const& args) | |
988 { | |
989 new((void*) address) T(boost::forward<A0>(args.a0)); | |
990 } | |
991 | |
992 template <typename Alloc, typename T, typename A0, typename A1> | |
993 inline void construct_value_impl(Alloc&, T* address, | |
994 emplace_args2<A0, A1> const& args) | |
995 { | |
996 new((void*) address) T( | |
997 boost::forward<A0>(args.a0), | |
998 boost::forward<A1>(args.a1) | |
999 ); | |
1000 } | |
1001 | |
1002 template <typename Alloc, typename T, typename A0, typename A1, typename A2> | |
1003 inline void construct_value_impl(Alloc&, T* address, | |
1004 emplace_args3<A0, A1, A2> const& args) | |
1005 { | |
1006 new((void*) address) T( | |
1007 boost::forward<A0>(args.a0), | |
1008 boost::forward<A1>(args.a1), | |
1009 boost::forward<A2>(args.a2) | |
1010 ); | |
1011 } | |
1012 | |
1013 // Use a macro for the rest. | |
1014 | |
1015 #define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \ | |
1016 template < \ | |
1017 typename Alloc, typename T, \ | |
1018 BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A) \ | |
1019 > \ | |
1020 inline void construct_value_impl(Alloc&, T* address, \ | |
1021 boost::unordered::detail::BOOST_PP_CAT(emplace_args,num_params) < \ | |
1022 BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ | |
1023 > const& args) \ | |
1024 { \ | |
1025 new((void*) address) T( \ | |
1026 BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_FORWARD, \ | |
1027 args.a)); \ | |
1028 } | |
1029 | |
1030 BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, | |
1031 BOOST_UNORDERED_CONSTRUCT_IMPL, _) | |
1032 | |
1033 #undef BOOST_UNORDERED_CONSTRUCT_IMPL | |
1034 | |
1035 // Construct with piece_construct | |
1036 | |
1037 template <typename Alloc, typename A, typename B, | |
1038 typename A0, typename A1, typename A2> | |
1039 inline void construct_value_impl(Alloc& alloc, std::pair<A, B>* address, | |
1040 boost::unordered::detail::emplace_args3<A0, A1, A2> const& args, | |
1041 typename enable_if<use_piecewise<A0>, void*>::type = 0) | |
1042 { | |
1043 boost::unordered::detail::func::construct_from_tuple(alloc, | |
1044 boost::addressof(address->first), args.a1); | |
1045 boost::unordered::detail::func::construct_from_tuple(alloc, | |
1046 boost::addressof(address->second), args.a2); | |
1047 } | |
1048 | |
1049 #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES | |
1050 | |
1051 }}}} | |
1052 | |
1053 namespace boost { namespace unordered { namespace detail { | |
1054 | |
1055 //////////////////////////////////////////////////////////////////////////// | |
1056 // | |
1057 // array_constructor | |
1058 // | |
1059 // Allocate and construct an array in an exception safe manner, and | |
1060 // clean up if an exception is thrown before the container takes charge | |
1061 // of it. | |
1062 | |
1063 template <typename Allocator> | |
1064 struct array_constructor | |
1065 { | |
1066 typedef boost::unordered::detail::allocator_traits<Allocator> traits; | |
1067 typedef typename traits::pointer pointer; | |
1068 | |
1069 Allocator& alloc_; | |
1070 pointer ptr_; | |
1071 pointer constructed_; | |
1072 std::size_t length_; | |
1073 | |
1074 array_constructor(Allocator& a) | |
1075 : alloc_(a), ptr_(), constructed_(), length_(0) | |
1076 { | |
1077 constructed_ = pointer(); | |
1078 ptr_ = pointer(); | |
1079 } | |
1080 | |
1081 ~array_constructor() { | |
1082 if (ptr_) { | |
1083 for(pointer p = ptr_; p != constructed_; ++p) | |
1084 traits::destroy(alloc_, boost::addressof(*p)); | |
1085 | |
1086 traits::deallocate(alloc_, ptr_, length_); | |
1087 } | |
1088 } | |
1089 | |
1090 template <typename V> | |
1091 void construct(V const& v, std::size_t l) | |
1092 { | |
1093 BOOST_ASSERT(!ptr_); | |
1094 length_ = l; | |
1095 ptr_ = traits::allocate(alloc_, length_); | |
1096 pointer end = ptr_ + static_cast<std::ptrdiff_t>(length_); | |
1097 for(constructed_ = ptr_; constructed_ != end; ++constructed_) | |
1098 traits::construct(alloc_, boost::addressof(*constructed_), v); | |
1099 } | |
1100 | |
1101 pointer get() const | |
1102 { | |
1103 return ptr_; | |
1104 } | |
1105 | |
1106 pointer release() | |
1107 { | |
1108 pointer p(ptr_); | |
1109 ptr_ = pointer(); | |
1110 return p; | |
1111 } | |
1112 | |
1113 private: | |
1114 | |
1115 array_constructor(array_constructor const&); | |
1116 array_constructor& operator=(array_constructor const&); | |
1117 }; | |
1118 }}} | |
1119 | |
1120 #if defined(BOOST_MSVC) | |
1121 #pragma warning(pop) | |
1122 #endif | |
1123 | |
1124 #endif |