1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
12 #define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
13 
14 #ifndef BOOST_CONFIG_HPP
15 #  include <boost/config.hpp>
16 #endif
17 
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
19 #  pragma once
20 #endif
21 
22 #include <boost/container/detail/config_begin.hpp>
23 #include <boost/container/detail/workaround.hpp>
24 
25 // container
26 #include <boost/container/allocator_traits.hpp>
27 // container/detail
28 #include <boost/container/detail/copy_move_algo.hpp>
29 #include <boost/container/detail/destroyers.hpp>
30 #include <boost/container/detail/mpl.hpp>
31 #include <boost/container/detail/type_traits.hpp>
32 #include <boost/container/detail/iterator.hpp>
33 #include <boost/container/detail/iterators.hpp>
34 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
35 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
36 #include <boost/move/detail/fwd_macros.hpp>
37 #endif
38 // move
39 #include <boost/move/utility_core.hpp>
40 // other
41 #include <boost/assert.hpp>
42 #include <boost/core/no_exceptions_support.hpp>
43 
44 namespace boost { namespace container { namespace dtl {
45 
46 template<class Allocator, class FwdIt, class Iterator>
47 struct move_insert_range_proxy
48 {
49    typedef typename allocator_traits<Allocator>::size_type size_type;
50    typedef typename allocator_traits<Allocator>::value_type value_type;
51 
move_insert_range_proxyboost::container::dtl::move_insert_range_proxy52    BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first)
53       :  first_(first)
54    {}
55 
uninitialized_copy_n_and_updateboost::container::dtl::move_insert_range_proxy56    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
57    {
58       this->first_ = ::boost::container::uninitialized_move_alloc_n_source
59          (a, this->first_, n, p);
60    }
61 
copy_n_and_updateboost::container::dtl::move_insert_range_proxy62    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n)
63    {
64       this->first_ = ::boost::container::move_n_source(this->first_, n, p);
65    }
66 
67    FwdIt first_;
68 };
69 
70 
71 template<class Allocator, class FwdIt, class Iterator>
72 struct insert_range_proxy
73 {
74    typedef typename allocator_traits<Allocator>::size_type size_type;
75    typedef typename allocator_traits<Allocator>::value_type value_type;
76 
insert_range_proxyboost::container::dtl::insert_range_proxy77    BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first)
78       :  first_(first)
79    {}
80 
uninitialized_copy_n_and_updateboost::container::dtl::insert_range_proxy81    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
82    {
83       this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
84    }
85 
copy_n_and_updateboost::container::dtl::insert_range_proxy86    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n)
87    {
88       this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
89    }
90 
91    FwdIt first_;
92 };
93 
94 
95 template<class Allocator, class Iterator>
96 struct insert_n_copies_proxy
97 {
98    typedef typename allocator_traits<Allocator>::size_type size_type;
99    typedef typename allocator_traits<Allocator>::value_type value_type;
100 
insert_n_copies_proxyboost::container::dtl::insert_n_copies_proxy101    BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v)
102       :  v_(v)
103    {}
104 
uninitialized_copy_n_and_updateboost::container::dtl::insert_n_copies_proxy105    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
106    {  boost::container::uninitialized_fill_alloc_n(a, v_, n, p);  }
107 
copy_n_and_updateboost::container::dtl::insert_n_copies_proxy108    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const
109    {
110       while (n){
111          --n;
112          *p = v_;
113          ++p;
114       }
115    }
116 
117    const value_type &v_;
118 };
119 
120 template<class Allocator, class Iterator>
121 struct insert_value_initialized_n_proxy
122 {
123    typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
124    typedef typename allocator_traits<Allocator>::size_type size_type;
125    typedef typename allocator_traits<Allocator>::value_type value_type;
126    typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
127 
uninitialized_copy_n_and_updateboost::container::dtl::insert_value_initialized_n_proxy128    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
129    {  boost::container::uninitialized_value_init_alloc_n(a, n, p);  }
130 
copy_n_and_updateboost::container::dtl::insert_value_initialized_n_proxy131    void copy_n_and_update(Allocator &a, Iterator p, size_type n) const
132    {
133       while (n){
134          --n;
135          storage_t v;
136          value_type *vp = reinterpret_cast<value_type *>(v.data);
137          alloc_traits::construct(a, vp);
138          value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
139          *p = ::boost::move(*vp);
140          ++p;
141       }
142    }
143 };
144 
145 template<class Allocator, class Iterator>
146 struct insert_default_initialized_n_proxy
147 {
148    typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
149    typedef typename allocator_traits<Allocator>::size_type size_type;
150    typedef typename allocator_traits<Allocator>::value_type value_type;
151    typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
152 
uninitialized_copy_n_and_updateboost::container::dtl::insert_default_initialized_n_proxy153    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
154    {  boost::container::uninitialized_default_init_alloc_n(a, n, p);  }
155 
copy_n_and_updateboost::container::dtl::insert_default_initialized_n_proxy156    void copy_n_and_update(Allocator &a, Iterator p, size_type n) const
157    {
158       if(!is_pod<value_type>::value){
159          while (n){
160             --n;
161             typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
162             value_type *vp = reinterpret_cast<value_type *>(v.data);
163             alloc_traits::construct(a, vp, default_init);
164             value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
165             *p = ::boost::move(*vp);
166             ++p;
167          }
168       }
169    }
170 };
171 
172 template<class Allocator, class Iterator>
173 struct insert_copy_proxy
174 {
175    typedef boost::container::allocator_traits<Allocator> alloc_traits;
176    typedef typename alloc_traits::size_type size_type;
177    typedef typename alloc_traits::value_type value_type;
178 
179    static const bool single_value = true;
180 
insert_copy_proxyboost::container::dtl::insert_copy_proxy181    BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v)
182       :  v_(v)
183    {}
184 
uninitialized_copy_n_and_updateboost::container::dtl::insert_copy_proxy185    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
186    {
187       BOOST_ASSERT(n == 1);  (void)n;
188       alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_);
189    }
190 
copy_n_and_updateboost::container::dtl::insert_copy_proxy191    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const
192    {
193       BOOST_ASSERT(n == 1);  (void)n;
194       *p = v_;
195    }
196 
197    const value_type &v_;
198 };
199 
200 
201 template<class Allocator, class Iterator>
202 struct insert_move_proxy
203 {
204    typedef boost::container::allocator_traits<Allocator> alloc_traits;
205    typedef typename alloc_traits::size_type size_type;
206    typedef typename alloc_traits::value_type value_type;
207 
208    static const bool single_value = true;
209 
insert_move_proxyboost::container::dtl::insert_move_proxy210    BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v)
211       :  v_(v)
212    {}
213 
uninitialized_copy_n_and_updateboost::container::dtl::insert_move_proxy214    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
215    {
216       BOOST_ASSERT(n == 1);  (void)n;
217       alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) );
218    }
219 
copy_n_and_updateboost::container::dtl::insert_move_proxy220    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const
221    {
222       BOOST_ASSERT(n == 1);  (void)n;
223       *p = ::boost::move(v_);
224    }
225 
226    value_type &v_;
227 };
228 
229 template<class It, class Allocator>
get_insert_value_proxy(BOOST_RV_REF (typename boost::container::iterator_traits<It>::value_type)v)230 BOOST_CONTAINER_FORCEINLINE insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
231 {
232    return insert_move_proxy<Allocator, It>(v);
233 }
234 
235 template<class It, class Allocator>
get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type & v)236 BOOST_CONTAINER_FORCEINLINE insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
237 {
238    return insert_copy_proxy<Allocator, It>(v);
239 }
240 
241 }}}   //namespace boost { namespace container { namespace dtl {
242 
243 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
244 
245 #include <boost/container/detail/variadic_templates_tools.hpp>
246 #include <boost/move/utility_core.hpp>
247 
248 namespace boost {
249 namespace container {
250 namespace dtl {
251 
252 template<class Allocator, class Iterator, class ...Args>
253 struct insert_nonmovable_emplace_proxy
254 {
255    typedef boost::container::allocator_traits<Allocator>   alloc_traits;
256    typedef typename alloc_traits::size_type        size_type;
257    typedef typename alloc_traits::value_type       value_type;
258    typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
259 
260    static const bool single_value = true;
261 
insert_nonmovable_emplace_proxyboost::container::dtl::insert_nonmovable_emplace_proxy262    BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
263       : args_(args...)
264    {}
265 
uninitialized_copy_n_and_updateboost::container::dtl::insert_nonmovable_emplace_proxy266    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
267    {  this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n);  }
268 
269    private:
270    template<std::size_t ...IdxPack>
priv_uninitialized_copy_some_and_updateboost::container::dtl::insert_nonmovable_emplace_proxy271    BOOST_CONTAINER_FORCEINLINE void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
272    {
273       BOOST_ASSERT(n == 1); (void)n;
274       alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
275    }
276 
277    protected:
278    tuple<Args&...> args_;
279 };
280 
281 template<class Allocator, class Iterator, class ...Args>
282 struct insert_emplace_proxy
283    :  public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...>
284 {
285    typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
286    typedef boost::container::allocator_traits<Allocator>   alloc_traits;
287    typedef typename base_t::value_type             value_type;
288    typedef typename base_t::size_type              size_type;
289    typedef typename base_t::index_tuple_t          index_tuple_t;
290 
291    static const bool single_value = true;
292 
insert_emplace_proxyboost::container::dtl::insert_emplace_proxy293    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
294       : base_t(::boost::forward<Args>(args)...)
295    {}
296 
copy_n_and_updateboost::container::dtl::insert_emplace_proxy297    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n)
298    {  this->priv_copy_some_and_update(a, index_tuple_t(), p, n);  }
299 
300    private:
301 
302    template<std::size_t ...IdxPack>
priv_copy_some_and_updateboost::container::dtl::insert_emplace_proxy303    BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
304    {
305       BOOST_ASSERT(n ==1); (void)n;
306       typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
307       value_type *vp = reinterpret_cast<value_type *>(v.data);
308       alloc_traits::construct(a, vp, ::boost::forward<Args>(get<IdxPack>(this->args_))...);
309       BOOST_TRY{
310          *p = ::boost::move(*vp);
311       }
312       BOOST_CATCH(...){
313          alloc_traits::destroy(a, vp);
314          BOOST_RETHROW
315       }
316       BOOST_CATCH_END
317       alloc_traits::destroy(a, vp);
318    }
319 };
320 
321 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
322 template<class Allocator, class Iterator>
323 struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
324    : public insert_move_proxy<Allocator, Iterator>
325 {
326    static const bool single_value = true;
327 
insert_emplace_proxyboost::container::dtl::insert_emplace_proxy328    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
329    : insert_move_proxy<Allocator, Iterator>(v)
330    {}
331 };
332 
333 //We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
334 //compiler error C2752 ("more than one partial specialization matches").
335 //Any problem is solvable with an extra layer of indirection? ;-)
336 template<class Allocator, class Iterator>
337 struct insert_emplace_proxy<Allocator, Iterator
338    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
339    >
340    : public insert_copy_proxy<Allocator, Iterator>
341 {
342 
343    static const bool single_value = true;
344 
insert_emplace_proxyboost::container::dtl::insert_emplace_proxy345    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
346    : insert_copy_proxy<Allocator, Iterator>(v)
347    {}
348 };
349 
350 template<class Allocator, class Iterator>
351 struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
352    : public insert_copy_proxy<Allocator, Iterator>
353 {
354    static const bool single_value = true;
355 
insert_emplace_proxyboost::container::dtl::insert_emplace_proxy356    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
357    : insert_copy_proxy<Allocator, Iterator>(v)
358    {}
359 };
360 
361 template<class Allocator, class Iterator>
362 struct insert_emplace_proxy<Allocator, Iterator
363    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
364    >
365    : public insert_copy_proxy<Allocator, Iterator>
366 {
367    static const bool single_value = true;
368 
insert_emplace_proxyboost::container::dtl::insert_emplace_proxy369    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
370    : insert_copy_proxy<Allocator, Iterator>(v)
371    {}
372 };
373 
374 }}}   //namespace boost { namespace container { namespace dtl {
375 
376 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
377 
378 #include <boost/container/detail/value_init.hpp>
379 
380 namespace boost {
381 namespace container {
382 namespace dtl {
383 
384 #define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
385 template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
386 struct insert_nonmovable_emplace_proxy##N\
387 {\
388    typedef boost::container::allocator_traits<Allocator> alloc_traits;\
389    typedef typename alloc_traits::size_type size_type;\
390    typedef typename alloc_traits::value_type value_type;\
391    \
392    static const bool single_value = true;\
393    \
394    BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
395       BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
396    \
397    BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
398    {\
399       BOOST_ASSERT(n == 1); (void)n;\
400       alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
401    }\
402    \
403    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator, size_type)\
404    {  BOOST_ASSERT(false);   }\
405    \
406    protected:\
407    BOOST_MOVE_MREF##N\
408 };\
409 \
410 template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
411 struct insert_emplace_proxy_arg##N\
412    : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
413 {\
414    typedef insert_nonmovable_emplace_proxy##N\
415       < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
416    typedef typename base_t::value_type value_type;\
417    typedef typename base_t::size_type size_type;\
418    typedef boost::container::allocator_traits<Allocator> alloc_traits;\
419    \
420    static const bool single_value = true;\
421    \
422    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
423       : base_t(BOOST_MOVE_FWD##N){}\
424    \
425    BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
426    {\
427       BOOST_ASSERT(n == 1); (void)n;\
428       typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\
429       value_type *vp = reinterpret_cast<value_type *>(v.data);\
430       alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
431       BOOST_TRY{\
432          *p = ::boost::move(*vp);\
433       }\
434       BOOST_CATCH(...){\
435          alloc_traits::destroy(a, vp);\
436          BOOST_RETHROW\
437       }\
438       BOOST_CATCH_END\
439       alloc_traits::destroy(a, vp);\
440    }\
441 };\
442 //
443 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
444 #undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
445 
446 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
447 
448 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
449 template<class Allocator, class Iterator>
450 struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
451    : public insert_move_proxy<Allocator, Iterator>
452 {
453    static const bool single_value = true;
454 
insert_emplace_proxy_arg1boost::container::dtl::insert_emplace_proxy_arg1455    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
456    : insert_move_proxy<Allocator, Iterator>(v)
457    {}
458 };
459 
460 template<class Allocator, class Iterator>
461 struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
462    : public insert_copy_proxy<Allocator, Iterator>
463 {
464    static const bool single_value = true;
465 
insert_emplace_proxy_arg1boost::container::dtl::insert_emplace_proxy_arg1466    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
467    : insert_copy_proxy<Allocator, Iterator>(v)
468    {}
469 };
470 
471 #else //e.g. MSVC10 & MSVC11
472 
473 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
474 template<class Allocator, class Iterator>
475 struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
476    : public insert_move_proxy<Allocator, Iterator>
477 {
478    static const bool single_value = true;
479 
480    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
481    : insert_move_proxy<Allocator, Iterator>(v)
482    {}
483 };
484 
485 //We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
486 //compiler error C2752 ("more than one partial specialization matches").
487 //Any problem is solvable with an extra layer of indirection? ;-)
488 template<class Allocator, class Iterator>
489 struct insert_emplace_proxy_arg1<Allocator, Iterator
490    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
491    >
492    : public insert_copy_proxy<Allocator, Iterator>
493 {
494    static const bool single_value = true;
495 
496    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
497    : insert_copy_proxy<Allocator, Iterator>(v)
498    {}
499 };
500 
501 template<class Allocator, class Iterator>
502 struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
503    : public insert_copy_proxy<Allocator, Iterator>
504 {
505    static const bool single_value = true;
506 
507    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
508    : insert_copy_proxy<Allocator, Iterator>(v)
509    {}
510 };
511 
512 template<class Allocator, class Iterator>
513 struct insert_emplace_proxy_arg1<Allocator, Iterator
514    , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
515    >
516    : public insert_copy_proxy<Allocator, Iterator>
517 {
518    static const bool single_value = true;
519 
520    BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
521    : insert_copy_proxy<Allocator, Iterator>(v)
522    {}
523 };
524 
525 #endif
526 
527 }}}   //namespace boost { namespace container { namespace dtl {
528 
529 #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
530 
531 namespace boost { namespace container { namespace dtl {
532 
533 template <class T>
534 struct has_single_value
535 {
536    private:
537    struct two {char array_[2];};
538    template<bool Arg> struct wrapper;
539    template <class U> static two test(int, ...);
540    template <class U> static char test(int, const wrapper<U::single_value>*);
541    public:
542    static const bool value = sizeof(test<T>(0, 0)) == 1;
dummyboost::container::dtl::has_single_value543    void dummy(){}
544 };
545 
546 template<class InsertionProxy, bool = has_single_value<InsertionProxy>::value>
547 struct is_single_value_proxy_impl
548 {
549    static const bool value = InsertionProxy::single_value;
550 };
551 
552 template<class InsertionProxy>
553 struct is_single_value_proxy_impl<InsertionProxy, false>
554 {
555    static const bool value = false;
556 };
557 
558 template<class InsertionProxy>
559 struct is_single_value_proxy
560    : is_single_value_proxy_impl<InsertionProxy>
561 {};
562 
563 }}}   //namespace boost { namespace container { namespace dtl {
564 
565 #include <boost/container/detail/config_end.hpp>
566 
567 #endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
568