mirror of
https://github.com/darlinghq/darling-libcxx.git
synced 2024-11-24 04:19:48 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@289710 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6d95982406
commit
ff62475dcd
@ -637,7 +637,8 @@ constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value;
|
||||
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 (integral_constant<int, 0>, _Tp *__storage, con
|
||||
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 (integral_constant<int, 1>, _Tp *__storage, con
|
||||
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 (integral_constant<int, 2>, _Tp *__storage, con
|
||||
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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user