1*e4b17023SJohn Marino// <scoped_allocator> -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2011, 2012 Free Software Foundation, Inc. 4*e4b17023SJohn Marino// 5*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino// terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino// any later version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino// GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino/** @file include/scoped_allocator 26*e4b17023SJohn Marino * This is a Standard C++ Library header. 27*e4b17023SJohn Marino */ 28*e4b17023SJohn Marino 29*e4b17023SJohn Marino#ifndef _SCOPED_ALLOCATOR 30*e4b17023SJohn Marino#define _SCOPED_ALLOCATOR 1 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino#pragma GCC system_header 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 35*e4b17023SJohn Marino# include <bits/c++0x_warning.h> 36*e4b17023SJohn Marino#else 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#include <utility> 39*e4b17023SJohn Marino#include <tuple> 40*e4b17023SJohn Marino#include <bits/alloc_traits.h> 41*e4b17023SJohn Marino 42*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 43*e4b17023SJohn Marino{ 44*e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 45*e4b17023SJohn Marino 46*e4b17023SJohn Marino template<template<typename> class _Pred, typename... _Allocs> 47*e4b17023SJohn Marino struct __any_of; 48*e4b17023SJohn Marino 49*e4b17023SJohn Marino template<template<typename> class _Pred, typename _Alloc, typename... _Allocs> 50*e4b17023SJohn Marino struct __any_of<_Pred, _Alloc, _Allocs...> 51*e4b17023SJohn Marino : __or_<_Pred<_Alloc>, __any_of<_Pred, _Allocs...>> 52*e4b17023SJohn Marino { }; 53*e4b17023SJohn Marino 54*e4b17023SJohn Marino template<template<typename> class _Pred, typename _Alloc> 55*e4b17023SJohn Marino struct __any_of<_Pred, _Alloc> 56*e4b17023SJohn Marino : _Pred<_Alloc> 57*e4b17023SJohn Marino { }; 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino /** 60*e4b17023SJohn Marino * @addtogroup allocators 61*e4b17023SJohn Marino * @{ 62*e4b17023SJohn Marino */ 63*e4b17023SJohn Marino 64*e4b17023SJohn Marino template<typename _Alloc> 65*e4b17023SJohn Marino struct __propagate_on_copy 66*e4b17023SJohn Marino : allocator_traits<_Alloc>::propagate_on_container_copy_assignment 67*e4b17023SJohn Marino { }; 68*e4b17023SJohn Marino template<typename _Alloc> 69*e4b17023SJohn Marino struct __propagate_on_move 70*e4b17023SJohn Marino : allocator_traits<_Alloc>::propagate_on_container_move_assignment 71*e4b17023SJohn Marino { }; 72*e4b17023SJohn Marino template<typename _Alloc> 73*e4b17023SJohn Marino struct __propagate_on_swap 74*e4b17023SJohn Marino : allocator_traits<_Alloc>::propagate_on_container_swap 75*e4b17023SJohn Marino { }; 76*e4b17023SJohn Marino 77*e4b17023SJohn Marino 78*e4b17023SJohn Marino template<typename _Alloc> 79*e4b17023SJohn Marino inline auto 80*e4b17023SJohn Marino __do_outermost(_Alloc& __a, _Alloc*) -> decltype(__a.outer_allocator()) 81*e4b17023SJohn Marino { return __a.outer_allocator(); } 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino template<typename _Alloc> 84*e4b17023SJohn Marino inline _Alloc& 85*e4b17023SJohn Marino __do_outermost(_Alloc& __a, ...) 86*e4b17023SJohn Marino { return __a; } 87*e4b17023SJohn Marino 88*e4b17023SJohn Marino template<typename _Alloc> 89*e4b17023SJohn Marino inline auto 90*e4b17023SJohn Marino __outermost(_Alloc& __a) -> decltype(__do_outermost(__a, &__a)) 91*e4b17023SJohn Marino { return __do_outermost(__a, &__a); } 92*e4b17023SJohn Marino 93*e4b17023SJohn Marino template<typename _OuterAlloc, typename... _InnerAllocs> 94*e4b17023SJohn Marino class scoped_allocator_adaptor; 95*e4b17023SJohn Marino 96*e4b17023SJohn Marino template<typename...> 97*e4b17023SJohn Marino struct __inner_type_impl; 98*e4b17023SJohn Marino 99*e4b17023SJohn Marino template<typename _Outer> 100*e4b17023SJohn Marino struct __inner_type_impl<_Outer> 101*e4b17023SJohn Marino { 102*e4b17023SJohn Marino typedef scoped_allocator_adaptor<_Outer> __type; 103*e4b17023SJohn Marino 104*e4b17023SJohn Marino __inner_type_impl() = default; 105*e4b17023SJohn Marino __inner_type_impl(const __inner_type_impl&) = default; 106*e4b17023SJohn Marino __inner_type_impl(__inner_type_impl&&) = default; 107*e4b17023SJohn Marino 108*e4b17023SJohn Marino template<typename _Alloc> 109*e4b17023SJohn Marino __inner_type_impl(const __inner_type_impl<_Alloc>& __other) 110*e4b17023SJohn Marino { } 111*e4b17023SJohn Marino 112*e4b17023SJohn Marino template<typename _Alloc> 113*e4b17023SJohn Marino __inner_type_impl(__inner_type_impl<_Alloc>&& __other) 114*e4b17023SJohn Marino { } 115*e4b17023SJohn Marino 116*e4b17023SJohn Marino __type& 117*e4b17023SJohn Marino _M_get(__type* __p) noexcept { return *__p; } 118*e4b17023SJohn Marino 119*e4b17023SJohn Marino const __type& 120*e4b17023SJohn Marino _M_get(const __type* __p) const noexcept { return *__p; } 121*e4b17023SJohn Marino 122*e4b17023SJohn Marino tuple<> 123*e4b17023SJohn Marino _M_tie() const noexcept { return tuple<>(); } 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino bool 126*e4b17023SJohn Marino operator==(const __inner_type_impl&) const noexcept 127*e4b17023SJohn Marino { return true; } 128*e4b17023SJohn Marino }; 129*e4b17023SJohn Marino 130*e4b17023SJohn Marino template<typename _Outer, typename _InnerHead, typename... _InnerTail> 131*e4b17023SJohn Marino struct __inner_type_impl<_Outer, _InnerHead, _InnerTail...> 132*e4b17023SJohn Marino { 133*e4b17023SJohn Marino typedef scoped_allocator_adaptor<_InnerHead, _InnerTail...> __type; 134*e4b17023SJohn Marino 135*e4b17023SJohn Marino __inner_type_impl() = default; 136*e4b17023SJohn Marino __inner_type_impl(const __inner_type_impl&) = default; 137*e4b17023SJohn Marino __inner_type_impl(__inner_type_impl&&) = default; 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino template<typename... _Allocs> 140*e4b17023SJohn Marino __inner_type_impl(const __inner_type_impl<_Allocs...>& __other) 141*e4b17023SJohn Marino : _M_inner(__other._M_inner) { } 142*e4b17023SJohn Marino 143*e4b17023SJohn Marino template<typename... _Allocs> 144*e4b17023SJohn Marino __inner_type_impl(__inner_type_impl<_Allocs...>&& __other) 145*e4b17023SJohn Marino : _M_inner(std::move(__other._M_inner)) { } 146*e4b17023SJohn Marino 147*e4b17023SJohn Marino template<typename... _Args> 148*e4b17023SJohn Marino explicit 149*e4b17023SJohn Marino __inner_type_impl(_Args&&... __args) 150*e4b17023SJohn Marino : _M_inner(std::forward<_Args>(__args)...) { } 151*e4b17023SJohn Marino 152*e4b17023SJohn Marino __type& 153*e4b17023SJohn Marino _M_get(void*) noexcept { return _M_inner; } 154*e4b17023SJohn Marino 155*e4b17023SJohn Marino const __type& 156*e4b17023SJohn Marino _M_get(const void*) const noexcept { return _M_inner; } 157*e4b17023SJohn Marino 158*e4b17023SJohn Marino tuple<const _InnerHead&, const _InnerTail&...> 159*e4b17023SJohn Marino _M_tie() const noexcept 160*e4b17023SJohn Marino { return _M_inner._M_tie(); } 161*e4b17023SJohn Marino 162*e4b17023SJohn Marino bool 163*e4b17023SJohn Marino operator==(const __inner_type_impl& __other) const noexcept 164*e4b17023SJohn Marino { return _M_inner == __other._M_inner; } 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino private: 167*e4b17023SJohn Marino template<typename...> friend class __inner_type_impl; 168*e4b17023SJohn Marino template<typename, typename...> friend class scoped_allocator_adaptor; 169*e4b17023SJohn Marino 170*e4b17023SJohn Marino __type _M_inner; 171*e4b17023SJohn Marino }; 172*e4b17023SJohn Marino 173*e4b17023SJohn Marino /// Primary class template. 174*e4b17023SJohn Marino template<typename _OuterAlloc, typename... _InnerAllocs> 175*e4b17023SJohn Marino class scoped_allocator_adaptor 176*e4b17023SJohn Marino : public _OuterAlloc 177*e4b17023SJohn Marino { 178*e4b17023SJohn Marino typedef allocator_traits<_OuterAlloc> __traits; 179*e4b17023SJohn Marino 180*e4b17023SJohn Marino typedef __inner_type_impl<_OuterAlloc, _InnerAllocs...> __inner_type; 181*e4b17023SJohn Marino __inner_type _M_inner; 182*e4b17023SJohn Marino 183*e4b17023SJohn Marino template<typename _Outer, typename... _Inner> 184*e4b17023SJohn Marino friend class scoped_allocator_adaptor; 185*e4b17023SJohn Marino 186*e4b17023SJohn Marino template<typename...> 187*e4b17023SJohn Marino friend class __inner_type_impl; 188*e4b17023SJohn Marino 189*e4b17023SJohn Marino tuple<const _OuterAlloc&, const _InnerAllocs&...> 190*e4b17023SJohn Marino _M_tie() const noexcept 191*e4b17023SJohn Marino { return std::tuple_cat(std::tie(outer_allocator()), _M_inner._M_tie()); } 192*e4b17023SJohn Marino 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 195*e4b17023SJohn Marino void 196*e4b17023SJohn Marino _M_construct(__uses_alloc0, _Tp* __p, _Args&&... __args) 197*e4b17023SJohn Marino { 198*e4b17023SJohn Marino auto& __outer = __outermost(*this); 199*e4b17023SJohn Marino typedef typename std::decay<decltype(__outer)>::type __outer_type; 200*e4b17023SJohn Marino typedef allocator_traits<__outer_type> __o_traits; 201*e4b17023SJohn Marino __o_traits::construct(__outer, __p, std::forward<_Args>(__args)...); 202*e4b17023SJohn Marino } 203*e4b17023SJohn Marino 204*e4b17023SJohn Marino typedef __uses_alloc1<typename __inner_type::__type> __uses_alloc1_; 205*e4b17023SJohn Marino typedef __uses_alloc2<typename __inner_type::__type> __uses_alloc2_; 206*e4b17023SJohn Marino 207*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 208*e4b17023SJohn Marino void 209*e4b17023SJohn Marino _M_construct(__uses_alloc1_, _Tp* __p, _Args&&... __args) 210*e4b17023SJohn Marino { 211*e4b17023SJohn Marino auto& __outer = __outermost(*this); 212*e4b17023SJohn Marino typedef typename std::decay<decltype(__outer)>::type __outer_type; 213*e4b17023SJohn Marino typedef allocator_traits<__outer_type> __o_traits; 214*e4b17023SJohn Marino __o_traits::construct(__outer, __p, allocator_arg, inner_allocator(), 215*e4b17023SJohn Marino std::forward<_Args>(__args)...); 216*e4b17023SJohn Marino } 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 219*e4b17023SJohn Marino void 220*e4b17023SJohn Marino _M_construct(__uses_alloc2_, _Tp* __p, _Args&&... __args) 221*e4b17023SJohn Marino { 222*e4b17023SJohn Marino auto& __outer = __outermost(*this); 223*e4b17023SJohn Marino typedef typename std::decay<decltype(__outer)>::type __outer_type; 224*e4b17023SJohn Marino typedef allocator_traits<__outer_type> __o_traits; 225*e4b17023SJohn Marino __o_traits::construct(__outer, __p, std::forward<_Args>(__args)..., 226*e4b17023SJohn Marino inner_allocator()); 227*e4b17023SJohn Marino } 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino template<typename _Alloc> 230*e4b17023SJohn Marino static _Alloc 231*e4b17023SJohn Marino _S_select_on_copy(const _Alloc& __a) 232*e4b17023SJohn Marino { 233*e4b17023SJohn Marino typedef allocator_traits<_Alloc> __a_traits; 234*e4b17023SJohn Marino return __a_traits::select_on_container_copy_construction(__a); 235*e4b17023SJohn Marino } 236*e4b17023SJohn Marino 237*e4b17023SJohn Marino template<std::size_t... _Indices> 238*e4b17023SJohn Marino scoped_allocator_adaptor(tuple<const _OuterAlloc&, 239*e4b17023SJohn Marino const _InnerAllocs&...> __refs, 240*e4b17023SJohn Marino _Index_tuple<_Indices...>) 241*e4b17023SJohn Marino : _OuterAlloc(_S_select_on_copy(std::get<0>(__refs))), 242*e4b17023SJohn Marino _M_inner(_S_select_on_copy(std::get<_Indices+1>(__refs))...) 243*e4b17023SJohn Marino { } 244*e4b17023SJohn Marino 245*e4b17023SJohn Marino public: 246*e4b17023SJohn Marino typedef _OuterAlloc outer_allocator_type; 247*e4b17023SJohn Marino typedef typename __inner_type::__type inner_allocator_type; 248*e4b17023SJohn Marino 249*e4b17023SJohn Marino typedef typename __traits::value_type value_type; 250*e4b17023SJohn Marino typedef typename __traits::size_type size_type; 251*e4b17023SJohn Marino typedef typename __traits::difference_type difference_type; 252*e4b17023SJohn Marino typedef typename __traits::pointer pointer; 253*e4b17023SJohn Marino typedef typename __traits::const_pointer const_pointer; 254*e4b17023SJohn Marino typedef typename __traits::void_pointer void_pointer; 255*e4b17023SJohn Marino typedef typename __traits::const_void_pointer const_void_pointer; 256*e4b17023SJohn Marino 257*e4b17023SJohn Marino typedef typename conditional< 258*e4b17023SJohn Marino __any_of<__propagate_on_copy, _OuterAlloc, _InnerAllocs...>::value, 259*e4b17023SJohn Marino true_type, false_type>::type propagate_on_container_copy_assignment; 260*e4b17023SJohn Marino typedef typename conditional< 261*e4b17023SJohn Marino __any_of<__propagate_on_move, _OuterAlloc, _InnerAllocs...>::value, 262*e4b17023SJohn Marino true_type, false_type>::type propagate_on_container_move_assignment; 263*e4b17023SJohn Marino typedef typename conditional< 264*e4b17023SJohn Marino __any_of<__propagate_on_swap, _OuterAlloc, _InnerAllocs...>::value, 265*e4b17023SJohn Marino true_type, false_type>::type propagate_on_container_swap; 266*e4b17023SJohn Marino 267*e4b17023SJohn Marino template <class _Tp> 268*e4b17023SJohn Marino struct rebind 269*e4b17023SJohn Marino { 270*e4b17023SJohn Marino typedef scoped_allocator_adaptor< 271*e4b17023SJohn Marino typename __traits::template rebind_alloc<_Tp>, 272*e4b17023SJohn Marino _InnerAllocs...> other; 273*e4b17023SJohn Marino }; 274*e4b17023SJohn Marino 275*e4b17023SJohn Marino scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { } 276*e4b17023SJohn Marino 277*e4b17023SJohn Marino template<typename _Outer2> 278*e4b17023SJohn Marino scoped_allocator_adaptor(_Outer2&& __outer, 279*e4b17023SJohn Marino const _InnerAllocs&... __inner) 280*e4b17023SJohn Marino : _OuterAlloc(std::forward<_Outer2>(__outer)), 281*e4b17023SJohn Marino _M_inner(__inner...) 282*e4b17023SJohn Marino { } 283*e4b17023SJohn Marino 284*e4b17023SJohn Marino scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) 285*e4b17023SJohn Marino : _OuterAlloc(__other.outer_allocator()), 286*e4b17023SJohn Marino _M_inner(__other._M_inner) 287*e4b17023SJohn Marino { } 288*e4b17023SJohn Marino 289*e4b17023SJohn Marino scoped_allocator_adaptor(scoped_allocator_adaptor&& __other) 290*e4b17023SJohn Marino : _OuterAlloc(std::move(__other.outer_allocator())), 291*e4b17023SJohn Marino _M_inner(std::move(__other._M_inner)) 292*e4b17023SJohn Marino { } 293*e4b17023SJohn Marino 294*e4b17023SJohn Marino template<typename _Outer2> 295*e4b17023SJohn Marino scoped_allocator_adaptor( 296*e4b17023SJohn Marino const scoped_allocator_adaptor<_Outer2, _InnerAllocs...>& __other) 297*e4b17023SJohn Marino : _OuterAlloc(__other.outer_allocator()), 298*e4b17023SJohn Marino _M_inner(__other._M_inner) 299*e4b17023SJohn Marino { } 300*e4b17023SJohn Marino 301*e4b17023SJohn Marino template<typename _Outer2> 302*e4b17023SJohn Marino scoped_allocator_adaptor( 303*e4b17023SJohn Marino scoped_allocator_adaptor<_Outer2, _InnerAllocs...>&& __other) 304*e4b17023SJohn Marino : _OuterAlloc(std::move(__other.outer_allocator())), 305*e4b17023SJohn Marino _M_inner(std::move(__other._M_inner)) 306*e4b17023SJohn Marino { } 307*e4b17023SJohn Marino 308*e4b17023SJohn Marino inner_allocator_type& inner_allocator() noexcept 309*e4b17023SJohn Marino { return _M_inner._M_get(this); } 310*e4b17023SJohn Marino 311*e4b17023SJohn Marino const inner_allocator_type& inner_allocator() const noexcept 312*e4b17023SJohn Marino { return _M_inner._M_get(this); } 313*e4b17023SJohn Marino 314*e4b17023SJohn Marino outer_allocator_type& outer_allocator() noexcept 315*e4b17023SJohn Marino { return static_cast<_OuterAlloc&>(*this); } 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino const outer_allocator_type& outer_allocator() const noexcept 318*e4b17023SJohn Marino { return static_cast<const _OuterAlloc&>(*this); } 319*e4b17023SJohn Marino 320*e4b17023SJohn Marino pointer allocate(size_type __n) 321*e4b17023SJohn Marino { return __traits::allocate(outer_allocator(), __n); } 322*e4b17023SJohn Marino 323*e4b17023SJohn Marino pointer allocate(size_type __n, const_void_pointer __hint) 324*e4b17023SJohn Marino { return __traits::allocate(outer_allocator(), __n, __hint); } 325*e4b17023SJohn Marino 326*e4b17023SJohn Marino void deallocate(pointer __p, size_type __n) 327*e4b17023SJohn Marino { return __traits::deallocate(outer_allocator(), __p, __n); } 328*e4b17023SJohn Marino 329*e4b17023SJohn Marino size_type max_size() const 330*e4b17023SJohn Marino { return __traits::max_size(outer_allocator()); } 331*e4b17023SJohn Marino 332*e4b17023SJohn Marino template<typename _Tp, typename... _Args> 333*e4b17023SJohn Marino void construct(_Tp* __p, _Args&&... __args) 334*e4b17023SJohn Marino { 335*e4b17023SJohn Marino auto& __inner = inner_allocator(); 336*e4b17023SJohn Marino auto __use_tag 337*e4b17023SJohn Marino = __use_alloc<_Tp, inner_allocator_type, _Args...>(__inner); 338*e4b17023SJohn Marino _M_construct(__use_tag, __p, std::forward<_Args>(__args)...); 339*e4b17023SJohn Marino } 340*e4b17023SJohn Marino 341*e4b17023SJohn Marino // TODO: construct pairs 342*e4b17023SJohn Marino 343*e4b17023SJohn Marino template<typename _Tp> 344*e4b17023SJohn Marino void destroy(_Tp* __p) 345*e4b17023SJohn Marino { 346*e4b17023SJohn Marino auto& __outer = __outermost(*this); 347*e4b17023SJohn Marino typedef typename std::decay<decltype(__outer)>::type __outer_type; 348*e4b17023SJohn Marino allocator_traits<__outer_type>::destroy(__outer, __p); 349*e4b17023SJohn Marino } 350*e4b17023SJohn Marino 351*e4b17023SJohn Marino scoped_allocator_adaptor 352*e4b17023SJohn Marino select_on_container_copy_construction() const 353*e4b17023SJohn Marino { 354*e4b17023SJohn Marino typedef typename _Build_index_tuple<sizeof...(_InnerAllocs)>::__type 355*e4b17023SJohn Marino _Indices; 356*e4b17023SJohn Marino return scoped_allocator_adaptor(_M_tie(), _Indices()); 357*e4b17023SJohn Marino } 358*e4b17023SJohn Marino 359*e4b17023SJohn Marino template <typename _OutA1, typename _OutA2, typename... _InA> 360*e4b17023SJohn Marino friend bool 361*e4b17023SJohn Marino operator==(const scoped_allocator_adaptor<_OutA1, _InA...>& __a, 362*e4b17023SJohn Marino const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept; 363*e4b17023SJohn Marino }; 364*e4b17023SJohn Marino 365*e4b17023SJohn Marino template <typename _OutA1, typename _OutA2, typename... _InA> 366*e4b17023SJohn Marino inline bool 367*e4b17023SJohn Marino operator==(const scoped_allocator_adaptor<_OutA1, _InA...>& __a, 368*e4b17023SJohn Marino const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept 369*e4b17023SJohn Marino { 370*e4b17023SJohn Marino return __a.outer_allocator() == __b.outer_allocator() 371*e4b17023SJohn Marino && __a._M_inner == __b._M_inner; 372*e4b17023SJohn Marino } 373*e4b17023SJohn Marino 374*e4b17023SJohn Marino template <typename _OutA1, typename _OutA2, typename... _InA> 375*e4b17023SJohn Marino inline bool 376*e4b17023SJohn Marino operator!=(const scoped_allocator_adaptor<_OutA1, _InA...>& __a, 377*e4b17023SJohn Marino const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept 378*e4b17023SJohn Marino { return !(__a == __b); } 379*e4b17023SJohn Marino 380*e4b17023SJohn Marino /// @} 381*e4b17023SJohn Marino 382*e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 383*e4b17023SJohn Marino} // namespace 384*e4b17023SJohn Marino 385*e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 386*e4b17023SJohn Marino 387*e4b17023SJohn Marino#endif // _SCOPED_ALLOCATOR 388