[libcxx] r289710 - [libcxx] Fix PR24075, PR23841 - Add scoped_allocator_adaptor::construct(pair<T, U>*, ...) overloads.
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 14 13:29:30 PST 2016
Author: ericwf
Date: Wed Dec 14 15:29:29 2016
New Revision: 289710
URL: http://llvm.org/viewvc/llvm-project?rev=289710&view=rev
Log:
[libcxx] Fix PR24075, PR23841 - Add scoped_allocator_adaptor::construct(pair<T, U>*, ...) overloads.
Summary:
For more information see:
* https://llvm.org/bugs/show_bug.cgi?id=23841
* https://llvm.org/bugs/show_bug.cgi?id=24075
I hope you have as much fun reviewing as I did writing these insane tests!
Reviewers: mclow.lists, AlisdairM, EricWF
Subscribers: AlisdairM, Potatoswatter, cfe-commits
Differential Revision: https://reviews.llvm.org/D27612
Added:
libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp
libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp
libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp
libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp
libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp
Modified:
libcxx/trunk/include/__functional_base
libcxx/trunk/include/scoped_allocator
Modified: libcxx/trunk/include/__functional_base
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__functional_base?rev=289710&r1=289709&r2=289710&view=diff
==============================================================================
--- libcxx/trunk/include/__functional_base (original)
+++ libcxx/trunk/include/__functional_base Wed Dec 14 15:29:29 2016
@@ -637,7 +637,8 @@ constexpr size_t uses_allocator_v = uses
template <class _Tp, class _Alloc, class ..._Args>
struct __uses_alloc_ctor_imp
{
- static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
+ typedef typename __uncvref<_Alloc>::type _RawAlloc;
+ static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
static const bool __ic =
is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
static const int value = __ua ? 2 - __ic : 0;
@@ -655,6 +656,7 @@ void __user_alloc_construct_impl (integr
new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
}
+// FIXME: This should have a version which takes a non-const alloc.
template <class _Tp, class _Allocator, class... _Args>
inline _LIBCPP_INLINE_VISIBILITY
void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
@@ -662,6 +664,7 @@ void __user_alloc_construct_impl (integr
new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
}
+// FIXME: This should have a version which takes a non-const alloc.
template <class _Tp, class _Allocator, class... _Args>
inline _LIBCPP_INLINE_VISIBILITY
void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
@@ -669,6 +672,7 @@ void __user_alloc_construct_impl (integr
new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
}
+// FIXME: Theis should have a version which takes a non-const alloc.
template <class _Tp, class _Allocator, class... _Args>
inline _LIBCPP_INLINE_VISIBILITY
void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
Modified: libcxx/trunk/include/scoped_allocator
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/scoped_allocator?rev=289710&r1=289709&r2=289710&view=diff
==============================================================================
--- libcxx/trunk/include/scoped_allocator (original)
+++ libcxx/trunk/include/scoped_allocator Wed Dec 14 15:29:29 2016
@@ -498,8 +498,58 @@ public:
template <class _Tp, class... _Args>
_LIBCPP_INLINE_VISIBILITY
void construct(_Tp* __p, _Args&& ...__args)
- {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
+ {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
__p, _VSTD::forward<_Args>(__args)...);}
+
+ template <class _T1, class _T2, class... _Args1, class... _Args2>
+ void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
+ tuple<_Args1...> __x, tuple<_Args2...> __y)
+ {
+ typedef __outermost<outer_allocator_type> _OM;
+ allocator_traits<typename _OM::type>::construct(
+ _OM()(outer_allocator()), __p, piecewise_construct
+ , __transform_tuple(
+ typename __uses_alloc_ctor<
+ _T1, inner_allocator_type&, _Args1...
+ >::type()
+ , _VSTD::move(__x)
+ , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
+ )
+ , __transform_tuple(
+ typename __uses_alloc_ctor<
+ _T2, inner_allocator_type&, _Args2...
+ >::type()
+ , _VSTD::move(__y)
+ , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
+ )
+ );
+ }
+
+ template <class _T1, class _T2>
+ void construct(pair<_T1, _T2>* __p)
+ { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
+
+ template <class _T1, class _T2, class _Up, class _Vp>
+ void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
+ construct(__p, piecewise_construct,
+ _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
+ }
+
+ template <class _T1, class _T2, class _Up, class _Vp>
+ void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
+ construct(__p, piecewise_construct,
+ _VSTD::forward_as_tuple(__x.first),
+ _VSTD::forward_as_tuple(__x.second));
+ }
+
+ template <class _T1, class _T2, class _Up, class _Vp>
+ void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
+ construct(__p, piecewise_construct,
+ _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
+ }
+
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
void destroy(_Tp* __p)
@@ -515,6 +565,7 @@ public:
private:
+
template <class _OuterA2,
class = typename enable_if<
is_constructible<outer_allocator_type, _OuterA2>::value
@@ -545,9 +596,7 @@ private:
allocator_traits<typename _OM::type>::construct
(
_OM()(outer_allocator()),
- __p,
- allocator_arg,
- inner_allocator(),
+ __p, allocator_arg, inner_allocator(),
_VSTD::forward<_Args>(__args)...
);
}
@@ -566,6 +615,36 @@ private:
);
}
+ template <class ..._Args, size_t ..._Idx>
+ _LIBCPP_INLINE_VISIBILITY
+ tuple<_Args&&...>
+ __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
+ __tuple_indices<_Idx...>)
+ {
+ return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
+ }
+
+ template <class ..._Args, size_t ..._Idx>
+ _LIBCPP_INLINE_VISIBILITY
+ tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
+ __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
+ __tuple_indices<_Idx...>)
+ {
+ using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
+ return _Tup(allocator_arg, inner_allocator(),
+ _VSTD::get<_Idx>(_VSTD::move(__t))...);
+ }
+
+ template <class ..._Args, size_t ..._Idx>
+ _LIBCPP_INLINE_VISIBILITY
+ tuple<_Args&&..., inner_allocator_type&>
+ __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
+ __tuple_indices<_Idx...>)
+ {
+ using _Tup = tuple<_Args&&..., inner_allocator_type&>;
+ return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
+ }
+
template <class...> friend class __scoped_allocator_storage;
};
Added: libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp?rev=289710&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp Wed Dec 14 15:29:29 2016
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 0>;
+ using U = UsesAllocatorV2<VoidAlloc, 0>;
+ using Pair = std::pair<T, U>;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&>&&,
+ std::tuple<SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 0>;
+ using U = NotUsesAllocator<VoidAlloc, 0>;
+ using Pair = std::pair<T, U>;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&>&&,
+ std::tuple<>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 0>;
+ using U = UsesAllocatorV2<VoidAlloc2, 0>;
+ using Pair = std::pair<T, U>;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&>&&,
+ std::tuple<SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 0>;
+ using U = NotUsesAllocator<VoidAlloc2, 0>;
+ using Pair = std::pair<T, U>;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&>&&,
+ std::tuple<>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
Added: libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp?rev=289710&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp Wed Dec 14 15:29:29 2016
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>const&)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ const PairIn in(x, std::move(y));
+ A.construct(ptr, in);
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ const PairIn in(x, y);
+ A.construct(ptr, in);
+ assert(checkConstruct<int const&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int const&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ const PairIn in(x, std::move(y));
+ A.construct(ptr, in);
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int const&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const &>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ const PairIn in(x, y);
+ A.construct(ptr, in);
+ assert(checkConstruct<int const&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int const&>&&,
+ std::tuple<int const&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
Added: libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp?rev=289710&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp Wed Dec 14 15:29:29 2016
@@ -0,0 +1,156 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*,
+// piecewise_construct_t, tuple<Args1...>, tuple<Args2...>)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(x),
+ std::forward_as_tuple(std::move(y)));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(std::move(x)),
+ std::forward_as_tuple(y));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(x),
+ std::forward_as_tuple(std::move(y)));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int &&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(std::move(x)),
+ std::forward_as_tuple(std::move(y)));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
+ std::tuple<int const&&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
Added: libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp?rev=289710&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp Wed Dec 14 15:29:29 2016
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>&&)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ PairIn in(x, std::move(y));
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ PairIn in(x, y);
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ PairIn in(x, std::move(y));
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int const&&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const &>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ PairIn in(x, y);
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
+ std::tuple<int const&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
Added: libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp?rev=289710&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp Wed Dec 14 15:29:29 2016
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2, class Tp, class Vp>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*, Tp&&, Up&&)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, x, std::move(y));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, std::move(x), y);
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, x, std::move(y));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int &&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, std::move(x), std::move(y));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
+ std::tuple<int const&&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
Added: libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp?rev=289710&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp Wed Dec 14 15:29:29 2016
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class T, class ...Args>
+// void scoped_allocator_adaptor::construct(T*, Args&&...)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+// â If uses_allocator_v<T, inner_allocator_type> is false and
+// is_constructible_v<T, Args...> is true, calls
+// OUTERMOST_ALLOC_TRAITS(*this)::construct(
+// OUTERMOST (*this), p, std::forward<Args>(args)...).
+void test_bullet_one() {
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = NotUsesAllocator<VoidAlloc2, 3>;
+ using Outer = CountingAllocator<T, 1>;
+ using Inner = CountingAllocator<T, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(!std::uses_allocator<T, Inner>::value, "");
+ T* ptr = (T*)::operator new(sizeof(T));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ int x = 42;
+ int const& cx = x;
+ A.construct(ptr, x, cx, std::move(x));
+ assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_None)));
+ assert((POuter.checkConstruct<int&, int const&, int&&>(O, ptr)));
+ A.destroy(ptr);
+ ::operator delete((void*)ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+}
+
+
+// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
+// is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> is
+// true, calls OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
+// allocator_arg, inner_allocator(), std::forward<Args>(args)...).
+void test_bullet_two() {
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 3>;
+ using Outer = CountingAllocator<T, 1>;
+ using Inner = CountingAllocator<T, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ T* ptr = (T*)::operator new(sizeof(T));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ int x = 42;
+ int const& cx = x;
+ A.construct(ptr, x, cx, std::move(x));
+ assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocArg, I)));
+ assert((POuter.checkConstruct<std::allocator_arg_t const&,
+ SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr)));
+ A.destroy(ptr);
+ ::operator delete((void*)ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+}
+
+// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
+// is_constructible_v<T, Args..., inner_allocator_type&> is true, calls
+// OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
+// std::forward<Args>(args)..., inner_allocator()).
+void test_bullet_three() {
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV2<VoidAlloc2, 3>;
+ using Outer = CountingAllocator<T, 1>;
+ using Inner = CountingAllocator<T, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ T* ptr = (T*)::operator new(sizeof(T));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ int x = 42;
+ int const& cx = x;
+ A.construct(ptr, x, cx, std::move(x));
+ assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I)));
+ assert((POuter.checkConstruct<
+ int&, int const&, int&&,
+ SA::inner_allocator_type&>(O, ptr)));
+ A.destroy(ptr);
+ ::operator delete((void*)ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+}
+
+int main() {
+ test_bullet_one();
+ test_bullet_two();
+ test_bullet_three();
+}
More information about the cfe-commits
mailing list