Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:19

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Pablo Halpern 2009. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 //////////////////////////////////////////////////////////////////////////////
0008 //
0009 // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
0010 // Software License, Version 1.0. (See accompanying file
0011 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0012 //
0013 // See http://www.boost.org/libs/container for documentation.
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 }  //namespace dtl {
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 //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0260 
0261 //Let's add a dummy first template parameter to allow creating
0262 //specializations up to maximum InnerAlloc count
0263 template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
0264 class scoped_allocator_adaptor_base;
0265 
0266 //Specializations for the adaptor with InnerAlloc allocators
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   //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
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 //Specialization for adaptor without any InnerAlloc
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          //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
0516          //as inner_allocator() is equal to *this and that would trigger an infinite loop
0517          , this->inner_allocator()
0518          );
0519    }
0520 };
0521 
0522 }  //namespace dtl {
0523 
0524 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0525 
0526 //Scoped allocator
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 //! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
0532 //! The class template scoped_allocator_adaptor is an allocator template that specifies
0533 //! the memory resource (the outer allocator) to be used by a container (as any other
0534 //! allocator does) and also specifies an inner allocator resource to be passed to
0535 //! the constructor of every element within the container.
0536 //!
0537 //! This adaptor is
0538 //! instantiated with one outer and zero or more inner allocator types. If
0539 //! instantiated with only one allocator type, the inner allocator becomes the
0540 //! scoped_allocator_adaptor itself, thus using the same allocator resource for the
0541 //! container and every element within the container and, if the elements themselves
0542 //! are containers, each of their elements recursively. If instantiated with more than
0543 //! one allocator, the first allocator is the outer allocator for use by the container,
0544 //! the second allocator is passed to the constructors of the container's elements,
0545 //! and, if the elements themselves are containers, the third allocator is passed to
0546 //! the elements' elements, and so on. If containers are nested to a depth greater
0547 //! than the number of allocators, the last allocator is used repeatedly, as in the
0548 //! single-allocator case, for any remaining recursions.
0549 //!
0550 //! [<b>Note</b>: The
0551 //! scoped_allocator_adaptor is derived from the outer allocator type so it can be
0552 //! substituted for the outer allocator type in most expressions. -end note]
0553 //!
0554 //! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
0555 //! an <code>outer_allocator()</code> member function and
0556 //! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
0557 //! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
0558 //!
0559 //! [<b>Note</b>: <code>OUTERMOST(x)</code> and
0560 //! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
0561 //! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
0562 //! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
0563 template <typename OuterAlloc, typename ...InnerAllocs>
0564 class scoped_allocator_adaptor
0565 
0566 #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
0567 
0568 template <typename OuterAlloc, typename ...InnerAllocs>
0569 class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
0570 
0571 #endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
0572 
0573 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
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   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0590    typedef OuterAlloc                                       outer_allocator_type;
0591    //! Type: For exposition only
0592    //!
0593    typedef allocator_traits<OuterAlloc>                     outer_traits_type;
0594    //! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
0595    //! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
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    //! Type: A type with a constant boolean <code>value</code> == true if
0606    //!`allocator_traits<Allocator>:: propagate_on_container_copy_assignment::value` is
0607    //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
0608    typedef typename base_type::
0609       propagate_on_container_copy_assignment                propagate_on_container_copy_assignment;
0610    //! Type: A type with a constant boolean <code>value</code> == true if
0611    //!`allocator_traits<Allocator>:: propagate_on_container_move_assignment::value` is
0612    //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
0613    typedef typename base_type::
0614       propagate_on_container_move_assignment                propagate_on_container_move_assignment;
0615 
0616    //! Type: A type with a constant boolean <code>value</code> == true if
0617    //! `allocator_traits<Allocator>:: propagate_on_container_swap::value` is
0618    //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
0619    typedef typename base_type::
0620       propagate_on_container_swap                           propagate_on_container_swap;
0621 
0622    //! Type: A type with a constant boolean <code>value</code> == true if
0623    //!`allocator_traits<Allocator>:: is_always_equal::value` is
0624    //! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
0625    typedef typename base_type::
0626       is_always_equal                           is_always_equal;
0627 
0628    //! Type: Rebinds scoped allocator to
0629    //!    <code>typedef scoped_allocator_adaptor
0630    //!      < typename outer_traits_type::template portable_rebind_alloc<U>::type
0631    //!      , InnerAllocs... ></code>
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    //! <b>Effects</b>: value-initializes the OuterAlloc base class
0641    //! and the inner allocator object.
0642    BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor()
0643       {}
0644 
0645    BOOST_CONTAINER_FORCEINLINE ~scoped_allocator_adaptor()
0646       {}
0647 
0648    //! <b>Effects</b>: initializes each allocator within the adaptor with
0649    //! the corresponding allocator from other.
0650    BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
0651       : base_type(other.base())
0652       {}
0653 
0654    //! <b>Effects</b>: move constructs each allocator within the adaptor with
0655    //! the corresponding allocator from other.
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    //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
0663    //!
0664    //! <b>Effects</b>: initializes the OuterAlloc base class with boost::forward<OuterA2>(outerAlloc) and inner
0665    //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the
0666    //! corresponding allocator from the argument list).
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 // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
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   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0683 
0684    //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
0685    //!
0686    //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
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    //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
0693    //!
0694    //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator
0695    //! rvalue from other.
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    //! <b>Effects</b>: swaps *this with r.
0710    //!
0711    void swap(scoped_allocator_adaptor &r);
0712 
0713    //! <b>Effects</b>: swaps *this with r.
0714    //!
0715    friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
0716 
0717    //! <b>Returns</b>:
0718    //!   <code>static_cast<OuterAlloc&>(*this)</code>.
0719    outer_allocator_type      & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
0720 
0721    //! <b>Returns</b>:
0722    //!   <code>static_cast<const OuterAlloc&>(*this)</code>.
0723    const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
0724 
0725    //! <b>Returns</b>:
0726    //!   *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
0727    inner_allocator_type&       inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
0728 
0729    //! <b>Returns</b>:
0730    //!   *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
0731    inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
0732 
0733    #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
0734 
0735    //! <b>Returns</b>:
0736    //!   <code>allocator_traits<OuterAlloc>:: max_size(outer_allocator())</code>.
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    //! <b>Effects</b>:
0741    //!   calls <code>OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p)</code>.
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    //! <b>Returns</b>:
0750    //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
0751    BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n)
0752    {  return outer_traits_type::allocate(this->outer_allocator(), n);   }
0753 
0754    //! <b>Returns</b>:
0755    //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
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    //! <b>Effects</b>:
0760    //! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
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    //! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator
0766    //! Allocator in the adaptor is initialized from the result of calling
0767    //! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
0768    //! the corresponding allocator in *this.
0769    scoped_allocator_adaptor select_on_container_copy_construction() const;
0770    #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
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   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0777 
0778    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0779 
0780    //! <b>Effects</b>:
0781    //! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
0782    //!    <code>OUTERMOST_ALLOC_TRAITS(*this)::
0783    //!       construct(OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
0784    //!
0785    //! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
0786    //!    <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>:: value</code> is true, calls
0787    //!    <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, allocator_arg,
0788    //!    inner_allocator(), std::forward<Args>(args)...)</code>.
0789    //!
0790    //! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
0791    //! be implemented so that condition will be replaced by
0792    //! constructible_with_allocator_prefix<T>::value. -end note]
0793    //!
0794    //! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
0795    //!    <code>is_constructible<T, Args..., inner_allocator_type>:: value</code> is true, calls
0796    //!    <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p,
0797    //!    std::forward<Args>(args)..., inner_allocator())</code>.
0798    //!
0799    //! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
0800    //! implemented so that condition will be replaced by
0801    //! <code>constructible_with_allocator_suffix<T>:: value</code>. -end note]
0802    //!
0803    //! 4) Otherwise, the program is ill-formed.
0804    //!
0805    //! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
0806    //! to true but the specific constructor does not take an allocator. This definition prevents a silent
0807    //! failure to pass an inner allocator to a contained element. -end note]
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 // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0817 
0818    //Disable this overload if the first argument is pair as some compilers have
0819    //overload selection problems when the first parameter is a pair.
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   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0833 
0834    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0835 
0836    public:
0837    //Internal function
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   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0844 };
0845 
0846 /// @cond
0847 
0848 template<bool ZeroInner>
0849 struct scoped_allocator_operator_equal
0850 {
0851    //Optimize equal outer allocator types with 
0852    //allocator_traits::equal which uses is_always_equal
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    //Otherwise compare it normally
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    //Otherwise compare it normally
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    //when inner allocator count is zero,
0873    //inner_allocator_type is the same as outer_allocator_type
0874    //so both types can be different in operator==
0875    template<class IA1, class IA2>
0876    BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA1 &, const IA2 &)
0877    {  return true;  }
0878 };
0879 
0880 /// @endcond
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 }} // namespace boost { namespace container {
0902 
0903 #include <boost/container/detail/config_end.hpp>
0904 
0905 #endif //  BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP