Browse code

Add more headers for unordered

Steffen Neumann authored on 18/01/2022 10:29:09
Showing8 changed files

1 1
new file mode 100755
... ...
@@ -0,0 +1,63 @@
1
+
2
+// Copyright (C) 2008-2016 Daniel James.
3
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
4
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+#ifndef BOOST_UNORDERED_FWD_HPP_INCLUDED
7
+#define BOOST_UNORDERED_FWD_HPP_INCLUDED
8
+
9
+#include <boost/config.hpp>
10
+#if defined(BOOST_HAS_PRAGMA_ONCE)
11
+#pragma once
12
+#endif
13
+
14
+#include <boost/predef.h>
15
+
16
+#if defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
17
+// Already defined.
18
+#elif defined(BOOST_LIBSTDCXX11)
19
+// https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70
20
+#if BOOST_LIBSTDCXX_VERSION > 40600
21
+#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
22
+#endif
23
+#elif BOOST_LIB_STD_CXX
24
+// https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206
25
+#if BOOST_LIB_STD_CXX >= BOOST_VERSION_NUMBER(3, 0, 0)
26
+#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
27
+#endif
28
+#elif defined(BOOST_LIB_STD_DINKUMWARE)
29
+// Apparently C++11 standard supported in Visual Studio 2012
30
+// https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl
31
+// 2012 = VC+11 = BOOST_MSVC 1700 Hopefully!
32
+// I have no idea when Dinkumware added it, probably a lot
33
+// earlier than this check.
34
+#if BOOST_LIB_STD_DINKUMWARE >= BOOST_VERSION_NUMBER(6, 50, 0) ||              \
35
+  BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(17, 0, 0)
36
+#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
37
+#endif
38
+#endif
39
+
40
+// Assume that an unknown library does not support piecewise construction.
41
+#if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
42
+#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 0
43
+#endif
44
+
45
+#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
46
+#include <utility>
47
+#endif
48
+
49
+namespace boost {
50
+  namespace unordered {
51
+#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
52
+    using std::piecewise_construct_t;
53
+    using std::piecewise_construct;
54
+#else
55
+    struct piecewise_construct_t
56
+    {
57
+    };
58
+    const piecewise_construct_t piecewise_construct = piecewise_construct_t();
59
+#endif
60
+  }
61
+}
62
+
63
+#endif
0 64
new file mode 100755
... ...
@@ -0,0 +1,4952 @@
1
+// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
2
+// Copyright (C) 2005-2016 Daniel James
3
+//
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
+#ifndef BOOST_UNORDERED_DETAIL_IMPLEMENTATION_HPP
8
+#define BOOST_UNORDERED_DETAIL_IMPLEMENTATION_HPP
9
+
10
+#include <boost/config.hpp>
11
+#if defined(BOOST_HAS_PRAGMA_ONCE)
12
+#pragma once
13
+#endif
14
+
15
+#include <boost/assert.hpp>
16
+#include <boost/core/no_exceptions_support.hpp>
17
+#include <boost/core/pointer_traits.hpp>
18
+#include <boost/detail/select_type.hpp>
19
+#include <boost/limits.hpp>
20
+#include <boost/move/move.hpp>
21
+#include <boost/preprocessor/arithmetic/inc.hpp>
22
+#include <boost/preprocessor/cat.hpp>
23
+#include <boost/preprocessor/repetition/enum.hpp>
24
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
25
+#include <boost/preprocessor/repetition/enum_params.hpp>
26
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
27
+#include <boost/preprocessor/seq/enum.hpp>
28
+#include <boost/preprocessor/seq/size.hpp>
29
+#include <boost/swap.hpp>
30
+#include <boost/throw_exception.hpp>
31
+#include <boost/tuple/tuple.hpp>
32
+#include <boost/type_traits/add_lvalue_reference.hpp>
33
+#include <boost/type_traits/aligned_storage.hpp>
34
+#include <boost/type_traits/alignment_of.hpp>
35
+#include <boost/type_traits/integral_constant.hpp>
36
+#include <boost/type_traits/is_base_of.hpp>
37
+#include <boost/type_traits/is_class.hpp>
38
+#include <boost/type_traits/is_empty.hpp>
39
+#include <boost/type_traits/is_nothrow_move_assignable.hpp>
40
+#include <boost/type_traits/is_nothrow_move_constructible.hpp>
41
+#include <boost/type_traits/is_nothrow_swappable.hpp>
42
+#include <boost/type_traits/is_same.hpp>
43
+#include <boost/type_traits/remove_const.hpp>
44
+#include <boost/unordered/detail/fwd.hpp>
45
+#include <boost/utility/addressof.hpp>
46
+#include <boost/utility/enable_if.hpp>
47
+#include <cmath>
48
+#include <iterator>
49
+#include <stdexcept>
50
+#include <utility>
51
+
52
+#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
53
+#include <type_traits>
54
+#endif
55
+
56
+////////////////////////////////////////////////////////////////////////////////
57
+// Configuration
58
+//
59
+// Unless documented elsewhere these configuration macros should be considered
60
+// an implementation detail, I'll try not to break them, but you never know.
61
+
62
+// Use Sun C++ workarounds
63
+// I'm not sure which versions of the compiler require these workarounds, so
64
+// I'm just using them of everything older than the current test compilers
65
+// (as of May 2017).
66
+
67
+#if !defined(BOOST_UNORDERED_SUN_WORKAROUNDS1)
68
+#if BOOST_COMP_SUNPRO && BOOST_COMP_SUNPRO < BOOST_VERSION_NUMBER(5, 20, 0)
69
+#define BOOST_UNORDERED_SUN_WORKAROUNDS1 1
70
+#else
71
+#define BOOST_UNORDERED_SUN_WORKAROUNDS1 0
72
+#endif
73
+#endif
74
+
75
+// BOOST_UNORDERED_EMPLACE_LIMIT = The maximum number of parameters in
76
+// emplace (not including things like hints). Don't set it to a lower value, as
77
+// that might break something.
78
+
79
+#if !defined BOOST_UNORDERED_EMPLACE_LIMIT
80
+#define BOOST_UNORDERED_EMPLACE_LIMIT 10
81
+#endif
82
+
83
+// BOOST_UNORDERED_USE_ALLOCATOR_TRAITS - Pick which version of
84
+// allocator_traits to use.
85
+//
86
+// 0 = Own partial implementation
87
+// 1 = std::allocator_traits
88
+// 2 = boost::container::allocator_traits
89
+
90
+#if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS)
91
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
92
+#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 1
93
+#elif defined(BOOST_MSVC)
94
+#if BOOST_MSVC < 1400
95
+// Use container's allocator_traits for older versions of Visual
96
+// C++ as I don't test with them.
97
+#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 2
98
+#endif
99
+#endif
100
+#endif
101
+
102
+#if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS)
103
+#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0
104
+#endif
105
+
106
+// BOOST_UNORDERED_TUPLE_ARGS
107
+//
108
+// Maximum number of std::tuple members to support, or 0 if std::tuple
109
+// isn't avaiable. More are supported when full C++11 is used.
110
+
111
+// Already defined, so do nothing
112
+#if defined(BOOST_UNORDERED_TUPLE_ARGS)
113
+
114
+// Assume if we have C++11 tuple it's properly variadic,
115
+// and just use a max number of 10 arguments.
116
+#elif !defined(BOOST_NO_CXX11_HDR_TUPLE)
117
+#define BOOST_UNORDERED_TUPLE_ARGS 10
118
+
119
+// Visual C++ has a decent enough tuple for piecewise construction,
120
+// so use that if available, using _VARIADIC_MAX for the maximum
121
+// number of parameters. Note that this comes after the check
122
+// for a full C++11 tuple.
123
+#elif defined(BOOST_MSVC)
124
+#if !BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
125
+#define BOOST_UNORDERED_TUPLE_ARGS 0
126
+#elif defined(_VARIADIC_MAX)
127
+#define BOOST_UNORDERED_TUPLE_ARGS _VARIADIC_MAX
128
+#else
129
+#define BOOST_UNORDERED_TUPLE_ARGS 5
130
+#endif
131
+
132
+// Assume that we don't have std::tuple
133
+#else
134
+#define BOOST_UNORDERED_TUPLE_ARGS 0
135
+#endif
136
+
137
+#if BOOST_UNORDERED_TUPLE_ARGS
138
+#include <tuple>
139
+#endif
140
+
141
+// BOOST_UNORDERED_CXX11_CONSTRUCTION
142
+//
143
+// Use C++11 construction, requires variadic arguments, good construct support
144
+// in allocator_traits and piecewise construction of std::pair
145
+// Otherwise allocators aren't used for construction/destruction
146
+
147
+#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT &&                                \
148
+  !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && BOOST_UNORDERED_TUPLE_ARGS
149
+#if BOOST_COMP_SUNPRO && BOOST_LIB_STD_GNU
150
+// Sun C++ std::pair piecewise construction doesn't seem to be exception safe.
151
+// (At least for Sun C++ 12.5 using libstdc++).
152
+#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0
153
+#elif BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 7, 0)
154
+// Piecewise construction in GCC 4.6 doesn't work for uncopyable types.
155
+#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0
156
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 0 &&                             \
157
+  !defined(BOOST_NO_SFINAE_EXPR)
158
+#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1
159
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
160
+#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1
161
+#endif
162
+#endif
163
+
164
+#if !defined(BOOST_UNORDERED_CXX11_CONSTRUCTION)
165
+#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0
166
+#endif
167
+
168
+// BOOST_UNORDERED_SUPPRESS_DEPRECATED
169
+//
170
+// Define to stop deprecation attributes
171
+
172
+#if defined(BOOST_UNORDERED_SUPPRESS_DEPRECATED)
173
+#define BOOST_UNORDERED_DEPRECATED(msg)
174
+#endif
175
+
176
+// BOOST_UNORDERED_DEPRECATED
177
+//
178
+// Wrapper around various depreaction attributes.
179
+
180
+#if defined(__has_cpp_attribute) &&                                            \
181
+  (!defined(__cplusplus) || __cplusplus >= 201402)
182
+#if __has_cpp_attribute(deprecated) && !defined(BOOST_UNORDERED_DEPRECATED)
183
+#define BOOST_UNORDERED_DEPRECATED(msg) [[deprecated(msg)]]
184
+#endif
185
+#endif
186
+
187
+#if !defined(BOOST_UNORDERED_DEPRECATED)
188
+#if defined(__GNUC__) && __GNUC__ >= 4
189
+#define BOOST_UNORDERED_DEPRECATED(msg) __attribute__((deprecated))
190
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
191
+#define BOOST_UNORDERED_DEPRECATED(msg) __declspec(deprecated(msg))
192
+#elif defined(_MSC_VER) && _MSC_VER >= 1310
193
+#define BOOST_UNORDERED_DEPRECATED(msg) __declspec(deprecated)
194
+#else
195
+#define BOOST_UNORDERED_DEPRECATED(msg)
196
+#endif
197
+#endif
198
+
199
+// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
200
+
201
+#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
202
+#if BOOST_COMP_CLANG && __cplusplus >= 201703
203
+#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 1
204
+#endif
205
+#endif
206
+
207
+#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
208
+#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 0
209
+#endif
210
+
211
+namespace boost {
212
+  namespace unordered {
213
+    namespace iterator_detail {
214
+      template <typename Node> struct iterator;
215
+      template <typename Node> struct c_iterator;
216
+      template <typename Node> struct l_iterator;
217
+      template <typename Node> struct cl_iterator;
218
+    }
219
+  }
220
+}
221
+
222
+namespace boost {
223
+  namespace unordered {
224
+    namespace detail {
225
+
226
+      template <typename Types> struct table;
227
+      template <typename NodePointer> struct bucket;
228
+      struct ptr_bucket;
229
+
230
+      template <typename A, typename T> struct node;
231
+      template <typename T> struct ptr_node;
232
+
233
+      static const float minimum_max_load_factor = 1e-3f;
234
+      static const std::size_t default_bucket_count = 11;
235
+
236
+      struct move_tag
237
+      {
238
+      };
239
+
240
+      struct empty_emplace
241
+      {
242
+      };
243
+
244
+      struct no_key
245
+      {
246
+        no_key() {}
247
+        template <class T> no_key(T const&) {}
248
+      };
249
+
250
+      namespace func {
251
+        template <class T> inline void ignore_unused_variable_warning(T const&)
252
+        {
253
+        }
254
+      }
255
+
256
+      //////////////////////////////////////////////////////////////////////////
257
+      // iterator SFINAE
258
+
259
+      template <typename I>
260
+      struct is_forward : boost::is_base_of<std::forward_iterator_tag,
261
+                            typename std::iterator_traits<I>::iterator_category>
262
+      {
263
+      };
264
+
265
+      template <typename I, typename ReturnType>
266
+      struct enable_if_forward
267
+        : boost::enable_if_c<boost::unordered::detail::is_forward<I>::value,
268
+            ReturnType>
269
+      {
270
+      };
271
+
272
+      template <typename I, typename ReturnType>
273
+      struct disable_if_forward
274
+        : boost::disable_if_c<boost::unordered::detail::is_forward<I>::value,
275
+            ReturnType>
276
+      {
277
+      };
278
+    }
279
+  }
280
+}
281
+
282
+////////////////////////////////////////////////////////////////////////////////
283
+// primes
284
+
285
+// clang-format off
286
+#define BOOST_UNORDERED_PRIMES \
287
+    (17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \
288
+    (97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \
289
+    (1031ul)(1543ul)(2053ul)(3079ul)(6151ul)(12289ul)(24593ul) \
290
+    (49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
291
+    (1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
292
+    (50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
293
+    (1610612741ul)(3221225473ul)(4294967291ul)
294
+// clang-format on
295
+
296
+namespace boost {
297
+  namespace unordered {
298
+    namespace detail {
299
+      template <class T> struct prime_list_template
300
+      {
301
+        static std::size_t const value[];
302
+
303
+#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
304
+        static std::ptrdiff_t const length;
305
+#else
306
+        static std::ptrdiff_t const length =
307
+          BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
308
+#endif
309
+      };
310
+
311
+      template <class T>
312
+      std::size_t const prime_list_template<T>::value[] = {
313
+        BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)};
314
+
315
+#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
316
+      template <class T>
317
+      std::ptrdiff_t const prime_list_template<T>::length = BOOST_PP_SEQ_SIZE(
318
+        BOOST_UNORDERED_PRIMES);
319
+#endif
320
+
321
+#undef BOOST_UNORDERED_PRIMES
322
+
323
+      typedef prime_list_template<std::size_t> prime_list;
324
+
325
+      // no throw
326
+      inline std::size_t next_prime(std::size_t num)
327
+      {
328
+        std::size_t const* const prime_list_begin = prime_list::value;
329
+        std::size_t const* const prime_list_end =
330
+          prime_list_begin + prime_list::length;
331
+        std::size_t const* bound =
332
+          std::lower_bound(prime_list_begin, prime_list_end, num);
333
+        if (bound == prime_list_end)
334
+          bound--;
335
+        return *bound;
336
+      }
337
+
338
+      // no throw
339
+      inline std::size_t prev_prime(std::size_t num)
340
+      {
341
+        std::size_t const* const prime_list_begin = prime_list::value;
342
+        std::size_t const* const prime_list_end =
343
+          prime_list_begin + prime_list::length;
344
+        std::size_t const* bound =
345
+          std::upper_bound(prime_list_begin, prime_list_end, num);
346
+        if (bound != prime_list_begin)
347
+          bound--;
348
+        return *bound;
349
+      }
350
+
351
+      //////////////////////////////////////////////////////////////////////////
352
+      // insert_size/initial_size
353
+
354
+      template <class I>
355
+      inline std::size_t insert_size(I i, I j,
356
+        typename boost::unordered::detail::enable_if_forward<I, void*>::type =
357
+          0)
358
+      {
359
+        return static_cast<std::size_t>(std::distance(i, j));
360
+      }
361
+
362
+      template <class I>
363
+      inline std::size_t insert_size(I, I,
364
+        typename boost::unordered::detail::disable_if_forward<I, void*>::type =
365
+          0)
366
+      {
367
+        return 1;
368
+      }
369
+
370
+      template <class I>
371
+      inline std::size_t initial_size(I i, I j,
372
+        std::size_t num_buckets =
373
+          boost::unordered::detail::default_bucket_count)
374
+      {
375
+        return (std::max)(
376
+          boost::unordered::detail::insert_size(i, j), num_buckets);
377
+      }
378
+
379
+      //////////////////////////////////////////////////////////////////////////
380
+      // compressed
381
+
382
+      template <typename T, int Index> struct compressed_base : private T
383
+      {
384
+        compressed_base(T const& x) : T(x) {}
385
+        compressed_base(T& x, move_tag) : T(boost::move(x)) {}
386
+
387
+        T& get() { return *this; }
388
+        T const& get() const { return *this; }
389
+      };
390
+
391
+      template <typename T, int Index> struct uncompressed_base
392
+      {
393
+        uncompressed_base(T const& x) : value_(x) {}
394
+        uncompressed_base(T& x, move_tag) : value_(boost::move(x)) {}
395
+
396
+        T& get() { return value_; }
397
+        T const& get() const { return value_; }
398
+
399
+      private:
400
+        T value_;
401
+      };
402
+
403
+      template <typename T, int Index>
404
+      struct generate_base
405
+        : boost::detail::if_true<
406
+            boost::is_empty<T>::value>::BOOST_NESTED_TEMPLATE
407
+            then<boost::unordered::detail::compressed_base<T, Index>,
408
+              boost::unordered::detail::uncompressed_base<T, Index> >
409
+      {
410
+      };
411
+
412
+      template <typename T1, typename T2>
413
+      struct compressed
414
+        : private boost::unordered::detail::generate_base<T1, 1>::type,
415
+          private boost::unordered::detail::generate_base<T2, 2>::type
416
+      {
417
+        typedef typename generate_base<T1, 1>::type base1;
418
+        typedef typename generate_base<T2, 2>::type base2;
419
+
420
+        typedef T1 first_type;
421
+        typedef T2 second_type;
422
+
423
+        first_type& first() { return static_cast<base1*>(this)->get(); }
424
+
425
+        first_type const& first() const
426
+        {
427
+          return static_cast<base1 const*>(this)->get();
428
+        }
429
+
430
+        second_type& second() { return static_cast<base2*>(this)->get(); }
431
+
432
+        second_type const& second() const
433
+        {
434
+          return static_cast<base2 const*>(this)->get();
435
+        }
436
+
437
+        template <typename First, typename Second>
438
+        compressed(First const& x1, Second const& x2) : base1(x1), base2(x2)
439
+        {
440
+        }
441
+
442
+        compressed(compressed const& x) : base1(x.first()), base2(x.second()) {}
443
+
444
+        compressed(compressed& x, move_tag m)
445
+            : base1(x.first(), m), base2(x.second(), m)
446
+        {
447
+        }
448
+
449
+        void assign(compressed const& x)
450
+        {
451
+          first() = x.first();
452
+          second() = x.second();
453
+        }
454
+
455
+        void move_assign(compressed& x)
456
+        {
457
+          first() = boost::move(x.first());
458
+          second() = boost::move(x.second());
459
+        }
460
+
461
+        void swap(compressed& x)
462
+        {
463
+          boost::swap(first(), x.first());
464
+          boost::swap(second(), x.second());
465
+        }
466
+
467
+      private:
468
+        // Prevent assignment just to make use of assign or
469
+        // move_assign explicit.
470
+        compressed& operator=(compressed const&);
471
+      };
472
+
473
+      //////////////////////////////////////////////////////////////////////////
474
+      // pair_traits
475
+      //
476
+      // Used to get the types from a pair without instantiating it.
477
+
478
+      template <typename Pair> struct pair_traits
479
+      {
480
+        typedef typename Pair::first_type first_type;
481
+        typedef typename Pair::second_type second_type;
482
+      };
483
+
484
+      template <typename T1, typename T2> struct pair_traits<std::pair<T1, T2> >
485
+      {
486
+        typedef T1 first_type;
487
+        typedef T2 second_type;
488
+      };
489
+
490
+#if defined(BOOST_MSVC)
491
+#pragma warning(push)
492
+#pragma warning(disable : 4512) // assignment operator could not be generated.
493
+#pragma warning(disable : 4345) // behavior change: an object of POD type
494
+// constructed with an initializer of the form ()
495
+// will be default-initialized.
496
+#endif
497
+
498
+      //////////////////////////////////////////////////////////////////////////
499
+      // Bits and pieces for implementing traits
500
+
501
+      template <typename T>
502
+      typename boost::add_lvalue_reference<T>::type make();
503
+      struct choice9
504
+      {
505
+        typedef char (&type)[9];
506
+      };
507
+      struct choice8 : choice9
508
+      {
509
+        typedef char (&type)[8];
510
+      };
511
+      struct choice7 : choice8
512
+      {
513
+        typedef char (&type)[7];
514
+      };
515
+      struct choice6 : choice7
516
+      {
517
+        typedef char (&type)[6];
518
+      };
519
+      struct choice5 : choice6
520
+      {
521
+        typedef char (&type)[5];
522
+      };
523
+      struct choice4 : choice5
524
+      {
525
+        typedef char (&type)[4];
526
+      };
527
+      struct choice3 : choice4
528
+      {
529
+        typedef char (&type)[3];
530
+      };
531
+      struct choice2 : choice3
532
+      {
533
+        typedef char (&type)[2];
534
+      };
535
+      struct choice1 : choice2
536
+      {
537
+        typedef char (&type)[1];
538
+      };
539
+      choice1 choose();
540
+
541
+      typedef choice1::type yes_type;
542
+      typedef choice2::type no_type;
543
+
544
+      struct private_type
545
+      {
546
+        private_type const& operator,(int) const;
547
+      };
548
+
549
+      template <typename T> no_type is_private_type(T const&);
550
+      yes_type is_private_type(private_type const&);
551
+
552
+      struct convert_from_anything
553
+      {
554
+        template <typename T> convert_from_anything(T const&);
555
+      };
556
+    }
557
+  }
558
+}
559
+
560
+////////////////////////////////////////////////////////////////////////////
561
+// emplace_args
562
+//
563
+// Either forwarding variadic arguments, or storing the arguments in
564
+// emplace_args##n
565
+
566
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
567
+
568
+#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename... Args
569
+#define BOOST_UNORDERED_EMPLACE_ARGS BOOST_FWD_REF(Args)... args
570
+#define BOOST_UNORDERED_EMPLACE_FORWARD boost::forward<Args>(args)...
571
+
572
+#else
573
+
574
+#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename Args
575
+#define BOOST_UNORDERED_EMPLACE_ARGS Args const& args
576
+#define BOOST_UNORDERED_EMPLACE_FORWARD args
577
+
578
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
579
+
580
+#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _)                                  \
581
+  typedef BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(Arg, n);              \
582
+  BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n);
583
+
584
+#else
585
+
586
+#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _)                                  \
587
+  typedef typename boost::add_lvalue_reference<BOOST_PP_CAT(A, n)>::type       \
588
+    BOOST_PP_CAT(Arg, n);                                                      \
589
+  BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n);
590
+
591
+#endif
592
+
593
+#define BOOST_UNORDERED_FWD_PARAM(z, n, a)                                     \
594
+  BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(a, n)
595
+
596
+#define BOOST_UNORDERED_CALL_FORWARD(z, i, a)                                  \
597
+  boost::forward<BOOST_PP_CAT(A, i)>(BOOST_PP_CAT(a, i))
598
+
599
+#define BOOST_UNORDERED_EARGS_INIT(z, n, _)                                    \
600
+  BOOST_PP_CAT(a, n)(BOOST_PP_CAT(b, n))
601
+
602
+#define BOOST_UNORDERED_EARGS(z, n, _)                                         \
603
+  template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
604
+  struct BOOST_PP_CAT(emplace_args, n)                                         \
605
+  {                                                                            \
606
+    BOOST_PP_REPEAT_##z(n, BOOST_UNORDERED_EARGS_MEMBER, _) BOOST_PP_CAT(      \
607
+      emplace_args, n)(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, b))            \
608
+        : BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_EARGS_INIT, _)                  \
609
+    {                                                                          \
610
+    }                                                                          \
611
+  };                                                                           \
612
+                                                                               \
613
+  template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                          \
614
+  inline BOOST_PP_CAT(emplace_args, n)<BOOST_PP_ENUM_PARAMS_Z(z, n, A)>        \
615
+    create_emplace_args(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, b))    \
616
+  {                                                                            \
617
+    BOOST_PP_CAT(emplace_args, n)<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> e(          \
618
+      BOOST_PP_ENUM_PARAMS_Z(z, n, b));                                        \
619
+    return e;                                                                  \
620
+  }
621
+
622
+namespace boost {
623
+  namespace unordered {
624
+    namespace detail {
625
+      template <typename A0> struct emplace_args1
626
+      {
627
+        BOOST_UNORDERED_EARGS_MEMBER(1, 0, _)
628
+
629
+        explicit emplace_args1(Arg0 b0) : a0(b0) {}
630
+      };
631
+
632
+      template <typename A0>
633
+      inline emplace_args1<A0> create_emplace_args(BOOST_FWD_REF(A0) b0)
634
+      {
635
+        emplace_args1<A0> e(b0);
636
+        return e;
637
+      }
638
+
639
+      template <typename A0, typename A1> struct emplace_args2
640
+      {
641
+        BOOST_UNORDERED_EARGS_MEMBER(1, 0, _)
642
+        BOOST_UNORDERED_EARGS_MEMBER(1, 1, _)
643
+
644
+        emplace_args2(Arg0 b0, Arg1 b1) : a0(b0), a1(b1) {}
645
+      };
646
+
647
+      template <typename A0, typename A1>
648
+      inline emplace_args2<A0, A1> create_emplace_args(
649
+        BOOST_FWD_REF(A0) b0, BOOST_FWD_REF(A1) b1)
650
+      {
651
+        emplace_args2<A0, A1> e(b0, b1);
652
+        return e;
653
+      }
654
+
655
+      template <typename A0, typename A1, typename A2> struct emplace_args3
656
+      {
657
+        BOOST_UNORDERED_EARGS_MEMBER(1, 0, _)
658
+        BOOST_UNORDERED_EARGS_MEMBER(1, 1, _)
659
+        BOOST_UNORDERED_EARGS_MEMBER(1, 2, _)
660
+
661
+        emplace_args3(Arg0 b0, Arg1 b1, Arg2 b2) : a0(b0), a1(b1), a2(b2) {}
662
+      };
663
+
664
+      template <typename A0, typename A1, typename A2>
665
+      inline emplace_args3<A0, A1, A2> create_emplace_args(
666
+        BOOST_FWD_REF(A0) b0, BOOST_FWD_REF(A1) b1, BOOST_FWD_REF(A2) b2)
667
+      {
668
+        emplace_args3<A0, A1, A2> e(b0, b1, b2);
669
+        return e;
670
+      }
671
+
672
+      BOOST_UNORDERED_EARGS(1, 4, _)
673
+      BOOST_UNORDERED_EARGS(1, 5, _)
674
+      BOOST_UNORDERED_EARGS(1, 6, _)
675
+      BOOST_UNORDERED_EARGS(1, 7, _)
676
+      BOOST_UNORDERED_EARGS(1, 8, _)
677
+      BOOST_UNORDERED_EARGS(1, 9, _)
678
+      BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
679
+        BOOST_UNORDERED_EARGS, _)
680
+    }
681
+  }
682
+}
683
+
684
+#undef BOOST_UNORDERED_DEFINE_EMPLACE_ARGS
685
+#undef BOOST_UNORDERED_EARGS_MEMBER
686
+#undef BOOST_UNORDERED_EARGS_INIT
687
+
688
+#endif
689
+
690
+////////////////////////////////////////////////////////////////////////////////
691
+//
692
+// Some utilities for implementing allocator_traits, but useful elsewhere so
693
+// they're always defined.
694
+
695
+namespace boost {
696
+  namespace unordered {
697
+    namespace detail {
698
+
699
+////////////////////////////////////////////////////////////////////////////
700
+// Integral_constrant, true_type, false_type
701
+//
702
+// Uses the standard versions if available.
703
+
704
+#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
705
+
706
+      using std::integral_constant;
707
+      using std::true_type;
708
+      using std::false_type;
709
+
710
+#else
711
+
712
+      template <typename T, T Value> struct integral_constant
713
+      {
714
+        enum
715
+        {
716
+          value = Value
717
+        };
718
+      };
719
+
720
+      typedef boost::unordered::detail::integral_constant<bool, true> true_type;
721
+      typedef boost::unordered::detail::integral_constant<bool, false>
722
+        false_type;
723
+
724
+#endif
725
+
726
+////////////////////////////////////////////////////////////////////////////
727
+// Explicitly call a destructor
728
+
729
+#if defined(BOOST_MSVC)
730
+#pragma warning(push)
731
+#pragma warning(disable : 4100) // unreferenced formal parameter
732
+#endif
733
+
734
+      namespace func {
735
+        template <class T> inline void destroy(T* x) { x->~T(); }
736
+      }
737
+
738
+#if defined(BOOST_MSVC)
739
+#pragma warning(pop)
740
+#endif
741
+
742
+      //////////////////////////////////////////////////////////////////////////
743
+      // value_base
744
+      //
745
+      // Space used to store values.
746
+
747
+      template <typename ValueType> struct value_base
748
+      {
749
+        typedef ValueType value_type;
750
+
751
+        typename boost::aligned_storage<sizeof(value_type),
752
+          boost::alignment_of<value_type>::value>::type data_;
753
+
754
+        value_base() : data_() {}
755
+
756
+        void* address() { return this; }
757
+
758
+        value_type& value() { return *(ValueType*)this; }
759
+
760
+        value_type const& value() const { return *(ValueType const*)this; }
761
+
762
+        value_type* value_ptr() { return (ValueType*)this; }
763
+
764
+        value_type const* value_ptr() const { return (ValueType const*)this; }
765
+
766
+      private:
767
+        value_base& operator=(value_base const&);
768
+      };
769
+
770
+      //////////////////////////////////////////////////////////////////////////
771
+      // optional
772
+      // TODO: Use std::optional when available.
773
+
774
+      template <typename T> class optional
775
+      {
776
+        BOOST_MOVABLE_BUT_NOT_COPYABLE(optional)
777
+
778
+        boost::unordered::detail::value_base<T> value_;
779
+        bool has_value_;
780
+
781
+        void destroy()
782
+        {
783
+          if (has_value_) {
784
+            boost::unordered::detail::func::destroy(value_.value_ptr());
785
+            has_value_ = false;
786
+          }
787
+        }
788
+
789
+        void move(optional<T>& x)
790
+        {
791
+          BOOST_ASSERT(!has_value_ && x.has_value_);
792
+          new (value_.value_ptr()) T(boost::move(x.value_.value()));
793
+          boost::unordered::detail::func::destroy(x.value_.value_ptr());
794
+          has_value_ = true;
795
+          x.has_value_ = false;
796
+        }
797
+
798
+      public:
799
+        optional() BOOST_NOEXCEPT : has_value_(false) {}
800
+
801
+        optional(BOOST_RV_REF(optional<T>) x) : has_value_(false)
802
+        {
803
+          if (x.has_value_) {
804
+            move(x);
805
+          }
806
+        }
807
+
808
+        explicit optional(T const& x) : has_value_(true)
809
+        {
810
+          new (value_.value_ptr()) T(x);
811
+        }
812
+
813
+        optional& operator=(BOOST_RV_REF(optional<T>) x)
814
+        {
815
+          destroy();
816
+          if (x.has_value_) {
817
+            move(x);
818
+          }
819
+          return *this;
820
+        }
821
+
822
+        ~optional() { destroy(); }
823
+
824
+        bool has_value() const { return has_value_; }
825
+        T& operator*() { return value_.value(); }
826
+        T const& operator*() const { return value_.value(); }
827
+        T* operator->() { return value_.value_ptr(); }
828
+        T const* operator->() const { return value_.value_ptr(); }
829
+
830
+        bool operator==(optional<T> const& x)
831
+        {
832
+          return has_value_ ? x.has_value_ && value_.value() == x.value_.value()
833
+                            : !x.has_value_;
834
+        }
835
+
836
+        bool operator!=(optional<T> const& x) { return !((*this) == x); }
837
+
838
+        void swap(optional<T>& x)
839
+        {
840
+          if (has_value_ != x.has_value_) {
841
+            if (has_value_) {
842
+              x.move(*this);
843
+            } else {
844
+              move(x);
845
+            }
846
+          } else if (has_value_) {
847
+            boost::swap(value_.value(), x.value_.value());
848
+          }
849
+        }
850
+
851
+        friend void swap(optional<T>& x, optional<T>& y) { x.swap(y); }
852
+      };
853
+    }
854
+  }
855
+}
856
+
857
+////////////////////////////////////////////////////////////////////////////
858
+// Expression test mechanism
859
+//
860
+// When SFINAE expressions are available, define
861
+// BOOST_UNORDERED_HAS_FUNCTION which can check if a function call is
862
+// supported by a class, otherwise define BOOST_UNORDERED_HAS_MEMBER which
863
+// can detect if a class has the specified member, but not that it has the
864
+// correct type, this is good enough for a passable impression of
865
+// allocator_traits.
866
+
867
+#if !defined(BOOST_NO_SFINAE_EXPR)
868
+
869
+namespace boost {
870
+  namespace unordered {
871
+    namespace detail {
872
+      template <typename T, long unsigned int> struct expr_test;
873
+      template <typename T> struct expr_test<T, sizeof(char)> : T
874
+      {
875
+      };
876
+    }
877
+  }
878
+}
879
+
880
+#define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression)            \
881
+  template <typename U>                                                        \
882
+  static                                                                       \
883
+    typename boost::unordered::detail::expr_test<BOOST_PP_CAT(choice, result), \
884
+      sizeof(for_expr_test(((expression), 0)))>::type                          \
885
+      test(BOOST_PP_CAT(choice, count))
886
+
887
+#define BOOST_UNORDERED_DEFAULT_EXPRESSION(count, result)                      \
888
+  template <typename U>                                                        \
889
+  static BOOST_PP_CAT(choice, result)::type test(BOOST_PP_CAT(choice, count))
890
+
891
+#define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _)                     \
892
+  struct BOOST_PP_CAT(has_, name)                                              \
893
+  {                                                                            \
894
+    template <typename U> static char for_expr_test(U const&);                 \
895
+    BOOST_UNORDERED_CHECK_EXPRESSION(                                          \
896
+      1, 1, boost::unordered::detail::make<thing>().name args);                \
897
+    BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2);                                  \
898
+                                                                               \
899
+    enum                                                                       \
900
+    {                                                                          \
901
+      value = sizeof(test<T>(choose())) == sizeof(choice1::type)               \
902
+    };                                                                         \
903
+  }
904
+
905
+#else
906
+
907
+namespace boost {
908
+  namespace unordered {
909
+    namespace detail {
910
+      template <typename T> struct identity
911
+      {
912
+        typedef T type;
913
+      };
914
+    }
915
+  }
916
+}
917
+
918
+#define BOOST_UNORDERED_CHECK_MEMBER(count, result, name, member)              \
919
+                                                                               \
920
+  typedef                                                                      \
921
+    typename boost::unordered::detail::identity<member>::type BOOST_PP_CAT(    \
922
+      check, count);                                                           \
923
+                                                                               \
924
+  template <BOOST_PP_CAT(check, count) e> struct BOOST_PP_CAT(test, count)     \
925
+  {                                                                            \
926
+    typedef BOOST_PP_CAT(choice, result) type;                                 \
927
+  };                                                                           \
928
+                                                                               \
929
+  template <class U>                                                           \
930
+  static typename BOOST_PP_CAT(test, count)<&U::name>::type test(              \
931
+    BOOST_PP_CAT(choice, count))
932
+
933
+#define BOOST_UNORDERED_DEFAULT_MEMBER(count, result)                          \
934
+  template <class U>                                                           \
935
+  static BOOST_PP_CAT(choice, result)::type test(BOOST_PP_CAT(choice, count))
936
+
937
+#define BOOST_UNORDERED_HAS_MEMBER(name)                                       \
938
+  struct BOOST_PP_CAT(has_, name)                                              \
939
+  {                                                                            \
940
+    struct impl                                                                \
941
+    {                                                                          \
942
+      struct base_mixin                                                        \
943
+      {                                                                        \
944
+        int name;                                                              \
945
+      };                                                                       \
946
+      struct base : public T, public base_mixin                                \
947
+      {                                                                        \
948
+      };                                                                       \
949
+                                                                               \
950
+      BOOST_UNORDERED_CHECK_MEMBER(1, 1, name, int base_mixin::*);             \
951
+      BOOST_UNORDERED_DEFAULT_MEMBER(2, 2);                                    \
952
+                                                                               \
953
+      enum                                                                     \
954
+      {                                                                        \
955
+        value = sizeof(choice2::type) == sizeof(test<base>(choose()))          \
956
+      };                                                                       \
957
+    };                                                                         \
958
+                                                                               \
959
+    enum                                                                       \
960
+    {                                                                          \
961
+      value = impl::value                                                      \
962
+    };                                                                         \
963
+  }
964
+
965
+#endif
966
+
967
+////////////////////////////////////////////////////////////////////////////
968
+// TRAITS TYPE DETECTION MECHANISM
969
+//
970
+// Used to implement traits that use a type if present, or a
971
+// default otherwise.
972
+
973
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1400
974
+
975
+#define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname)                              \
976
+  template <typename Tp, typename Default> struct default_type_##tname         \
977
+  {                                                                            \
978
+                                                                               \
979
+    template <typename X>                                                      \
980
+    static choice1::type test(choice1, typename X::tname* = 0);                \
981
+                                                                               \
982
+    template <typename X> static choice2::type test(choice2, void* = 0);       \
983
+                                                                               \
984
+    struct DefaultWrap                                                         \
985
+    {                                                                          \
986
+      typedef Default tname;                                                   \
987
+    };                                                                         \
988
+                                                                               \
989
+    enum                                                                       \
990
+    {                                                                          \
991
+      value = (1 == sizeof(test<Tp>(choose())))                                \
992
+    };                                                                         \
993
+                                                                               \
994
+    typedef typename boost::detail::if_true<value>::BOOST_NESTED_TEMPLATE      \
995
+      then<Tp, DefaultWrap>::type::tname type;                                 \
996
+  }
997
+
998
+#else
999
+
1000
+namespace boost {
1001
+  namespace unordered {
1002
+    namespace detail {
1003
+      template <typename T, typename T2> struct sfinae : T2
1004
+      {
1005
+      };
1006
+    }
1007
+  }
1008
+}
1009
+
1010
+#define BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(tname)                              \
1011
+  template <typename Tp, typename Default> struct default_type_##tname         \
1012
+  {                                                                            \
1013
+                                                                               \
1014
+    template <typename X>                                                      \
1015
+    static typename boost::unordered::detail::sfinae<typename X::tname,        \
1016
+      choice1>::type test(choice1);                                            \
1017
+                                                                               \
1018
+    template <typename X> static choice2::type test(choice2);                  \
1019
+                                                                               \
1020
+    struct DefaultWrap                                                         \
1021
+    {                                                                          \
1022
+      typedef Default tname;                                                   \
1023
+    };                                                                         \
1024
+                                                                               \
1025
+    enum                                                                       \
1026
+    {                                                                          \
1027
+      value = (1 == sizeof(test<Tp>(choose())))                                \
1028
+    };                                                                         \
1029
+                                                                               \
1030
+    typedef typename boost::detail::if_true<value>::BOOST_NESTED_TEMPLATE      \
1031
+      then<Tp, DefaultWrap>::type::tname type;                                 \
1032
+  }
1033
+
1034
+#endif
1035
+
1036
+#define BOOST_UNORDERED_DEFAULT_TYPE(T, tname, arg)                            \
1037
+  typename default_type_##tname<T, arg>::type
1038
+
1039
+////////////////////////////////////////////////////////////////////////////////
1040
+//
1041
+// Allocator traits
1042
+//
1043
+// First our implementation, then later light wrappers around the alternatives
1044
+
1045
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 0
1046
+
1047
+#include <boost/limits.hpp>
1048
+#include <boost/pointer_to_other.hpp>
1049
+#include <boost/utility/enable_if.hpp>
1050
+
1051
+namespace boost {
1052
+  namespace unordered {
1053
+    namespace detail {
1054
+
1055
+      template <typename Alloc, typename T> struct rebind_alloc;
1056
+
1057
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1058
+
1059
+      template <template <typename, typename...> class Alloc, typename U,
1060
+        typename T, typename... Args>
1061
+      struct rebind_alloc<Alloc<U, Args...>, T>
1062
+      {
1063
+        typedef Alloc<T, Args...> type;
1064
+      };
1065
+
1066
+#else
1067
+
1068
+      template <template <typename> class Alloc, typename U, typename T>
1069
+      struct rebind_alloc<Alloc<U>, T>
1070
+      {
1071
+        typedef Alloc<T> type;
1072
+      };
1073
+
1074
+      template <template <typename, typename> class Alloc, typename U,
1075
+        typename T, typename A0>
1076
+      struct rebind_alloc<Alloc<U, A0>, T>
1077
+      {
1078
+        typedef Alloc<T, A0> type;
1079
+      };
1080
+
1081
+      template <template <typename, typename, typename> class Alloc, typename U,
1082
+        typename T, typename A0, typename A1>
1083
+      struct rebind_alloc<Alloc<U, A0, A1>, T>
1084
+      {
1085
+        typedef Alloc<T, A0, A1> type;
1086
+      };
1087
+
1088
+#endif
1089
+
1090
+      template <typename Alloc, typename T> struct rebind_wrap
1091
+      {
1092
+        template <typename X>
1093
+        static choice1::type test(
1094
+          choice1, typename X::BOOST_NESTED_TEMPLATE rebind<T>::other* = 0);
1095
+        template <typename X> static choice2::type test(choice2, void* = 0);
1096
+
1097
+        enum
1098
+        {
1099
+          value = (1 == sizeof(test<Alloc>(choose())))
1100
+        };
1101
+
1102
+        struct fallback
1103
+        {
1104
+          template <typename U> struct rebind
1105
+          {
1106
+            typedef typename rebind_alloc<Alloc, T>::type other;
1107
+          };
1108
+        };
1109
+
1110
+        typedef
1111
+          typename boost::detail::if_true<value>::BOOST_NESTED_TEMPLATE then<
1112
+            Alloc, fallback>::type::BOOST_NESTED_TEMPLATE rebind<T>::other type;
1113
+      };
1114
+    }
1115
+  }
1116
+}
1117
+
1118
+namespace boost {
1119
+  namespace unordered {
1120
+    namespace detail {
1121
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(pointer);
1122
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(const_pointer);
1123
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(void_pointer);
1124
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(const_void_pointer);
1125
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(difference_type);
1126
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(size_type);
1127
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(
1128
+        propagate_on_container_copy_assignment);
1129
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(
1130
+        propagate_on_container_move_assignment);
1131
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
1132
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(is_always_equal);
1133
+
1134
+#if !defined(BOOST_NO_SFINAE_EXPR)
1135
+
1136
+      template <typename T>
1137
+      BOOST_UNORDERED_HAS_FUNCTION(
1138
+        select_on_container_copy_construction, U const, (), 0);
1139
+
1140
+      template <typename T>
1141
+      BOOST_UNORDERED_HAS_FUNCTION(max_size, U const, (), 0);
1142
+
1143
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1144
+
1145
+      template <typename T, typename ValueType, typename... Args>
1146
+      BOOST_UNORDERED_HAS_FUNCTION(construct, U,
1147
+        (boost::unordered::detail::make<ValueType*>(),
1148
+          boost::unordered::detail::make<Args const>()...),
1149
+        2);
1150
+
1151
+#else
1152
+
1153
+      template <typename T, typename ValueType>
1154
+      BOOST_UNORDERED_HAS_FUNCTION(construct, U,
1155
+        (boost::unordered::detail::make<ValueType*>(),
1156
+          boost::unordered::detail::make<ValueType const>()),
1157
+        2);
1158
+
1159
+#endif
1160
+
1161
+      template <typename T, typename ValueType>
1162
+      BOOST_UNORDERED_HAS_FUNCTION(
1163
+        destroy, U, (boost::unordered::detail::make<ValueType*>()), 1);
1164
+
1165
+#else
1166
+
1167
+      template <typename T>
1168
+      BOOST_UNORDERED_HAS_MEMBER(select_on_container_copy_construction);
1169
+
1170
+      template <typename T> BOOST_UNORDERED_HAS_MEMBER(max_size);
1171
+
1172
+      template <typename T, typename ValueType>
1173
+      BOOST_UNORDERED_HAS_MEMBER(construct);
1174
+
1175
+      template <typename T, typename ValueType>
1176
+      BOOST_UNORDERED_HAS_MEMBER(destroy);
1177
+
1178
+#endif
1179
+    }
1180
+  }
1181
+}
1182
+
1183
+namespace boost {
1184
+  namespace unordered {
1185
+    namespace detail {
1186
+      namespace func {
1187
+
1188
+        template <typename Alloc>
1189
+        inline Alloc call_select_on_container_copy_construction(
1190
+          const Alloc& rhs,
1191
+          typename boost::enable_if_c<
1192
+            boost::unordered::detail::has_select_on_container_copy_construction<
1193
+              Alloc>::value,
1194
+            void*>::type = 0)
1195
+        {
1196
+          return rhs.select_on_container_copy_construction();
1197
+        }
1198
+
1199
+        template <typename Alloc>
1200
+        inline Alloc call_select_on_container_copy_construction(
1201
+          const Alloc& rhs,
1202
+          typename boost::disable_if_c<
1203
+            boost::unordered::detail::has_select_on_container_copy_construction<
1204
+              Alloc>::value,
1205
+            void*>::type = 0)
1206
+        {
1207
+          return rhs;
1208
+        }
1209
+
1210
+        template <typename SizeType, typename Alloc>
1211
+        inline SizeType call_max_size(const Alloc& a,
1212
+          typename boost::enable_if_c<
1213
+            boost::unordered::detail::has_max_size<Alloc>::value, void*>::type =
1214
+            0)
1215
+        {
1216
+          return a.max_size();
1217
+        }
1218
+
1219
+        template <typename SizeType, typename Alloc>
1220
+        inline SizeType call_max_size(const Alloc&,
1221
+          typename boost::disable_if_c<
1222
+            boost::unordered::detail::has_max_size<Alloc>::value, void*>::type =
1223
+            0)
1224
+        {
1225
+          return (std::numeric_limits<SizeType>::max)();
1226
+        }
1227
+      } // namespace func.
1228
+    }
1229
+  }
1230
+}
1231
+
1232
+namespace boost {
1233
+  namespace unordered {
1234
+    namespace detail {
1235
+      template <typename Alloc> struct allocator_traits
1236
+      {
1237
+        typedef Alloc allocator_type;
1238
+        typedef typename Alloc::value_type value_type;
1239
+
1240
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(
1241
+          Alloc, pointer, value_type*) pointer;
1242
+
1243
+        template <typename T>
1244
+        struct pointer_to_other : boost::pointer_to_other<pointer, T>
1245
+        {
1246
+        };
1247
+
1248
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_pointer,
1249
+          typename pointer_to_other<const value_type>::type) const_pointer;
1250
+
1251
+        // typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, void_pointer,
1252
+        //    typename pointer_to_other<void>::type)
1253
+        //    void_pointer;
1254
+        //
1255
+        // typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, const_void_pointer,
1256
+        //    typename pointer_to_other<const void>::type)
1257
+        //    const_void_pointer;
1258
+
1259
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(
1260
+          Alloc, difference_type, std::ptrdiff_t) difference_type;
1261
+
1262
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(
1263
+          Alloc, size_type, std::size_t) size_type;
1264
+
1265
+#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
1266
+        template <typename T>
1267
+        using rebind_alloc = typename rebind_wrap<Alloc, T>::type;
1268
+
1269
+        template <typename T>
1270
+        using rebind_traits =
1271
+          boost::unordered::detail::allocator_traits<rebind_alloc<T> >;
1272
+#endif
1273
+
1274
+        static pointer allocate(Alloc& a, size_type n) { return a.allocate(n); }
1275
+
1276
+        // I never use this, so I'll just comment it out for now.
1277
+        //
1278
+        // static pointer allocate(Alloc& a, size_type n,
1279
+        //        const_void_pointer hint)
1280
+        //    { return DEFAULT_FUNC(allocate, pointer)(a, n, hint); }
1281
+
1282
+        static void deallocate(Alloc& a, pointer p, size_type n)
1283
+        {
1284
+          a.deallocate(p, n);
1285
+        }
1286
+
1287
+      public:
1288
+#if BOOST_UNORDERED_CXX11_CONSTRUCTION
1289
+
1290
+        template <typename T, typename... Args>
1291
+        static
1292
+          typename boost::enable_if_c<boost::unordered::detail::has_construct<
1293
+            Alloc, T, Args...>::value>::type
1294
+          construct(Alloc& a, T* p, BOOST_FWD_REF(Args)... x)
1295
+        {
1296
+          a.construct(p, boost::forward<Args>(x)...);
1297
+        }
1298
+
1299
+        template <typename T, typename... Args>
1300
+        static
1301
+          typename boost::disable_if_c<boost::unordered::detail::has_construct<
1302
+            Alloc, T, Args...>::value>::type
1303
+          construct(Alloc&, T* p, BOOST_FWD_REF(Args)... x)
1304
+        {
1305
+          new (static_cast<void*>(p)) T(boost::forward<Args>(x)...);
1306
+        }
1307
+
1308
+        template <typename T>
1309
+        static typename boost::enable_if_c<
1310
+          boost::unordered::detail::has_destroy<Alloc, T>::value>::type
1311
+        destroy(Alloc& a, T* p)
1312
+        {
1313
+          a.destroy(p);
1314
+        }
1315
+
1316
+        template <typename T>
1317
+        static typename boost::disable_if_c<
1318
+          boost::unordered::detail::has_destroy<Alloc, T>::value>::type
1319
+        destroy(Alloc&, T* p)
1320
+        {
1321
+          boost::unordered::detail::func::destroy(p);
1322
+        }
1323
+
1324
+#elif !defined(BOOST_NO_SFINAE_EXPR)
1325
+
1326
+        template <typename T>
1327
+        static typename boost::enable_if_c<
1328
+          boost::unordered::detail::has_construct<Alloc, T>::value>::type
1329
+        construct(Alloc& a, T* p, T const& x)
1330
+        {
1331
+          a.construct(p, x);
1332
+        }
1333
+
1334
+        template <typename T>
1335
+        static typename boost::disable_if_c<
1336
+          boost::unordered::detail::has_construct<Alloc, T>::value>::type
1337
+        construct(Alloc&, T* p, T const& x)
1338
+        {
1339
+          new (static_cast<void*>(p)) T(x);
1340
+        }
1341
+
1342
+        template <typename T>
1343
+        static typename boost::enable_if_c<
1344
+          boost::unordered::detail::has_destroy<Alloc, T>::value>::type
1345
+        destroy(Alloc& a, T* p)
1346
+        {
1347
+          a.destroy(p);
1348
+        }
1349
+
1350
+        template <typename T>
1351
+        static typename boost::disable_if_c<
1352
+          boost::unordered::detail::has_destroy<Alloc, T>::value>::type
1353
+        destroy(Alloc&, T* p)
1354
+        {
1355
+          boost::unordered::detail::func::destroy(p);
1356
+        }
1357
+
1358
+#else
1359
+
1360
+        // If we don't have SFINAE expressions, only call construct for the
1361
+        // copy constructor for the allocator's value_type - as that's
1362
+        // the only construct method that old fashioned allocators support.
1363
+
1364
+        template <typename T>
1365
+        static void construct(Alloc& a, T* p, T const& x,
1366
+          typename boost::enable_if_c<
1367
+            boost::unordered::detail::has_construct<Alloc, T>::value &&
1368
+              boost::is_same<T, value_type>::value,
1369
+            void*>::type = 0)
1370
+        {
1371
+          a.construct(p, x);
1372
+        }
1373
+
1374
+        template <typename T>
1375
+        static void construct(Alloc&, T* p, T const& x,
1376
+          typename boost::disable_if_c<
1377
+            boost::unordered::detail::has_construct<Alloc, T>::value &&
1378
+              boost::is_same<T, value_type>::value,
1379
+            void*>::type = 0)
1380
+        {
1381
+          new (static_cast<void*>(p)) T(x);
1382
+        }
1383
+
1384
+        template <typename T>
1385
+        static void destroy(Alloc& a, T* p,
1386
+          typename boost::enable_if_c<
1387
+            boost::unordered::detail::has_destroy<Alloc, T>::value &&
1388
+              boost::is_same<T, value_type>::value,
1389
+            void*>::type = 0)
1390
+        {
1391
+          a.destroy(p);
1392
+        }
1393
+
1394
+        template <typename T>
1395
+        static void destroy(Alloc&, T* p,
1396
+          typename boost::disable_if_c<
1397
+            boost::unordered::detail::has_destroy<Alloc, T>::value &&
1398
+              boost::is_same<T, value_type>::value,
1399
+            void*>::type = 0)
1400
+        {
1401
+          boost::unordered::detail::func::destroy(p);
1402
+        }
1403
+
1404
+#endif
1405
+
1406
+        static size_type max_size(const Alloc& a)
1407
+        {
1408
+          return boost::unordered::detail::func::call_max_size<size_type>(a);
1409
+        }
1410
+
1411
+        // Allocator propagation on construction
1412
+
1413
+        static Alloc select_on_container_copy_construction(Alloc const& rhs)
1414
+        {
1415
+          return boost::unordered::detail::func::
1416
+            call_select_on_container_copy_construction(rhs);
1417
+        }
1418
+
1419
+        // Allocator propagation on assignment and swap.
1420
+        // Return true if lhs is modified.
1421
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc,
1422
+          propagate_on_container_copy_assignment,
1423
+          false_type) propagate_on_container_copy_assignment;
1424
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc,
1425
+          propagate_on_container_move_assignment,
1426
+          false_type) propagate_on_container_move_assignment;
1427
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, propagate_on_container_swap,
1428
+          false_type) propagate_on_container_swap;
1429
+
1430
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(Alloc, is_always_equal,
1431
+          typename boost::is_empty<Alloc>::type) is_always_equal;
1432
+      };
1433
+    }
1434
+  }
1435
+}
1436
+
1437
+#undef BOOST_UNORDERED_DEFAULT_TYPE_TMPLT
1438
+#undef BOOST_UNORDERED_DEFAULT_TYPE
1439
+
1440
+////////////////////////////////////////////////////////////////////////////////
1441
+//
1442
+// std::allocator_traits
1443
+
1444
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
1445
+
1446
+#include <memory>
1447
+
1448
+namespace boost {
1449
+  namespace unordered {
1450
+    namespace detail {
1451
+
1452
+      BOOST_UNORDERED_DEFAULT_TYPE_TMPLT(is_always_equal);
1453
+
1454
+      template <typename Alloc>
1455
+      struct allocator_traits : std::allocator_traits<Alloc>
1456
+      {
1457
+        // As is_always_equal was introduced in C++17, std::allocator_traits
1458
+        // doesn't always have it. So use it when available, implement it
1459
+        // ourselves when not. Would be simpler not to bother with
1460
+        // std::allocator_traits, but I feel like I should try to use
1461
+        // it where possible.
1462
+        typedef BOOST_UNORDERED_DEFAULT_TYPE(std::allocator_traits<Alloc>,
1463
+          is_always_equal,
1464
+          BOOST_UNORDERED_DEFAULT_TYPE(Alloc, is_always_equal,
1465
+            typename boost::is_empty<Alloc>::type)) is_always_equal;
1466
+      };
1467
+
1468
+      template <typename Alloc, typename T> struct rebind_wrap
1469
+      {
1470
+        typedef typename std::allocator_traits<Alloc>::template rebind_alloc<T>
1471
+          type;
1472
+      };
1473
+    }
1474
+  }
1475
+}
1476
+
1477
+////////////////////////////////////////////////////////////////////////////////
1478
+//
1479
+// boost::container::allocator_traits
1480
+
1481
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 2
1482
+
1483
+#include <boost/container/allocator_traits.hpp>
1484
+
1485
+namespace boost {
1486
+  namespace unordered {
1487
+    namespace detail {
1488
+
1489
+      template <typename Alloc>
1490
+      struct allocator_traits : boost::container::allocator_traits<Alloc>
1491
+      {
1492
+      };
1493
+
1494
+      template <typename Alloc, typename T>
1495
+      struct rebind_wrap : boost::container::allocator_traits<
1496
+                             Alloc>::template portable_rebind_alloc<T>
1497
+      {
1498
+      };
1499
+    }
1500
+  }
1501
+}
1502
+
1503
+#else
1504
+
1505
+#error "Invalid BOOST_UNORDERED_USE_ALLOCATOR_TRAITS value."
1506
+
1507
+#endif
1508
+
1509
+////////////////////////////////////////////////////////////////////////////
1510
+// Functions used to construct nodes. Emulates variadic construction,
1511
+// piecewise construction etc.
1512
+
1513
+////////////////////////////////////////////////////////////////////////////
1514
+// construct_value
1515
+//
1516
+// Only use allocator_traits::construct, allocator_traits::destroy when full
1517
+// C++11 support is available.
1518
+
1519
+#if BOOST_UNORDERED_CXX11_CONSTRUCTION
1520
+
1521
+#define BOOST_UNORDERED_CALL_CONSTRUCT1(Traits, alloc, address, a0)            \
1522
+  Traits::construct(alloc, address, a0)
1523
+#define BOOST_UNORDERED_CALL_DESTROY(Traits, alloc, x) Traits::destroy(alloc, x)
1524
+
1525
+#elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1526
+
1527
+namespace boost {
1528
+  namespace unordered {
1529
+    namespace detail {
1530
+      namespace func {
1531
+        template <typename T, typename... Args>
1532
+        inline void construct_value(T* address, BOOST_FWD_REF(Args)... args)
1533
+        {
1534
+          new ((void*)address) T(boost::forward<Args>(args)...);
1535
+        }
1536
+      }
1537
+    }
1538
+  }
1539
+}
1540
+
1541
+#define BOOST_UNORDERED_CALL_CONSTRUCT1(Traits, alloc, address, a0)            \
1542
+  boost::unordered::detail::func::construct_value(address, a0)
1543
+#define BOOST_UNORDERED_CALL_DESTROY(Traits, alloc, x)                         \
1544
+  boost::unordered::detail::func::destroy(x)
1545
+
1546
+#else
1547
+
1548
+namespace boost {
1549
+  namespace unordered {
1550
+    namespace detail {
1551
+      namespace func {
1552
+        template <typename T> inline void construct_value(T* address)
1553
+        {
1554
+          new ((void*)address) T();
1555
+        }
1556
+
1557
+        template <typename T, typename A0>
1558
+        inline void construct_value(T* address, BOOST_FWD_REF(A0) a0)
1559
+        {
1560
+          new ((void*)address) T(boost::forward<A0>(a0));
1561
+        }
1562
+      }
1563
+    }
1564
+  }
1565
+}
1566
+
1567
+#define BOOST_UNORDERED_CALL_CONSTRUCT1(Traits, alloc, address, a0)            \
1568
+  boost::unordered::detail::func::construct_value(address, a0)
1569
+#define BOOST_UNORDERED_CALL_DESTROY(Traits, alloc, x)                         \
1570
+  boost::unordered::detail::func::destroy(x)
1571
+
1572
+#endif
1573
+
1574
+////////////////////////////////////////////////////////////////////////////
1575
+// Construct from tuple
1576
+//
1577
+// Used to emulate piecewise construction.
1578
+
1579
+#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(z, n, namespace_)                 \
1580
+  template <typename Alloc, typename T,                                        \
1581
+    BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                                  \
1582
+  void construct_from_tuple(Alloc&, T* ptr,                                    \
1583
+    namespace_::tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x)               \
1584
+  {                                                                            \
1585
+    new ((void*)ptr)                                                           \
1586
+      T(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_));      \
1587
+  }
1588
+
1589
+#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) namespace_::get<n>(x)
1590
+
1591
+// construct_from_tuple for boost::tuple
1592
+// The workaround for old Sun compilers comes later in the file.
1593
+
1594
+#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
1595
+
1596
+namespace boost {
1597
+  namespace unordered {
1598
+    namespace detail {
1599
+      namespace func {
1600
+        template <typename Alloc, typename T>
1601
+        void construct_from_tuple(Alloc&, T* ptr, boost::tuple<>)
1602
+        {
1603
+          new ((void*)ptr) T();
1604
+        }
1605
+
1606
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, boost)
1607
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, boost)
1608
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, boost)
1609
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, boost)
1610
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, boost)
1611
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 6, boost)
1612
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 7, boost)
1613
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 8, boost)
1614
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 9, boost)
1615
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 10, boost)
1616
+      }
1617
+    }
1618
+  }
1619
+}
1620
+
1621
+#endif
1622
+
1623
+// construct_from_tuple for std::tuple
1624
+
1625
+#if !BOOST_UNORDERED_CXX11_CONSTRUCTION && BOOST_UNORDERED_TUPLE_ARGS
1626
+
1627
+namespace boost {
1628
+  namespace unordered {
1629
+    namespace detail {
1630
+      namespace func {
1631
+        template <typename Alloc, typename T>
1632
+        void construct_from_tuple(Alloc&, T* ptr, std::tuple<>)
1633
+        {
1634
+          new ((void*)ptr) T();
1635
+        }
1636
+
1637
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, std)
1638
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, std)
1639
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, std)
1640
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, std)
1641
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, std)
1642
+
1643
+#if BOOST_UNORDERED_TUPLE_ARGS >= 6
1644
+        BOOST_PP_REPEAT_FROM_TO(6, BOOST_PP_INC(BOOST_UNORDERED_TUPLE_ARGS),
1645
+          BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE, std)
1646
+#endif
1647
+      }
1648
+    }
1649
+  }
1650
+}
1651
+
1652
+#endif
1653
+
1654
+#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE
1655
+#undef BOOST_UNORDERED_GET_TUPLE_ARG
1656
+
1657
+// construct_from_tuple for boost::tuple on old versions of sunpro.
1658
+//
1659
+// Old versions of Sun C++ had problems with template overloads of
1660
+// boost::tuple, so to fix it I added a distinct type for each length to
1661
+// the overloads. That means there's no possible ambiguity between the
1662
+// different overloads, so that the compiler doesn't get confused
1663
+
1664
+#if BOOST_UNORDERED_SUN_WORKAROUNDS1
1665
+
1666
+#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(z, n, namespace_)                 \
1667
+  template <typename Alloc, typename T,                                        \
1668
+    BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>                                  \
1669
+  void construct_from_tuple_impl(boost::unordered::detail::func::length<n>,    \
1670
+    Alloc&, T* ptr,                                                            \
1671
+    namespace_::tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x)               \
1672
+  {                                                                            \
1673
+    new ((void*)ptr)                                                           \
1674
+      T(BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_));      \
1675
+  }
1676
+
1677
+#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) namespace_::get<n>(x)
1678
+
1679
+namespace boost {
1680
+  namespace unordered {
1681
+    namespace detail {
1682
+      namespace func {
1683
+        template <int N> struct length
1684
+        {
1685
+        };
1686
+
1687
+        template <typename Alloc, typename T>
1688
+        void construct_from_tuple_impl(
1689
+          boost::unordered::detail::func::length<0>, Alloc&, T* ptr,
1690
+          boost::tuple<>)
1691
+        {
1692
+          new ((void*)ptr) T();
1693
+        }
1694
+
1695
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 1, boost)
1696
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 2, boost)
1697
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 3, boost)
1698
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 4, boost)
1699
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 5, boost)
1700
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 6, boost)
1701
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 7, boost)
1702
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 8, boost)
1703
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 9, boost)
1704
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(1, 10, boost)
1705
+
1706
+        template <typename Alloc, typename T, typename Tuple>
1707
+        void construct_from_tuple(Alloc& alloc, T* ptr, Tuple const& x)
1708
+        {
1709
+          construct_from_tuple_impl(boost::unordered::detail::func::length<
1710
+                                      boost::tuples::length<Tuple>::value>(),
1711
+            alloc, ptr, x);
1712
+        }
1713
+      }
1714
+    }
1715
+  }
1716
+}
1717
+
1718
+#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE
1719
+#undef BOOST_UNORDERED_GET_TUPLE_ARG
1720
+
1721
+#endif
1722
+
1723
+namespace boost {
1724
+  namespace unordered {
1725
+    namespace detail {
1726
+      namespace func {
1727
+        ////////////////////////////////////////////////////////////////////////
1728
+        // Trait to check for piecewise construction.
1729
+
1730
+        template <typename A0> struct use_piecewise
1731
+        {
1732
+          static choice1::type test(
1733
+            choice1, boost::unordered::piecewise_construct_t);
1734
+
1735
+          static choice2::type test(choice2, ...);
1736
+
1737
+          enum
1738
+          {
1739
+            value = sizeof(choice1::type) ==
1740
+                    sizeof(test(choose(), boost::unordered::detail::make<A0>()))
1741
+          };
1742
+        };
1743
+
1744
+#if BOOST_UNORDERED_CXX11_CONSTRUCTION
1745
+
1746
+        ////////////////////////////////////////////////////////////////////////
1747
+        // Construct from variadic parameters
1748
+
1749
+        template <typename Alloc, typename T, typename... Args>
1750
+        inline void construct_from_args(
1751
+          Alloc& alloc, T* address, BOOST_FWD_REF(Args)... args)
1752
+        {
1753
+          boost::unordered::detail::allocator_traits<Alloc>::construct(
1754
+            alloc, address, boost::forward<Args>(args)...);
1755
+        }
1756
+
1757
+        // For backwards compatibility, implement a special case for
1758
+        // piecewise_construct with boost::tuple
1759
+
1760
+        template <typename A0> struct detect_boost_tuple
1761
+        {
1762
+          template <typename T0, typename T1, typename T2, typename T3,
1763
+            typename T4, typename T5, typename T6, typename T7, typename T8,
1764
+            typename T9>
1765
+          static choice1::type test(choice1,
1766
+            boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> const&);
1767
+
1768
+          static choice2::type test(choice2, ...);
1769
+
1770
+          enum
1771
+          {
1772
+            value = sizeof(choice1::type) ==
1773
+                    sizeof(test(choose(), boost::unordered::detail::make<A0>()))
1774
+          };
1775
+        };
1776
+
1777
+        // Special case for piecewise_construct
1778
+
1779
+        template <typename Alloc, typename A, typename B, typename A0,
1780
+          typename A1, typename A2>
1781
+        inline typename boost::enable_if_c<use_piecewise<A0>::value &&
1782
+                                             detect_boost_tuple<A1>::value &&
1783
+                                             detect_boost_tuple<A2>::value,
1784
+          void>::type
1785
+        construct_from_args(Alloc& alloc, std::pair<A, B>* address,
1786
+          BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
1787
+        {
1788
+          boost::unordered::detail::func::construct_from_tuple(
1789
+            alloc, boost::addressof(address->first), boost::forward<A1>(a1));
1790
+          BOOST_TRY
1791
+          {
1792
+            boost::unordered::detail::func::construct_from_tuple(
1793
+              alloc, boost::addressof(address->second), boost::forward<A2>(a2));
1794
+          }
1795
+          BOOST_CATCH(...)
1796
+          {
1797
+            boost::unordered::detail::func::destroy(
1798
+              boost::addressof(address->first));
1799
+            BOOST_RETHROW
1800
+          }
1801
+          BOOST_CATCH_END
1802
+        }
1803
+
1804
+#elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1805
+
1806
+        ////////////////////////////////////////////////////////////////////////
1807
+        // Construct from variadic parameters
1808
+
1809
+        template <typename Alloc, typename T, typename... Args>
1810
+        inline void construct_from_args(
1811
+          Alloc&, T* address, BOOST_FWD_REF(Args)... args)
1812
+        {
1813
+          new ((void*)address) T(boost::forward<Args>(args)...);
1814
+        }
1815
+
1816
+        // Special case for piecewise_construct
1817
+
1818
+        template <typename Alloc, typename A, typename B, typename A0,
1819
+          typename A1, typename A2>
1820
+        inline typename enable_if<use_piecewise<A0>, void>::type
1821
+        construct_from_args(Alloc& alloc, std::pair<A, B>* address,
1822
+          BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
1823
+        {
1824
+          boost::unordered::detail::func::construct_from_tuple(
1825
+            alloc, boost::addressof(address->first), boost::forward<A1>(a1));
1826
+          BOOST_TRY
1827
+          {
1828
+            boost::unordered::detail::func::construct_from_tuple(
1829
+              alloc, boost::addressof(address->second), boost::forward<A2>(a2));
1830
+          }
1831
+          BOOST_CATCH(...)
1832
+          {
1833
+            boost::unordered::detail::func::destroy(
1834
+              boost::addressof(address->first));
1835
+            BOOST_RETHROW
1836
+          }
1837
+          BOOST_CATCH_END
1838
+        }
1839
+
1840
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
1841
+
1842
+        ////////////////////////////////////////////////////////////////////////
1843
+        // Construct from emplace_args
1844
+
1845
+        // Explicitly write out first three overloads for the sake of sane
1846
+        // error messages.
1847
+
1848
+        template <typename Alloc, typename T, typename A0>
1849
+        inline void construct_from_args(
1850
+          Alloc&, T* address, emplace_args1<A0> const& args)
1851
+        {
1852
+          new ((void*)address) T(boost::forward<A0>(args.a0));
1853
+        }
1854
+
1855
+        template <typename Alloc, typename T, typename A0, typename A1>
1856
+        inline void construct_from_args(
1857
+          Alloc&, T* address, emplace_args2<A0, A1> const& args)
1858
+        {
1859
+          new ((void*)address)
1860
+            T(boost::forward<A0>(args.a0), boost::forward<A1>(args.a1));
1861
+        }
1862
+
1863
+        template <typename Alloc, typename T, typename A0, typename A1,
1864
+          typename A2>
1865
+        inline void construct_from_args(
1866
+          Alloc&, T* address, emplace_args3<A0, A1, A2> const& args)
1867
+        {
1868
+          new ((void*)address) T(boost::forward<A0>(args.a0),
1869
+            boost::forward<A1>(args.a1), boost::forward<A2>(args.a2));
1870
+        }
1871
+
1872
+// Use a macro for the rest.
1873
+
1874
+#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _)                       \
1875
+  template <typename Alloc, typename T,                                        \
1876
+    BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A)>                         \
1877
+  inline void construct_from_args(Alloc&, T* address,                          \
1878
+    boost::unordered::detail::BOOST_PP_CAT(emplace_args, num_params) <         \
1879
+      BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) > const& args)                  \
1880
+  {                                                                            \
1881
+    new ((void*)address)                                                       \
1882
+      T(BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_FORWARD, args.a));  \
1883
+  }
1884
+
1885
+        BOOST_UNORDERED_CONSTRUCT_IMPL(1, 4, _)
1886
+        BOOST_UNORDERED_CONSTRUCT_IMPL(1, 5, _)
1887
+        BOOST_UNORDERED_CONSTRUCT_IMPL(1, 6, _)
1888
+        BOOST_UNORDERED_CONSTRUCT_IMPL(1, 7, _)
1889
+        BOOST_UNORDERED_CONSTRUCT_IMPL(1, 8, _)
1890
+        BOOST_UNORDERED_CONSTRUCT_IMPL(1, 9, _)
1891
+        BOOST_PP_REPEAT_FROM_TO(10, BOOST_PP_INC(BOOST_UNORDERED_EMPLACE_LIMIT),
1892
+          BOOST_UNORDERED_CONSTRUCT_IMPL, _)
1893
+
1894
+#undef BOOST_UNORDERED_CONSTRUCT_IMPL
1895
+