File indexing completed on 2025-01-18 09:30:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
0018 #define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
0019
0020 #if defined (_MSC_VER)
0021 # pragma once
0022 #endif
0023
0024 #include <boost/container/detail/config_begin.hpp>
0025 #include <boost/container/detail/workaround.hpp>
0026
0027 #include <boost/container/allocator_traits.hpp>
0028 #include <boost/container/scoped_allocator_fwd.hpp>
0029 #include <boost/container/detail/dispatch_uses_allocator.hpp>
0030
0031 #include <boost/container/detail/mpl.hpp>
0032 #include <boost/container/detail/pair.hpp>
0033 #include <boost/container/detail/type_traits.hpp>
0034
0035 #include <boost/move/adl_move_swap.hpp>
0036 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0037 #include <boost/move/detail/fwd_macros.hpp>
0038 #endif
0039 #include <boost/move/utility_core.hpp>
0040
0041 namespace boost { namespace container {
0042
0043 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0044
0045 namespace dtl {
0046
0047 template <typename Allocator>
0048 struct is_scoped_allocator_imp
0049 {
0050 typedef char yes_type;
0051 struct no_type{ char dummy[2]; };
0052
0053 template <typename T>
0054 static yes_type test(typename T::outer_allocator_type*);
0055
0056 template <typename T>
0057 static int test(...);
0058
0059 static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0)));
0060 };
0061
0062 template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
0063 struct outermost_allocator_type_impl
0064 {
0065 typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
0066 typedef typename outermost_allocator_type_impl<outer_type>::type type;
0067 };
0068
0069 template<class MaybeScopedAlloc>
0070 struct outermost_allocator_type_impl<MaybeScopedAlloc, false>
0071 {
0072 typedef MaybeScopedAlloc type;
0073 };
0074
0075 template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
0076 struct outermost_allocator_imp
0077 {
0078 typedef MaybeScopedAlloc type;
0079
0080 BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a)
0081 { return a; }
0082
0083 BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a)
0084 { return a; }
0085 };
0086
0087 template<class MaybeScopedAlloc>
0088 struct outermost_allocator_imp<MaybeScopedAlloc, true>
0089 {
0090 typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
0091 typedef typename outermost_allocator_type_impl<outer_type>::type type;
0092
0093 BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a)
0094 { return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
0095
0096 BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a)
0097 { return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
0098 };
0099
0100 }
0101
0102 template <typename Allocator>
0103 struct is_scoped_allocator
0104 : dtl::is_scoped_allocator_imp<Allocator>
0105 {};
0106
0107 template <typename Allocator>
0108 struct outermost_allocator
0109 : dtl::outermost_allocator_imp<Allocator>
0110 {};
0111
0112 template <typename Allocator>
0113 BOOST_CONTAINER_FORCEINLINE typename outermost_allocator<Allocator>::type &
0114 get_outermost_allocator(Allocator &a)
0115 { return outermost_allocator<Allocator>::get(a); }
0116
0117 template <typename Allocator>
0118 BOOST_CONTAINER_FORCEINLINE const typename outermost_allocator<Allocator>::type &
0119 get_outermost_allocator(const Allocator &a)
0120 { return outermost_allocator<Allocator>::get(a); }
0121
0122 namespace dtl {
0123
0124 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0125
0126 template <typename OuterAlloc, class ...InnerAllocs>
0127 class scoped_allocator_adaptor_base
0128 : public OuterAlloc
0129 {
0130 typedef allocator_traits<OuterAlloc> outer_traits_type;
0131 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
0132
0133 public:
0134 template <class OuterA2>
0135 struct rebind_base
0136 {
0137 typedef scoped_allocator_adaptor_base<OuterA2, InnerAllocs...> other;
0138 };
0139
0140 typedef OuterAlloc outer_allocator_type;
0141 typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
0142 typedef allocator_traits<inner_allocator_type> inner_traits_type;
0143 typedef scoped_allocator_adaptor
0144 <OuterAlloc, InnerAllocs...> scoped_allocator_type;
0145 typedef dtl::bool_<
0146 outer_traits_type::propagate_on_container_copy_assignment::value ||
0147 inner_allocator_type::propagate_on_container_copy_assignment::value
0148 > propagate_on_container_copy_assignment;
0149 typedef dtl::bool_<
0150 outer_traits_type::propagate_on_container_move_assignment::value ||
0151 inner_allocator_type::propagate_on_container_move_assignment::value
0152 > propagate_on_container_move_assignment;
0153 typedef dtl::bool_<
0154 outer_traits_type::propagate_on_container_swap::value ||
0155 inner_allocator_type::propagate_on_container_swap::value
0156 > propagate_on_container_swap;
0157 typedef dtl::bool_<
0158 outer_traits_type::is_always_equal::value &&
0159 inner_allocator_type::is_always_equal::value
0160 > is_always_equal;
0161
0162 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base()
0163 {}
0164
0165 template <class OuterA2>
0166 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
0167 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
0168 , m_inner(args...)
0169 {}
0170
0171 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
0172 : outer_allocator_type(other.outer_allocator())
0173 , m_inner(other.inner_allocator())
0174 {}
0175
0176 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
0177 : outer_allocator_type(::boost::move(other.outer_allocator()))
0178 , m_inner(::boost::move(other.inner_allocator()))
0179 {}
0180
0181 template <class OuterA2>
0182 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
0183 (const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
0184 : outer_allocator_type(other.outer_allocator())
0185 , m_inner(other.inner_allocator())
0186 {}
0187
0188 template <class OuterA2>
0189 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
0190 (BOOST_RV_REF_BEG scoped_allocator_adaptor_base
0191 <OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
0192 : outer_allocator_type(other.outer_allocator())
0193 , m_inner(other.inner_allocator())
0194 {}
0195
0196 public:
0197 struct internal_type_t{};
0198
0199 template <class OuterA2>
0200 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
0201 ( internal_type_t
0202 , BOOST_FWD_REF(OuterA2) outerAlloc
0203 , const inner_allocator_type &inner)
0204 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
0205 , m_inner(inner)
0206 {}
0207
0208 public:
0209
0210 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=
0211 (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
0212 {
0213 outer_allocator_type::operator=(other.outer_allocator());
0214 m_inner = other.inner_allocator();
0215 return *this;
0216 }
0217
0218 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
0219 {
0220 outer_allocator_type::operator=(boost::move(other.outer_allocator()));
0221 m_inner = ::boost::move(other.inner_allocator());
0222 return *this;
0223 }
0224
0225 BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r)
0226 {
0227 boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
0228 boost::adl_move_swap(this->m_inner, r.inner_allocator());
0229 }
0230
0231 BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
0232 { l.swap(r); }
0233
0234 BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
0235 { return m_inner; }
0236
0237 BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0238 { return m_inner; }
0239
0240 BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
0241 { return static_cast<outer_allocator_type&>(*this); }
0242
0243 BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0244 { return static_cast<const outer_allocator_type&>(*this); }
0245
0246 BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const
0247 {
0248 return scoped_allocator_type
0249 (internal_type_t()
0250 ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
0251 ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
0252 );
0253 }
0254
0255 private:
0256 inner_allocator_type m_inner;
0257 };
0258
0259 #else
0260
0261
0262
0263 template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
0264 class scoped_allocator_adaptor_base;
0265
0266
0267
0268 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\
0269 template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
0270 class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
0271 : public OuterAlloc\
0272 {\
0273 typedef allocator_traits<OuterAlloc> outer_traits_type;\
0274 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\
0275 \
0276 public:\
0277 template <class OuterA2>\
0278 struct rebind_base\
0279 {\
0280 typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\
0281 };\
0282 \
0283 typedef OuterAlloc outer_allocator_type;\
0284 typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\
0285 typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\
0286 typedef allocator_traits<inner_allocator_type> inner_traits_type;\
0287 typedef dtl::bool_<\
0288 outer_traits_type::propagate_on_container_copy_assignment::value ||\
0289 inner_allocator_type::propagate_on_container_copy_assignment::value\
0290 > propagate_on_container_copy_assignment;\
0291 typedef dtl::bool_<\
0292 outer_traits_type::propagate_on_container_move_assignment::value ||\
0293 inner_allocator_type::propagate_on_container_move_assignment::value\
0294 > propagate_on_container_move_assignment;\
0295 typedef dtl::bool_<\
0296 outer_traits_type::propagate_on_container_swap::value ||\
0297 inner_allocator_type::propagate_on_container_swap::value\
0298 > propagate_on_container_swap;\
0299 \
0300 typedef dtl::bool_<\
0301 outer_traits_type::is_always_equal::value &&\
0302 inner_allocator_type::is_always_equal::value\
0303 > is_always_equal;\
0304 \
0305 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(){}\
0306 \
0307 template <class OuterA2>\
0308 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
0309 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
0310 , m_inner(BOOST_MOVE_ARG##N)\
0311 {}\
0312 \
0313 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\
0314 : outer_allocator_type(other.outer_allocator())\
0315 , m_inner(other.inner_allocator())\
0316 {}\
0317 \
0318 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
0319 : outer_allocator_type(::boost::move(other.outer_allocator()))\
0320 , m_inner(::boost::move(other.inner_allocator()))\
0321 {}\
0322 \
0323 template <class OuterA2>\
0324 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\
0325 (const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\
0326 : outer_allocator_type(other.outer_allocator())\
0327 , m_inner(other.inner_allocator())\
0328 {}\
0329 \
0330 template <class OuterA2>\
0331 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\
0332 (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\
0333 : outer_allocator_type(other.outer_allocator())\
0334 , m_inner(other.inner_allocator())\
0335 {}\
0336 \
0337 public:\
0338 struct internal_type_t{};\
0339 \
0340 template <class OuterA2>\
0341 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\
0342 ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\
0343 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
0344 , m_inner(inner)\
0345 {}\
0346 \
0347 public:\
0348 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=\
0349 (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
0350 {\
0351 outer_allocator_type::operator=(other.outer_allocator());\
0352 m_inner = other.inner_allocator();\
0353 return *this;\
0354 }\
0355 \
0356 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
0357 {\
0358 outer_allocator_type::operator=(boost::move(other.outer_allocator()));\
0359 m_inner = ::boost::move(other.inner_allocator());\
0360 return *this;\
0361 }\
0362 \
0363 BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r)\
0364 {\
0365 boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\
0366 boost::adl_move_swap(this->m_inner, r.inner_allocator());\
0367 }\
0368 \
0369 BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
0370 { l.swap(r); }\
0371 \
0372 BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator()\
0373 { return m_inner; }\
0374 \
0375 BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const\
0376 { return m_inner; }\
0377 \
0378 BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator()\
0379 { return static_cast<outer_allocator_type&>(*this); }\
0380 \
0381 BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const\
0382 { return static_cast<const outer_allocator_type&>(*this); }\
0383 \
0384 BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const\
0385 {\
0386 return scoped_allocator_type\
0387 (internal_type_t()\
0388 ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\
0389 ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\
0390 );\
0391 }\
0392 private:\
0393 inner_allocator_type m_inner;\
0394 };\
0395
0396 BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE)
0397 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE
0398
0399 #endif
0400
0401 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0402 #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true
0403 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9
0404 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9
0405 #else
0406 #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE
0407 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs...
0408 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs
0409 #endif
0410
0411
0412 template <typename OuterAlloc>
0413 class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>
0414 : public OuterAlloc
0415 {
0416 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
0417 public:
0418
0419 template <class U>
0420 struct rebind_base
0421 {
0422 typedef scoped_allocator_adaptor_base
0423 <typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
0424 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other;
0425 };
0426
0427 typedef OuterAlloc outer_allocator_type;
0428 typedef allocator_traits<OuterAlloc> outer_traits_type;
0429 typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
0430 typedef inner_allocator_type scoped_allocator_type;
0431 typedef allocator_traits<inner_allocator_type> inner_traits_type;
0432 typedef typename outer_traits_type::
0433 propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
0434 typedef typename outer_traits_type::
0435 propagate_on_container_move_assignment propagate_on_container_move_assignment;
0436 typedef typename outer_traits_type::
0437 propagate_on_container_swap propagate_on_container_swap;
0438 typedef typename outer_traits_type::
0439 is_always_equal is_always_equal;
0440
0441 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base()
0442 {}
0443
0444 template <class OuterA2>
0445 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
0446 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
0447 {}
0448
0449 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
0450 : outer_allocator_type(other.outer_allocator())
0451 {}
0452
0453 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
0454 : outer_allocator_type(::boost::move(other.outer_allocator()))
0455 {}
0456
0457 template <class OuterA2>
0458 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
0459 (const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other)
0460 : outer_allocator_type(other.outer_allocator())
0461 {}
0462
0463 template <class OuterA2>
0464 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
0465 (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
0466 : outer_allocator_type(other.outer_allocator())
0467 {}
0468
0469 public:
0470 struct internal_type_t{};
0471
0472 template <class OuterA2>
0473 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
0474 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
0475 {}
0476
0477 public:
0478 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
0479 {
0480 outer_allocator_type::operator=(other.outer_allocator());
0481 return *this;
0482 }
0483
0484 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
0485 {
0486 outer_allocator_type::operator=(boost::move(other.outer_allocator()));
0487 return *this;
0488 }
0489
0490 BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r)
0491 {
0492 boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
0493 }
0494
0495 BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
0496 { l.swap(r); }
0497
0498 BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator()
0499 { return static_cast<inner_allocator_type&>(*this); }
0500
0501 BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const
0502 { return static_cast<const inner_allocator_type&>(*this); }
0503
0504 BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator()
0505 { return static_cast<outer_allocator_type&>(*this); }
0506
0507 BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const
0508 { return static_cast<const outer_allocator_type&>(*this); }
0509
0510 BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const
0511 {
0512 return scoped_allocator_type
0513 (internal_type_t()
0514 ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
0515
0516
0517 , this->inner_allocator()
0518 );
0519 }
0520 };
0521
0522 }
0523
0524 #endif
0525
0526
0527 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0528
0529 #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563 template <typename OuterAlloc, typename ...InnerAllocs>
0564 class scoped_allocator_adaptor
0565
0566 #else
0567
0568 template <typename OuterAlloc, typename ...InnerAllocs>
0569 class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
0570
0571 #endif
0572
0573 #else
0574
0575 template <typename OuterAlloc, BOOST_MOVE_CLASS9>
0576 class scoped_allocator_adaptor
0577 #endif
0578
0579 : public dtl::scoped_allocator_adaptor_base
0580 <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
0581 {
0582 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
0583
0584 public:
0585 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0586 typedef dtl::scoped_allocator_adaptor_base
0587 <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type;
0588 typedef typename base_type::internal_type_t internal_type_t;
0589 #endif
0590 typedef OuterAlloc outer_allocator_type;
0591
0592
0593 typedef allocator_traits<OuterAlloc> outer_traits_type;
0594
0595
0596 typedef typename base_type::inner_allocator_type inner_allocator_type;
0597 typedef allocator_traits<inner_allocator_type> inner_traits_type;
0598 typedef typename outer_traits_type::value_type value_type;
0599 typedef typename outer_traits_type::size_type size_type;
0600 typedef typename outer_traits_type::difference_type difference_type;
0601 typedef typename outer_traits_type::pointer pointer;
0602 typedef typename outer_traits_type::const_pointer const_pointer;
0603 typedef typename outer_traits_type::void_pointer void_pointer;
0604 typedef typename outer_traits_type::const_void_pointer const_void_pointer;
0605
0606
0607
0608 typedef typename base_type::
0609 propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
0610
0611
0612
0613 typedef typename base_type::
0614 propagate_on_container_move_assignment propagate_on_container_move_assignment;
0615
0616
0617
0618
0619 typedef typename base_type::
0620 propagate_on_container_swap propagate_on_container_swap;
0621
0622
0623
0624
0625 typedef typename base_type::
0626 is_always_equal is_always_equal;
0627
0628
0629
0630
0631
0632 template <class U>
0633 struct rebind
0634 {
0635 typedef scoped_allocator_adaptor
0636 < typename outer_traits_type::template portable_rebind_alloc<U>::type
0637 , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other;
0638 };
0639
0640
0641
0642 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor()
0643 {}
0644
0645 BOOST_CONTAINER_FORCEINLINE ~scoped_allocator_adaptor()
0646 {}
0647
0648
0649
0650 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
0651 : base_type(other.base())
0652 {}
0653
0654
0655
0656 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
0657 : base_type(::boost::move(other.base()))
0658 {}
0659
0660 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0661
0662
0663
0664
0665
0666
0667 template <class OuterA2>
0668 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
0669 : base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
0670 {}
0671 #else
0672
0673 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\
0674 template <class OuterA2>\
0675 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\
0676 : base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\
0677 {}\
0678
0679 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE)
0680 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE
0681
0682 #endif
0683
0684
0685
0686
0687 template <class OuterA2>
0688 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
0689 : base_type(other.base())
0690 {}
0691
0692
0693
0694
0695
0696 template <class OuterA2>
0697 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor
0698 <OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other)
0699 : base_type(::boost::move(other.base()))
0700 {}
0701
0702 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
0703 { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
0704
0705 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
0706 { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
0707
0708 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0709
0710
0711 void swap(scoped_allocator_adaptor &r);
0712
0713
0714
0715 friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
0716
0717
0718
0719 outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
0720
0721
0722
0723 const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
0724
0725
0726
0727 inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
0728
0729
0730
0731 inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
0732
0733 #endif
0734
0735
0736
0737 BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
0738 { return outer_traits_type::max_size(this->outer_allocator()); }
0739
0740
0741
0742 template <class T>
0743 BOOST_CONTAINER_FORCEINLINE void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
0744 {
0745 allocator_traits<typename outermost_allocator<OuterAlloc>::type>
0746 ::destroy(get_outermost_allocator(this->outer_allocator()), p);
0747 }
0748
0749
0750
0751 BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n)
0752 { return outer_traits_type::allocate(this->outer_allocator(), n); }
0753
0754
0755
0756 BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n, const_void_pointer hint)
0757 { return outer_traits_type::allocate(this->outer_allocator(), n, hint); }
0758
0759
0760
0761 BOOST_CONTAINER_FORCEINLINE void deallocate(pointer p, size_type n)
0762 { outer_traits_type::deallocate(this->outer_allocator(), p, n); }
0763
0764 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0765
0766
0767
0768
0769 scoped_allocator_adaptor select_on_container_copy_construction() const;
0770 #endif
0771
0772 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0773 BOOST_CONTAINER_FORCEINLINE base_type &base() { return *this; }
0774
0775 BOOST_CONTAINER_FORCEINLINE const base_type &base() const { return *this; }
0776 #endif
0777
0778 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808 template < typename T, class ...Args>
0809 BOOST_CONTAINER_FORCEINLINE void construct(T* p, BOOST_FWD_REF(Args)...args)
0810 {
0811 dtl::dispatch_uses_allocator
0812 ( (get_outermost_allocator)(this->outer_allocator())
0813 , this->inner_allocator(), p, ::boost::forward<Args>(args)...);
0814 }
0815
0816 #else
0817
0818
0819
0820 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
0821 template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
0822 BOOST_CONTAINER_FORCEINLINE void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
0823 {\
0824 dtl::dispatch_uses_allocator\
0825 ( (get_outermost_allocator)(this->outer_allocator())\
0826 , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
0827 }\
0828
0829 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE)
0830 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE
0831
0832 #endif
0833
0834 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0835
0836 public:
0837
0838 template <class OuterA2>
0839 BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
0840 : base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
0841 {}
0842
0843 #endif
0844 };
0845
0846
0847
0848 template<bool ZeroInner>
0849 struct scoped_allocator_operator_equal
0850 {
0851
0852
0853 template<class IA>
0854 BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA &l, const IA &r)
0855 { return allocator_traits<IA>::equal(l, r); }
0856
0857
0858 template<class IA1, class IA2>
0859 BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA1 &l, const IA2 &r)
0860 { return l == r; }
0861
0862
0863 template<class IA>
0864 BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA &l, const IA &r)
0865 { return allocator_traits<IA>::equal(l, r); }
0866 };
0867
0868 template<>
0869 struct scoped_allocator_operator_equal<true>
0870 : scoped_allocator_operator_equal<false>
0871 {
0872
0873
0874
0875 template<class IA1, class IA2>
0876 BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA1 &, const IA2 &)
0877 { return true; }
0878 };
0879
0880
0881
0882 template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
0883 BOOST_CONTAINER_FORCEINLINE bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
0884 ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
0885 {
0886 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0887 const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
0888 #else
0889 const bool has_zero_inner = boost::container::dtl::is_same<P0, void>::value;
0890 #endif
0891 typedef scoped_allocator_operator_equal<has_zero_inner> equal_t;
0892 return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) &&
0893 equal_t::equal_inner(a.inner_allocator(), b.inner_allocator());
0894 }
0895
0896 template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
0897 BOOST_CONTAINER_FORCEINLINE bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
0898 ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
0899 { return !(a == b); }
0900
0901 }}
0902
0903 #include <boost/container/detail/config_end.hpp>
0904
0905 #endif