]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/scoped_allocator
Merge OpenSSL 1.0.2i.
[FreeBSD/FreeBSD.git] / contrib / libc++ / include / scoped_allocator
1 // -*- C++ -*-
2 //===-------------------------- scoped_allocator --------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_SCOPED_ALLOCATOR
12 #define _LIBCPP_SCOPED_ALLOCATOR
13
14 /*
15     scoped_allocator synopsis
16
17 namespace std
18 {
19
20 template <class OuterAlloc, class... InnerAllocs>
21 class scoped_allocator_adaptor : public OuterAlloc
22 {
23     typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
24     scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
25 public:
26
27     typedef OuterAlloc outer_allocator_type;
28     typedef see below inner_allocator_type;
29
30     typedef typename OuterTraits::value_type value_type;
31     typedef typename OuterTraits::size_type size_type;
32     typedef typename OuterTraits::difference_type difference_type;
33     typedef typename OuterTraits::pointer pointer;
34     typedef typename OuterTraits::const_pointer const_pointer;
35     typedef typename OuterTraits::void_pointer void_pointer;
36     typedef typename OuterTraits::const_void_pointer const_void_pointer;
37
38     typedef see below propagate_on_container_copy_assignment;
39     typedef see below propagate_on_container_move_assignment;
40     typedef see below propagate_on_container_swap;
41     typedef see below is_always_equal;
42
43     template <class Tp>
44         struct rebind
45         {
46             typedef scoped_allocator_adaptor<
47                 OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
48         };
49
50     scoped_allocator_adaptor();
51     template <class OuterA2>
52         scoped_allocator_adaptor(OuterA2&& outerAlloc,
53                                  const InnerAllocs&... innerAllocs) noexcept;
54     scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
55     scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
56     template <class OuterA2>
57         scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
58     template <class OuterA2>
59         scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
60
61     scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
62     scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
63     ~scoped_allocator_adaptor();
64
65     inner_allocator_type& inner_allocator() noexcept;
66     const inner_allocator_type& inner_allocator() const noexcept;
67
68     outer_allocator_type& outer_allocator() noexcept;
69     const outer_allocator_type& outer_allocator() const noexcept;
70
71     pointer allocate(size_type n);
72     pointer allocate(size_type n, const_void_pointer hint);
73     void deallocate(pointer p, size_type n) noexcept;
74
75     size_type max_size() const;
76     template <class T, class... Args> void construct(T* p, Args&& args);
77     template <class T1, class T2, class... Args1, class... Args2>
78         void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
79                        tuple<Args2...> y);
80     template <class T1, class T2>
81         void construct(pair<T1, T2>* p);
82     template <class T1, class T2, class U, class V>
83         void construct(pair<T1, T2>* p, U&& x, V&& y);
84     template <class T1, class T2, class U, class V>
85         void construct(pair<T1, T2>* p, const pair<U, V>& x);
86     template <class T1, class T2, class U, class V>
87         void construct(pair<T1, T2>* p, pair<U, V>&& x);
88     template <class T> void destroy(T* p);
89
90     template <class T> void destroy(T* p) noexcept;
91
92     scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
93 };
94
95 template <class OuterA1, class OuterA2, class... InnerAllocs>
96     bool
97     operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
98                const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
99
100 template <class OuterA1, class OuterA2, class... InnerAllocs>
101     bool
102     operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
103                const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
104
105 }  // std
106
107 */
108
109 #include <__config>
110 #include <memory>
111
112 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
113 #pragma GCC system_header
114 #endif
115
116 _LIBCPP_BEGIN_NAMESPACE_STD
117
118 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
119
120 // scoped_allocator_adaptor
121
122 template <class ..._Allocs>
123 class scoped_allocator_adaptor;
124
125 template <class ..._Allocs> struct __get_poc_copy_assignment;
126
127 template <class _A0>
128 struct __get_poc_copy_assignment<_A0>
129 {
130     static const bool value = allocator_traits<_A0>::
131                               propagate_on_container_copy_assignment::value;
132 };
133
134 template <class _A0, class ..._Allocs>
135 struct __get_poc_copy_assignment<_A0, _Allocs...>
136 {
137     static const bool value =
138         allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
139         __get_poc_copy_assignment<_Allocs...>::value;
140 };
141
142 template <class ..._Allocs> struct __get_poc_move_assignment;
143
144 template <class _A0>
145 struct __get_poc_move_assignment<_A0>
146 {
147     static const bool value = allocator_traits<_A0>::
148                               propagate_on_container_move_assignment::value;
149 };
150
151 template <class _A0, class ..._Allocs>
152 struct __get_poc_move_assignment<_A0, _Allocs...>
153 {
154     static const bool value =
155         allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
156         __get_poc_move_assignment<_Allocs...>::value;
157 };
158
159 template <class ..._Allocs> struct __get_poc_swap;
160
161 template <class _A0>
162 struct __get_poc_swap<_A0>
163 {
164     static const bool value = allocator_traits<_A0>::
165                               propagate_on_container_swap::value;
166 };
167
168 template <class _A0, class ..._Allocs>
169 struct __get_poc_swap<_A0, _Allocs...>
170 {
171     static const bool value =
172         allocator_traits<_A0>::propagate_on_container_swap::value ||
173         __get_poc_swap<_Allocs...>::value;
174 };
175
176 template <class ..._Allocs> struct __get_is_always_equal;
177
178 template <class _A0>
179 struct __get_is_always_equal<_A0>
180 {
181     static const bool value = allocator_traits<_A0>::is_always_equal::value;
182 };
183
184 template <class _A0, class ..._Allocs>
185 struct __get_is_always_equal<_A0, _Allocs...>
186 {
187     static const bool value =
188         allocator_traits<_A0>::is_always_equal::value &&
189         __get_is_always_equal<_Allocs...>::value;
190 };
191
192 template <class ..._Allocs>
193 class __scoped_allocator_storage;
194
195 template <class _OuterAlloc, class... _InnerAllocs>
196 class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
197     : public _OuterAlloc
198 {
199     typedef _OuterAlloc outer_allocator_type;
200 protected:
201     typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
202
203 private:
204     inner_allocator_type __inner_;
205
206 protected:
207
208     _LIBCPP_INLINE_VISIBILITY
209     __scoped_allocator_storage() _NOEXCEPT {}
210
211     template <class _OuterA2,
212               class = typename enable_if<
213                         is_constructible<outer_allocator_type, _OuterA2>::value
214                       >::type>
215         _LIBCPP_INLINE_VISIBILITY
216         __scoped_allocator_storage(_OuterA2&& __outerAlloc,
217                                    const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
218             : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
219               __inner_(__innerAllocs...) {}
220
221     template <class _OuterA2,
222               class = typename enable_if<
223                         is_constructible<outer_allocator_type, const _OuterA2&>::value
224                       >::type>
225         _LIBCPP_INLINE_VISIBILITY
226         __scoped_allocator_storage(
227             const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
228             : outer_allocator_type(__other.outer_allocator()),
229               __inner_(__other.inner_allocator()) {}
230
231     template <class _OuterA2,
232               class = typename enable_if<
233                         is_constructible<outer_allocator_type, _OuterA2>::value
234                       >::type>
235         _LIBCPP_INLINE_VISIBILITY
236         __scoped_allocator_storage(
237             __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
238             : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
239               __inner_(_VSTD::move(__other.inner_allocator())) {}
240
241     template <class _OuterA2,
242               class = typename enable_if<
243                         is_constructible<outer_allocator_type, _OuterA2>::value
244                       >::type>
245         _LIBCPP_INLINE_VISIBILITY
246         __scoped_allocator_storage(_OuterA2&& __o,
247                                    const inner_allocator_type& __i) _NOEXCEPT
248             : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
249               __inner_(__i)
250         {
251         }
252
253     _LIBCPP_INLINE_VISIBILITY
254     inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}
255     _LIBCPP_INLINE_VISIBILITY
256     const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
257
258     _LIBCPP_INLINE_VISIBILITY
259     outer_allocator_type& outer_allocator() _NOEXCEPT
260         {return static_cast<outer_allocator_type&>(*this);}
261     _LIBCPP_INLINE_VISIBILITY
262     const outer_allocator_type& outer_allocator() const _NOEXCEPT
263         {return static_cast<const outer_allocator_type&>(*this);}
264
265     scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
266     _LIBCPP_INLINE_VISIBILITY
267     select_on_container_copy_construction() const _NOEXCEPT
268         {
269             return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
270             (
271                 allocator_traits<outer_allocator_type>::
272                     select_on_container_copy_construction(outer_allocator()),
273                 allocator_traits<inner_allocator_type>::
274                     select_on_container_copy_construction(inner_allocator())
275             );
276         }
277
278     template <class...> friend class __scoped_allocator_storage;
279 };
280
281 template <class _OuterAlloc>
282 class __scoped_allocator_storage<_OuterAlloc>
283     : public _OuterAlloc
284 {
285     typedef _OuterAlloc outer_allocator_type;
286 protected:
287     typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
288
289     _LIBCPP_INLINE_VISIBILITY
290     __scoped_allocator_storage() _NOEXCEPT {}
291
292     template <class _OuterA2,
293               class = typename enable_if<
294                         is_constructible<outer_allocator_type, _OuterA2>::value
295                       >::type>
296         _LIBCPP_INLINE_VISIBILITY
297         __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
298             : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
299
300     template <class _OuterA2,
301               class = typename enable_if<
302                         is_constructible<outer_allocator_type, const _OuterA2&>::value
303                       >::type>
304         _LIBCPP_INLINE_VISIBILITY
305         __scoped_allocator_storage(
306             const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
307             : outer_allocator_type(__other.outer_allocator()) {}
308
309     template <class _OuterA2,
310               class = typename enable_if<
311                         is_constructible<outer_allocator_type, _OuterA2>::value
312                       >::type>
313         _LIBCPP_INLINE_VISIBILITY
314         __scoped_allocator_storage(
315             __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
316             : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
317
318     _LIBCPP_INLINE_VISIBILITY
319     inner_allocator_type& inner_allocator() _NOEXCEPT
320         {return static_cast<inner_allocator_type&>(*this);}
321     _LIBCPP_INLINE_VISIBILITY
322     const inner_allocator_type& inner_allocator() const _NOEXCEPT
323         {return static_cast<const inner_allocator_type&>(*this);}
324
325     _LIBCPP_INLINE_VISIBILITY
326     outer_allocator_type& outer_allocator() _NOEXCEPT
327         {return static_cast<outer_allocator_type&>(*this);}
328     _LIBCPP_INLINE_VISIBILITY
329     const outer_allocator_type& outer_allocator() const _NOEXCEPT
330         {return static_cast<const outer_allocator_type&>(*this);}
331
332     _LIBCPP_INLINE_VISIBILITY
333     scoped_allocator_adaptor<outer_allocator_type>
334     select_on_container_copy_construction() const _NOEXCEPT
335         {return scoped_allocator_adaptor<outer_allocator_type>(
336             allocator_traits<outer_allocator_type>::
337                 select_on_container_copy_construction(outer_allocator())
338         );}
339
340     __scoped_allocator_storage(const outer_allocator_type& __o,
341                                const inner_allocator_type& __i) _NOEXCEPT;
342
343     template <class...> friend class __scoped_allocator_storage;
344 };
345
346 // __outermost
347
348 template <class _Alloc>
349 decltype(declval<_Alloc>().outer_allocator(), true_type())
350 __has_outer_allocator_test(_Alloc&& __a);
351
352 template <class _Alloc>
353 false_type
354 __has_outer_allocator_test(const volatile _Alloc& __a);
355
356 template <class _Alloc>
357 struct __has_outer_allocator
358     : public common_type
359              <
360                  decltype(__has_outer_allocator_test(declval<_Alloc&>()))
361              >::type
362 {
363 };
364
365 template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
366 struct __outermost
367 {
368     typedef _Alloc type;
369     _LIBCPP_INLINE_VISIBILITY
370     type& operator()(type& __a) const _NOEXCEPT {return __a;}
371 };
372
373 template <class _Alloc>
374 struct __outermost<_Alloc, true>
375 {
376     typedef typename remove_reference
377                      <
378                         decltype(_VSTD::declval<_Alloc>().outer_allocator())
379                      >::type                                    _OuterAlloc;
380     typedef typename __outermost<_OuterAlloc>::type             type;
381     _LIBCPP_INLINE_VISIBILITY
382     type& operator()(_Alloc& __a) const _NOEXCEPT
383         {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
384 };
385
386 template <class _OuterAlloc, class... _InnerAllocs>
387 class _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
388     : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
389 {
390     typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
391     typedef allocator_traits<_OuterAlloc>             _OuterTraits;
392 public:
393     typedef _OuterAlloc                               outer_allocator_type;
394     typedef typename base::inner_allocator_type       inner_allocator_type;
395     typedef typename _OuterTraits::size_type          size_type;
396     typedef typename _OuterTraits::difference_type    difference_type;
397     typedef typename _OuterTraits::pointer            pointer;
398     typedef typename _OuterTraits::const_pointer      const_pointer;
399     typedef typename _OuterTraits::void_pointer       void_pointer;
400     typedef typename _OuterTraits::const_void_pointer const_void_pointer;
401
402     typedef integral_constant
403             <
404                 bool,
405                 __get_poc_copy_assignment<outer_allocator_type,
406                                           _InnerAllocs...>::value
407             > propagate_on_container_copy_assignment;
408     typedef integral_constant
409             <
410                 bool,
411                 __get_poc_move_assignment<outer_allocator_type,
412                                           _InnerAllocs...>::value
413             > propagate_on_container_move_assignment;
414     typedef integral_constant
415             <
416                 bool,
417                 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
418             > propagate_on_container_swap;
419     typedef integral_constant
420             <
421                 bool,
422                 __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
423             > is_always_equal;
424
425     template <class _Tp>
426     struct rebind
427     {
428         typedef scoped_allocator_adaptor
429         <
430             typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
431         > other;
432     };
433
434     _LIBCPP_INLINE_VISIBILITY
435     scoped_allocator_adaptor() _NOEXCEPT {}
436     template <class _OuterA2,
437               class = typename enable_if<
438                         is_constructible<outer_allocator_type, _OuterA2>::value
439                       >::type>
440         _LIBCPP_INLINE_VISIBILITY
441         scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
442                                  const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
443             : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
444     // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
445     template <class _OuterA2,
446               class = typename enable_if<
447                         is_constructible<outer_allocator_type, const _OuterA2&>::value
448                       >::type>
449         _LIBCPP_INLINE_VISIBILITY
450         scoped_allocator_adaptor(
451             const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
452                 : base(__other) {}
453     template <class _OuterA2,
454               class = typename enable_if<
455                         is_constructible<outer_allocator_type, _OuterA2>::value
456                       >::type>
457         _LIBCPP_INLINE_VISIBILITY
458         scoped_allocator_adaptor(
459             scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
460                 : base(_VSTD::move(__other)) {}
461
462     // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
463     // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
464     // ~scoped_allocator_adaptor() = default;
465
466     _LIBCPP_INLINE_VISIBILITY
467     inner_allocator_type& inner_allocator() _NOEXCEPT
468         {return base::inner_allocator();}
469     _LIBCPP_INLINE_VISIBILITY
470     const inner_allocator_type& inner_allocator() const _NOEXCEPT
471         {return base::inner_allocator();}
472
473     _LIBCPP_INLINE_VISIBILITY
474     outer_allocator_type& outer_allocator() _NOEXCEPT
475         {return base::outer_allocator();}
476     _LIBCPP_INLINE_VISIBILITY
477     const outer_allocator_type& outer_allocator() const _NOEXCEPT
478         {return base::outer_allocator();}
479
480     _LIBCPP_INLINE_VISIBILITY
481     pointer allocate(size_type __n)
482         {return allocator_traits<outer_allocator_type>::
483             allocate(outer_allocator(), __n);}
484     _LIBCPP_INLINE_VISIBILITY
485     pointer allocate(size_type __n, const_void_pointer __hint)
486         {return allocator_traits<outer_allocator_type>::
487             allocate(outer_allocator(), __n, __hint);}
488
489     _LIBCPP_INLINE_VISIBILITY
490     void deallocate(pointer __p, size_type __n) _NOEXCEPT
491         {allocator_traits<outer_allocator_type>::
492             deallocate(outer_allocator(), __p, __n);}
493
494     _LIBCPP_INLINE_VISIBILITY
495     size_type max_size() const
496         {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
497
498     template <class _Tp, class... _Args>
499         _LIBCPP_INLINE_VISIBILITY
500         void construct(_Tp* __p, _Args&& ...__args)
501             {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
502                          __p, _VSTD::forward<_Args>(__args)...);}
503     template <class _Tp>
504         _LIBCPP_INLINE_VISIBILITY
505         void destroy(_Tp* __p)
506             {
507                 typedef __outermost<outer_allocator_type> _OM;
508                 allocator_traits<typename _OM::type>::
509                                          destroy(_OM()(outer_allocator()), __p);
510             }
511
512     _LIBCPP_INLINE_VISIBILITY
513     scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
514         {return base::select_on_container_copy_construction();}
515
516 private:
517
518     template <class _OuterA2,
519               class = typename enable_if<
520                         is_constructible<outer_allocator_type, _OuterA2>::value
521                       >::type>
522     _LIBCPP_INLINE_VISIBILITY
523     scoped_allocator_adaptor(_OuterA2&& __o,
524                              const inner_allocator_type& __i) _NOEXCEPT
525         : base(_VSTD::forward<_OuterA2>(__o), __i) {}
526
527     template <class _Tp, class... _Args>
528         _LIBCPP_INLINE_VISIBILITY
529         void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
530             {
531                 typedef __outermost<outer_allocator_type> _OM;
532                 allocator_traits<typename _OM::type>::construct
533                 (
534                     _OM()(outer_allocator()),
535                     __p,
536                     _VSTD::forward<_Args>(__args)...
537                 );
538             }
539
540     template <class _Tp, class... _Args>
541         _LIBCPP_INLINE_VISIBILITY
542         void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
543             {
544                 typedef __outermost<outer_allocator_type> _OM;
545                 allocator_traits<typename _OM::type>::construct
546                 (
547                     _OM()(outer_allocator()),
548                     __p,
549                     allocator_arg,
550                     inner_allocator(),
551                     _VSTD::forward<_Args>(__args)...
552                 );
553             }
554
555     template <class _Tp, class... _Args>
556         _LIBCPP_INLINE_VISIBILITY
557         void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
558             {
559                 typedef __outermost<outer_allocator_type> _OM;
560                 allocator_traits<typename _OM::type>::construct
561                 (
562                     _OM()(outer_allocator()),
563                     __p,
564                     _VSTD::forward<_Args>(__args)...,
565                     inner_allocator()
566                 );
567             }
568
569     template <class...> friend class __scoped_allocator_storage;
570 };
571
572 template <class _OuterA1, class _OuterA2>
573 inline _LIBCPP_INLINE_VISIBILITY
574 bool
575 operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
576            const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
577 {
578     return __a.outer_allocator() == __b.outer_allocator();
579 }
580
581 template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
582 inline _LIBCPP_INLINE_VISIBILITY
583 bool
584 operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
585            const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
586 {
587     return __a.outer_allocator() == __b.outer_allocator() &&
588            __a.inner_allocator() == __b.inner_allocator();
589 }
590
591 template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
592 inline _LIBCPP_INLINE_VISIBILITY
593 bool
594 operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
595            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
596 {
597     return !(__a == __b);
598 }
599
600 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
601
602 _LIBCPP_END_NAMESPACE_STD
603
604 #endif  // _LIBCPP_SCOPED_ALLOCATOR