mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[libc++] Implement P0591R4 (Utility functions to implement uses-allocator construction)
Reviewed By: ldionne, #libc, huixie90 Spies: huixie90, libcxx-commits, mgorny Differential Revision: https://reviews.llvm.org/D131898
This commit is contained in:
parent
8e3e96298f
commit
79df8e19be
@ -41,6 +41,7 @@ Implemented Papers
|
||||
- P2417R2 - A more constexpr bitset
|
||||
- P2445R1 - ``std::forward_like``
|
||||
- P2273R3 - Making ``std::unique_ptr`` constexpr
|
||||
- P0591R4 - Utility functions to implement uses-allocator construction
|
||||
|
||||
Improvements and New Features
|
||||
-----------------------------
|
||||
|
@ -40,6 +40,7 @@ Paper Status
|
||||
|
||||
.. note::
|
||||
|
||||
.. [#note-P0591] P0591: The changes in [mem.poly.allocator.mem] are missing.
|
||||
.. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class] and |sect|\ [mem.poly.allocator.class].
|
||||
.. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature
|
||||
(the feature-test macro is not set and the libary is only available when built with ``-fexperimental-library``).
|
||||
|
@ -149,7 +149,7 @@
|
||||
"`3169 <https://wg21.link/LWG3169>`__","``ranges``\ permutation generators discard useful information","Cologne","|Complete|","15.0","|ranges|"
|
||||
"`3183 <https://wg21.link/LWG3183>`__","Normative permission to specialize Ranges variable templates","Cologne","|Nothing To Do|","","|ranges|"
|
||||
"`3184 <https://wg21.link/LWG3184>`__","Inconsistencies in ``bind_front``\ wording","Cologne","|Complete|","13.0"
|
||||
"`3185 <https://wg21.link/LWG3185>`__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","Cologne","",""
|
||||
"`3185 <https://wg21.link/LWG3185>`__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","Cologne","|Complete|","16.0"
|
||||
"`3186 <https://wg21.link/LWG3186>`__","``ranges``\ removal, partition, and ``partial_sort_copy``\ algorithms discard useful information","Cologne","|Complete|","15.0","|ranges|"
|
||||
"`3187 <https://wg21.link/LWG3187>`__","`P0591R4 <https://wg21.link/p0591r4>`__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","Cologne","",""
|
||||
"`3191 <https://wg21.link/LWG3191>`__","``std::ranges::shuffle``\ synopsis does not match algorithm definition","Cologne","|Complete|","15.0","|ranges|"
|
||||
@ -243,7 +243,7 @@
|
||||
"`3318 <https://wg21.link/LWG3318>`__","Clarify whether clocks can represent time before their epoch","Prague","","","|chrono|"
|
||||
"`3319 <https://wg21.link/LWG3319>`__","Properly reference specification of IANA time zone database","Prague","","","|chrono|"
|
||||
"`3320 <https://wg21.link/LWG3320>`__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|",""
|
||||
"`3321 <https://wg21.link/LWG3321>`__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","",""
|
||||
"`3321 <https://wg21.link/LWG3321>`__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","|Complete|","16.0"
|
||||
"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","","","|ranges|"
|
||||
"`3324 <https://wg21.link/LWG3324>`__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","|Complete|","14.0","|spaceship|"
|
||||
"`3325 <https://wg21.link/LWG3325>`__","Constrain return type of transformation function for ``transform_view``\ ","Prague","|Complete|","15.0","|ranges|"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -55,8 +55,8 @@
|
||||
"`P0357R3 <https://wg21.link/P0357R3>`__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0"
|
||||
"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|Partial| [#note-P0482]_","16.0"
|
||||
"`P0487R1 <https://wg21.link/P0487R1>`__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\ (LWG 2499)","San Diego","|Complete|","8.0"
|
||||
"`P0591R4 <https://wg21.link/P0591R4>`__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *",""
|
||||
"`P0595R2 <https://wg21.link/P0595R2>`__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0"
|
||||
"`P0591R4 <https://wg21.link/P0591R4>`__","LWG","Utility functions to implement uses-allocator construction","San Diego","|Partial| [#note-P0591]_",""
|
||||
"`P0595R2 <https://wg21.link/P0595R2>`__","CWG","std::is_constant_evaluated()","San Diego","|Complete|","9.0"
|
||||
"`P0602R4 <https://wg21.link/P0602R4>`__","LWG","variant and optional should propagate copy/move triviality","San Diego","|Complete|","8.0"
|
||||
"`P0608R3 <https://wg21.link/P0608R3>`__","LWG","A sane variant converting constructor","San Diego","|Complete|","9.0"
|
||||
"`P0655R1 <https://wg21.link/P0655R1>`__","LWG","visit<R>: Explicit Return Type for visit","San Diego","|Complete|","12.0"
|
||||
|
|
@ -4,7 +4,7 @@ Section,Description,Dependencies,Assignee,Complete
|
||||
| `[utility.syn] <https://wg21.link/utility.syn>`_, "[pair] basic_common_reference, common_type", None, Nikolas Klauser, |Complete|
|
||||
| `[pairs.pair] <https://wg21.link/pairs.pair>`_, "`[pair] constructor, assignment and swap overloads <https://reviews.llvm.org/D131495>`_", None, Hui Xie, |Complete|
|
||||
"| `[memory.syn] <https://wg21.link/memory.syn>`_
|
||||
| `[allocator.uses.construction] <https://wg21.link/allocator.uses.construction>`_", "[pair] uses_allocator_construction_args overloads", None, Unassigned, |Not Started|
|
||||
| `[allocator.uses.construction] <https://wg21.link/allocator.uses.construction>`_", "[pair] uses_allocator_construction_args overloads", None, Nikolas Klauser, |Complete|
|
||||
| `[vector.bool] <https://wg21.link/vector.bool>`_, "[vector<bool>::reference] add const operator= overload", None, Hui Xie, |Not Started|
|
||||
| `[iterator.concept.winc] <https://wg21.link/iterator.concept.winc>`_, "Update weakly_comparable", None, Hui Xie, |Not Started|
|
||||
| `[range.zip] <https://wg21.link/ranges.syn>`_, "`zip_view <https://reviews.llvm.org/D122806>`_", "| `zip_view::iterator`
|
||||
|
|
@ -412,6 +412,7 @@ set(files
|
||||
__memory/uninitialized_algorithms.h
|
||||
__memory/unique_ptr.h
|
||||
__memory/uses_allocator.h
|
||||
__memory/uses_allocator_construction.h
|
||||
__memory/voidify.h
|
||||
__mutex_base
|
||||
__node_handle
|
||||
|
219
libcxx/include/__memory/uses_allocator_construction.h
Normal file
219
libcxx/include/__memory/uses_allocator_construction.h
Normal file
@ -0,0 +1,219 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H
|
||||
#define _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H
|
||||
|
||||
#include <__config>
|
||||
#include <__memory/construct_at.h>
|
||||
#include <__memory/uses_allocator.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <tuple>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
|
||||
template <class _Type>
|
||||
inline constexpr bool __is_std_pair = false;
|
||||
|
||||
template <class _Type1, class _Type2>
|
||||
inline constexpr bool __is_std_pair<pair<_Type1, _Type2>> = true;
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args, __enable_if_t<!__is_std_pair<_Type>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, _Args&&... __args) noexcept {
|
||||
if constexpr (!uses_allocator_v<_Type, _Alloc> && is_constructible_v<_Type, _Args...>) {
|
||||
return std::forward_as_tuple(std::forward<_Args>(__args)...);
|
||||
} else if constexpr (uses_allocator_v<_Type, _Alloc> &&
|
||||
is_constructible_v<_Type, allocator_arg_t, const _Alloc&, _Args...>) {
|
||||
return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(allocator_arg, __alloc, std::forward<_Args>(__args)...);
|
||||
} else if constexpr (uses_allocator_v<_Type, _Alloc> && is_constructible_v<_Type, _Args..., const _Alloc&>) {
|
||||
return std::forward_as_tuple(std::forward<_Args>(__args)..., __alloc);
|
||||
} else {
|
||||
static_assert(
|
||||
sizeof(_Type) + 1 == 0, "If uses_allocator_v<Type> is true, the type has to be allocator-constructible");
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Pair, class _Alloc, class _Tuple1, class _Tuple2, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __uses_allocator_construction_args(
|
||||
const _Alloc& __alloc, piecewise_construct_t, _Tuple1&& __x, _Tuple2&& __y) noexcept {
|
||||
return std::make_tuple(
|
||||
piecewise_construct,
|
||||
std::apply(
|
||||
[&__alloc](auto&&... __args1) {
|
||||
return std::__uses_allocator_construction_args<typename _Pair::first_type>(
|
||||
__alloc, std::forward<decltype(__args1)>(__args1)...);
|
||||
},
|
||||
std::forward<_Tuple1>(__x)),
|
||||
std::apply(
|
||||
[&__alloc](auto&&... __args2) {
|
||||
return std::__uses_allocator_construction_args<typename _Pair::second_type>(
|
||||
__alloc, std::forward<decltype(__args2)>(__args2)...);
|
||||
},
|
||||
std::forward<_Tuple2>(__y)));
|
||||
}
|
||||
|
||||
template <class _Pair, class _Alloc, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __uses_allocator_construction_args(const _Alloc& __alloc) noexcept {
|
||||
return std::__uses_allocator_construction_args<_Pair>(__alloc, piecewise_construct, tuple<>{}, tuple<>{});
|
||||
}
|
||||
|
||||
template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, _Up&& __u, _Vp&& __v) noexcept {
|
||||
return std::__uses_allocator_construction_args<_Pair>(
|
||||
__alloc,
|
||||
piecewise_construct,
|
||||
std::forward_as_tuple(std::forward<_Up>(__u)),
|
||||
std::forward_as_tuple(std::forward<_Vp>(__v)));
|
||||
}
|
||||
|
||||
# if _LIBCPP_STD_VER > 20
|
||||
template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>& __pair) noexcept {
|
||||
return std::__uses_allocator_construction_args<_Pair>(
|
||||
__alloc, piecewise_construct, std::forward_as_tuple(__pair.first), std::forward_as_tuple(__pair.second));
|
||||
}
|
||||
# endif
|
||||
|
||||
template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>& __pair) noexcept {
|
||||
return std::__uses_allocator_construction_args<_Pair>(
|
||||
__alloc, piecewise_construct, std::forward_as_tuple(__pair.first), std::forward_as_tuple(__pair.second));
|
||||
}
|
||||
|
||||
template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>&& __pair) noexcept {
|
||||
return std::__uses_allocator_construction_args<_Pair>(
|
||||
__alloc,
|
||||
piecewise_construct,
|
||||
std::forward_as_tuple(std::get<0>(std::move(__pair))),
|
||||
std::forward_as_tuple(std::get<1>(std::move(__pair))));
|
||||
}
|
||||
|
||||
# if _LIBCPP_STD_VER > 20
|
||||
template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>&& __pair) noexcept {
|
||||
return std::__uses_allocator_construction_args<_Pair>(
|
||||
__alloc,
|
||||
piecewise_construct,
|
||||
std::forward_as_tuple(std::get<0>(std::move(__pair))),
|
||||
std::forward_as_tuple(std::get<1>(std::move(__pair))));
|
||||
}
|
||||
# endif
|
||||
|
||||
namespace __uses_allocator_detail {
|
||||
|
||||
template <class _Ap, class _Bp>
|
||||
void __fun(const pair<_Ap, _Bp>&);
|
||||
|
||||
template <class _Tp>
|
||||
decltype(__uses_allocator_detail::__fun(std::declval<_Tp>()), true_type()) __convertible_to_const_pair_ref_impl(int);
|
||||
|
||||
template <class>
|
||||
false_type __convertible_to_const_pair_ref_impl(...);
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool __convertible_to_const_pair_ref =
|
||||
decltype(__uses_allocator_detail::__convertible_to_const_pair_ref_impl<_Tp>(0))::value;
|
||||
|
||||
} // namespace __uses_allocator_detail
|
||||
|
||||
template <
|
||||
class _Pair,
|
||||
class _Alloc,
|
||||
class _Type,
|
||||
__enable_if_t<__is_std_pair<_Pair> && !__uses_allocator_detail::__convertible_to_const_pair_ref<_Type>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, _Type&& __value) noexcept;
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args);
|
||||
|
||||
template <class _Pair,
|
||||
class _Alloc,
|
||||
class _Type,
|
||||
__enable_if_t<__is_std_pair<_Pair> && !__uses_allocator_detail::__convertible_to_const_pair_ref<_Type>, int>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
__uses_allocator_construction_args(const _Alloc& __alloc, _Type&& __value) noexcept {
|
||||
struct __pair_constructor {
|
||||
using _PairMutable = remove_cv_t<_Pair>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __do_construct(const _PairMutable& __pair) const {
|
||||
return std::__make_obj_using_allocator<_PairMutable>(__alloc_, __pair);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __do_construct(_PairMutable&& __pair) const {
|
||||
return std::__make_obj_using_allocator<_PairMutable>(__alloc_, std::move(__pair));
|
||||
}
|
||||
|
||||
const _Alloc& __alloc_;
|
||||
_Type& __value_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator _PairMutable() const {
|
||||
return __do_construct(std::forward<_Type>(this->__value_));
|
||||
}
|
||||
};
|
||||
|
||||
return std::make_tuple(__pair_constructor{__alloc, __value});
|
||||
}
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args) {
|
||||
return std::make_from_tuple<_Type>(
|
||||
std::__uses_allocator_construction_args<_Type>(__alloc, std::forward<_Args>(__args)...));
|
||||
}
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Type*
|
||||
__uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Args&&... __args) {
|
||||
return std::apply(
|
||||
[&__ptr](auto&&... __xs) { return std::__construct_at(__ptr, std::forward<decltype(__xs)>(__xs)...); },
|
||||
std::__uses_allocator_construction_args<_Type>(__alloc, std::forward<_Args>(__args)...));
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 17
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto uses_allocator_construction_args(const _Alloc& __alloc, _Args&&... __args) noexcept
|
||||
-> decltype(std::__uses_allocator_construction_args<_Type>(__alloc, std::forward<_Args>(__args)...)) {
|
||||
return /*--*/ std::__uses_allocator_construction_args<_Type>(__alloc, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args)
|
||||
-> decltype(std::__make_obj_using_allocator<_Type>(__alloc, std::forward<_Args>(__args)...)) {
|
||||
return /*--*/ std::__make_obj_using_allocator<_Type>(__alloc, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template <class _Type, class _Alloc, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Args&&... __args)
|
||||
-> decltype(std::__uninitialized_construct_using_allocator(__ptr, __alloc, std::forward<_Args>(__args)...)) {
|
||||
return /*--*/ std::__uninitialized_construct_using_allocator(__ptr, __alloc, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H
|
@ -883,6 +883,7 @@ template<size_t N, class T>
|
||||
#include <__memory/uninitialized_algorithms.h>
|
||||
#include <__memory/unique_ptr.h>
|
||||
#include <__memory/uses_allocator.h>
|
||||
#include <__memory/uses_allocator_construction.h>
|
||||
#include <version>
|
||||
|
||||
// standard-mandated includes
|
||||
|
@ -878,6 +878,7 @@ module std [system] {
|
||||
module uninitialized_algorithms { private header "__memory/uninitialized_algorithms.h" }
|
||||
module unique_ptr { private header "__memory/unique_ptr.h" }
|
||||
module uses_allocator { private header "__memory/uses_allocator.h" }
|
||||
module uses_allocator_construction { private header "__memory/uses_allocator_construction.h" }
|
||||
module voidify { private header "__memory/voidify.h" }
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
|
||||
#include <__assert> // all public C++ headers provide the assertion handler
|
||||
#include <__config>
|
||||
#include <__memory/allocator_traits.h>
|
||||
#include <__memory/uses_allocator_construction.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/integral_constant.h>
|
||||
@ -523,6 +524,18 @@ public:
|
||||
size_type max_size() const
|
||||
{return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
template <class _Type, class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI void construct(_Type* __ptr, _Args&&... __args) {
|
||||
using _OM = __outermost<outer_allocator_type>;
|
||||
std::apply(
|
||||
[__ptr, this](auto&&... __newargs) {
|
||||
allocator_traits<typename _OM::type>::construct(
|
||||
_OM()(outer_allocator()), __ptr, std::forward<decltype(__newargs)>(__newargs)...);
|
||||
},
|
||||
std::uses_allocator_construction_args<_Type>(inner_allocator(), std::forward<_Args>(__args)...));
|
||||
}
|
||||
#else
|
||||
template <class _Tp, class... _Args>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void construct(_Tp* __p, _Args&& ...__args)
|
||||
@ -577,6 +590,7 @@ public:
|
||||
_VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
|
||||
_VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -443,6 +443,7 @@ END-SCRIPT
|
||||
#include <__memory/uninitialized_algorithms.h> // expected-error@*:* {{use of private header from outside its module: '__memory/uninitialized_algorithms.h'}}
|
||||
#include <__memory/unique_ptr.h> // expected-error@*:* {{use of private header from outside its module: '__memory/unique_ptr.h'}}
|
||||
#include <__memory/uses_allocator.h> // expected-error@*:* {{use of private header from outside its module: '__memory/uses_allocator.h'}}
|
||||
#include <__memory/uses_allocator_construction.h> // expected-error@*:* {{use of private header from outside its module: '__memory/uses_allocator_construction.h'}}
|
||||
#include <__memory/voidify.h> // expected-error@*:* {{use of private header from outside its module: '__memory/voidify.h'}}
|
||||
#include <__mutex_base> // expected-error@*:* {{use of private header from outside its module: '__mutex_base'}}
|
||||
#include <__node_handle> // expected-error@*:* {{use of private header from outside its module: '__node_handle'}}
|
||||
|
@ -479,6 +479,7 @@ memory iosfwd
|
||||
memory limits
|
||||
memory new
|
||||
memory stdexcept
|
||||
memory tuple
|
||||
memory type_traits
|
||||
memory typeinfo
|
||||
memory version
|
||||
|
|
@ -115,10 +115,10 @@ struct G
|
||||
{
|
||||
static bool constructed;
|
||||
|
||||
typedef std::allocator<G> allocator_type;
|
||||
typedef std::scoped_allocator_adaptor<std::allocator<G>> allocator_type;
|
||||
|
||||
G(std::allocator_arg_t, allocator_type&&) { assert(false); }
|
||||
G(allocator_type&) { constructed = true; }
|
||||
G(const allocator_type&) { constructed = true; }
|
||||
};
|
||||
|
||||
bool G::constructed = false;
|
||||
@ -202,7 +202,7 @@ int main(int, char**)
|
||||
// Test that is_constructible uses an lvalue ref so the correct constructor
|
||||
// is picked.
|
||||
{
|
||||
std::scoped_allocator_adaptor<G::allocator_type> sa;
|
||||
G::allocator_type sa;
|
||||
G* ptr = sa.allocate(1);
|
||||
sa.construct(ptr);
|
||||
assert(G::constructed);
|
||||
|
@ -46,10 +46,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr);
|
||||
assert(checkConstruct<>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<>(ptr->second, UA_AllocLast, CA));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&>&&,
|
||||
std::tuple<const SA&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&>&&,
|
||||
std::tuple<SA&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
|
||||
@ -69,10 +76,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr);
|
||||
assert(checkConstruct<>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&>&&,
|
||||
std::tuple<>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&>&&,
|
||||
std::tuple<>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -102,10 +116,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr);
|
||||
assert(checkConstruct<>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<>(ptr->second, UA_AllocLast));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&>&&,
|
||||
std::tuple<const SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&>&&,
|
||||
std::tuple<SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -129,10 +150,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr);
|
||||
assert(checkConstruct<>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&>&&,
|
||||
std::tuple<>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&>&&,
|
||||
std::tuple<>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
|
@ -50,10 +50,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr, in);
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_AllocLast, CA));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&>&&,
|
||||
std::tuple<int const&, const SA&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&>&&,
|
||||
std::tuple<int const&, SA&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
|
||||
@ -77,10 +84,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr, in);
|
||||
assert(checkConstruct<int const&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int const&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int const&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -114,10 +128,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr, in);
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_AllocLast));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&>&&,
|
||||
std::tuple<int const&, const SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
|
||||
std::tuple<int const&, SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -145,10 +166,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr, in);
|
||||
assert(checkConstruct<int const&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int const&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int const&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
|
@ -51,10 +51,17 @@ void test_no_inner_alloc()
|
||||
std::forward_as_tuple(std::move(y)));
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&>&&,
|
||||
std::tuple<int const&&, const SA&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&>&&,
|
||||
std::tuple<int const&&, SA&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
|
||||
@ -78,10 +85,17 @@ void test_no_inner_alloc()
|
||||
std::forward_as_tuple(y));
|
||||
assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -115,10 +129,17 @@ void test_with_inner_alloc()
|
||||
std::forward_as_tuple(std::move(y)));
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&>&&,
|
||||
std::tuple<int &&, const SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
|
||||
std::tuple<int &&, SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -146,10 +167,17 @@ void test_with_inner_alloc()
|
||||
std::forward_as_tuple(std::move(y)));
|
||||
assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int const&&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&&>&&,
|
||||
std::tuple<int const&&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
|
||||
std::tuple<int const&&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
|
@ -50,10 +50,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr, std::move(in));
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&>&&,
|
||||
std::tuple<int const&&, const SA&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&>&&,
|
||||
std::tuple<int const&&, SA&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
|
||||
@ -77,10 +84,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr, std::move(in));
|
||||
assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -114,10 +128,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr, std::move(in));
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&>&&,
|
||||
std::tuple<int const&&, const SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
|
||||
std::tuple<int const&&, SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -145,10 +166,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr, std::move(in));
|
||||
assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
|
@ -48,10 +48,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr, x, std::move(y));
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&>&&,
|
||||
std::tuple<int const&&, const SA&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&>&&,
|
||||
std::tuple<int const&&, SA&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
|
||||
@ -73,10 +80,17 @@ void test_no_inner_alloc()
|
||||
A.construct(ptr, std::move(x), y);
|
||||
assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
|
||||
assert(checkConstruct<int const&>(ptr->second, UA_None));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((P.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SA&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#else
|
||||
assert((P.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SA&, int&&>&&,
|
||||
std::tuple<int const&>&&
|
||||
>(CA, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -108,10 +122,17 @@ void test_with_inner_alloc()
|
||||
A.construct(ptr, x, std::move(y));
|
||||
assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
|
||||
assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&>&&,
|
||||
std::tuple<int &&, const SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
|
||||
std::tuple<int &&, SAInner&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
@ -137,10 +158,17 @@ void test_with_inner_alloc()
|
||||
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));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t&&,
|
||||
std::tuple<std::allocator_arg_t, const SAInner&, int&&>&&,
|
||||
std::tuple<int const&&>&&
|
||||
>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::piecewise_construct_t const&,
|
||||
std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
|
||||
std::tuple<int const&&>&&
|
||||
>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
std::free(ptr);
|
||||
}
|
||||
|
@ -84,8 +84,13 @@ void test_bullet_two() {
|
||||
int const& cx = x;
|
||||
A.construct(ptr, x, cx, std::move(x));
|
||||
assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocArg, I)));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<std::allocator_arg_t&&,
|
||||
const SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<std::allocator_arg_t const&,
|
||||
SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
::operator delete((void*)ptr);
|
||||
}
|
||||
@ -117,9 +122,15 @@ void test_bullet_three() {
|
||||
int const& cx = x;
|
||||
A.construct(ptr, x, cx, std::move(x));
|
||||
assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I)));
|
||||
#if TEST_STD_VER >= 20
|
||||
assert((POuter.checkConstruct<
|
||||
int&, int const&, int&&,
|
||||
const SA::inner_allocator_type&>(O, ptr)));
|
||||
#else
|
||||
assert((POuter.checkConstruct<
|
||||
int&, int const&, int&&,
|
||||
SA::inner_allocator_type&>(O, ptr)));
|
||||
#endif
|
||||
A.destroy(ptr);
|
||||
::operator delete((void*)ptr);
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "test_allocator.h"
|
||||
|
||||
using Alloc = test_allocator<int>;
|
||||
|
||||
enum class RefType {
|
||||
LValue,
|
||||
ConstLValue,
|
||||
RValue,
|
||||
ConstRValue,
|
||||
};
|
||||
|
||||
struct UsesAllocArgT {
|
||||
using allocator_type = Alloc;
|
||||
|
||||
bool allocator_constructed_ = false;
|
||||
Alloc a_;
|
||||
const Alloc& alloc_ = a_;
|
||||
const int* val_ptr_;
|
||||
RefType ref_type_;
|
||||
|
||||
constexpr UsesAllocArgT() = default;
|
||||
constexpr UsesAllocArgT(std::allocator_arg_t, const Alloc& alloc) : allocator_constructed_(true), alloc_(alloc) {}
|
||||
constexpr UsesAllocArgT(std::allocator_arg_t, const Alloc& alloc, int& val)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::LValue) {}
|
||||
constexpr UsesAllocArgT(std::allocator_arg_t, const Alloc& alloc, const int& val)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::ConstLValue) {}
|
||||
constexpr UsesAllocArgT(std::allocator_arg_t, const Alloc& alloc, int&& val)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::RValue) {}
|
||||
constexpr UsesAllocArgT(std::allocator_arg_t, const Alloc& alloc, const int&& val)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::ConstRValue) {}
|
||||
};
|
||||
|
||||
struct UsesAllocLast {
|
||||
using allocator_type = Alloc;
|
||||
|
||||
bool allocator_constructed_ = false;
|
||||
Alloc a_;
|
||||
const Alloc& alloc_ = a_;
|
||||
const int* val_ptr_;
|
||||
RefType ref_type_;
|
||||
|
||||
constexpr UsesAllocLast() = default;
|
||||
constexpr UsesAllocLast(const Alloc& alloc) : allocator_constructed_(true), alloc_(alloc) {}
|
||||
constexpr UsesAllocLast(int& val, const Alloc& alloc)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::LValue) {}
|
||||
constexpr UsesAllocLast(const int& val, const Alloc& alloc)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::ConstLValue) {}
|
||||
constexpr UsesAllocLast(int&& val, const Alloc& alloc)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::RValue) {}
|
||||
constexpr UsesAllocLast(const int&& val, const Alloc& alloc)
|
||||
: allocator_constructed_(true), alloc_(alloc), val_ptr_(&val), ref_type_(RefType::ConstRValue) {}
|
||||
};
|
||||
|
||||
struct NotAllocatorAware {
|
||||
bool allocator_constructed_ = false;
|
||||
|
||||
constexpr NotAllocatorAware() = default;
|
||||
constexpr NotAllocatorAware(const Alloc&) : allocator_constructed_(true) {}
|
||||
constexpr NotAllocatorAware(const Alloc&, int) : allocator_constructed_(true) {}
|
||||
};
|
||||
|
||||
struct ConvertibleToPair {
|
||||
constexpr operator std::pair<int, int>() const { return {1, 2}; }
|
||||
};
|
@ -0,0 +1,139 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// template<class T, class Alloc, class... Args>
|
||||
// constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "common.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
constexpr bool test() {
|
||||
Alloc a(12);
|
||||
{
|
||||
std::same_as<UsesAllocArgT> auto ret = std::make_obj_using_allocator<UsesAllocArgT>(a);
|
||||
assert(ret.allocator_constructed_);
|
||||
assert(&ret.alloc_ == &a);
|
||||
}
|
||||
{
|
||||
std::same_as<UsesAllocLast> auto ret = std::make_obj_using_allocator<UsesAllocLast>(a);
|
||||
assert(ret.allocator_constructed_);
|
||||
assert(&ret.alloc_ == &a);
|
||||
}
|
||||
{
|
||||
std::same_as<NotAllocatorAware> auto ret = std::make_obj_using_allocator<NotAllocatorAware>(a);
|
||||
assert(!ret.allocator_constructed_);
|
||||
}
|
||||
{
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(
|
||||
a, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
}
|
||||
{
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(a);
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
}
|
||||
{
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(a, 0, 0);
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(a, p);
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.first.ref_type_ == RefType::LValue);
|
||||
assert(ret.first.val_ptr_ == &p.first);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
assert(ret.second.ref_type_ == RefType::LValue);
|
||||
assert(ret.second.val_ptr_ == &p.second);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(a, std::as_const(p));
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.first.ref_type_ == RefType::ConstLValue);
|
||||
assert(ret.first.val_ptr_ == &p.first);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
assert(ret.second.ref_type_ == RefType::ConstLValue);
|
||||
assert(ret.second.val_ptr_ == &p.second);
|
||||
}
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(a, std::move(p));
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.first.ref_type_ == RefType::RValue);
|
||||
assert(ret.first.val_ptr_ == &p.first);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
assert(ret.second.ref_type_ == RefType::RValue);
|
||||
assert(ret.second.val_ptr_ == &p.second);
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>> auto ret =
|
||||
std::make_obj_using_allocator<std::pair<UsesAllocArgT, UsesAllocLast>>(a, std::move(std::as_const(p)));
|
||||
assert(ret.first.allocator_constructed_);
|
||||
assert(&ret.first.alloc_ == &a);
|
||||
assert(ret.first.ref_type_ == RefType::ConstRValue);
|
||||
assert(ret.first.val_ptr_ == &p.first);
|
||||
assert(ret.second.allocator_constructed_);
|
||||
assert(&ret.second.alloc_ == &a);
|
||||
assert(ret.second.ref_type_ == RefType::ConstRValue);
|
||||
assert(ret.second.val_ptr_ == &p.second);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
ConvertibleToPair ctp;
|
||||
std::same_as<std::pair<int, int>> auto ret = std::make_obj_using_allocator<std::pair<int, int>>(a, ctp);
|
||||
assert(ret.first == 1);
|
||||
assert(ret.second == 2);
|
||||
}
|
||||
{
|
||||
ConvertibleToPair ctp;
|
||||
std::same_as<std::pair<int, int>> auto ret = std::make_obj_using_allocator<std::pair<int, int>>(a, std::move(ctp));
|
||||
assert(ret.first == 1);
|
||||
assert(ret.second == 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// template<class T, class Alloc, class... Args>
|
||||
// constexpr T uninitialized_construct_using_allocator(const Alloc& alloc, Args&&... args);
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "common.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
constexpr bool test() {
|
||||
Alloc a(12);
|
||||
{
|
||||
auto* ptr = std::allocator<UsesAllocArgT>{}.allocate(1);
|
||||
std::same_as<UsesAllocArgT*> auto ret = std::uninitialized_construct_using_allocator(ptr, a);
|
||||
assert(ret == ptr);
|
||||
assert(ret->allocator_constructed_);
|
||||
assert(&ret->alloc_ == &a);
|
||||
std::allocator<UsesAllocArgT>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
auto* ptr = std::allocator<UsesAllocLast>{}.allocate(1);
|
||||
std::same_as<UsesAllocLast*> auto ret = std::uninitialized_construct_using_allocator(ptr, a);
|
||||
assert(ret->allocator_constructed_);
|
||||
assert(&ret->alloc_ == &a);
|
||||
std::allocator<UsesAllocLast>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
auto* ptr = std::allocator<NotAllocatorAware>{}.allocate(1);
|
||||
std::same_as<NotAllocatorAware*> auto ret = std::uninitialized_construct_using_allocator(ptr, a);
|
||||
assert(!ret->allocator_constructed_);
|
||||
std::allocator<NotAllocatorAware>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a);
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
int val = 0;
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, val, val);
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->first.ref_type_ == RefType::LValue);
|
||||
assert(ret->first.val_ptr_ == &val);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
assert(ret->second.ref_type_ == RefType::LValue);
|
||||
assert(ret->second.val_ptr_ == &val);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
int val = 0;
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, std::move(val), std::move(val));
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->first.ref_type_ == RefType::RValue);
|
||||
assert(ret->first.val_ptr_ == &val);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
assert(ret->second.ref_type_ == RefType::RValue);
|
||||
assert(ret->second.val_ptr_ == &val);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, p);
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->first.ref_type_ == RefType::LValue);
|
||||
assert(ret->first.val_ptr_ == &p.first);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
assert(ret->second.ref_type_ == RefType::LValue);
|
||||
assert(ret->second.val_ptr_ == &p.second);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, std::as_const(p));
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->first.ref_type_ == RefType::ConstLValue);
|
||||
assert(ret->first.val_ptr_ == &p.first);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
assert(ret->second.ref_type_ == RefType::ConstLValue);
|
||||
assert(ret->second.val_ptr_ == &p.second);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, std::move(p));
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->first.ref_type_ == RefType::RValue);
|
||||
assert(ret->first.val_ptr_ == &p.first);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
assert(ret->second.ref_type_ == RefType::RValue);
|
||||
assert(ret->second.val_ptr_ == &p.second);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
std::pair p{0, 0};
|
||||
auto* ptr = std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.allocate(1);
|
||||
std::same_as<std::pair<UsesAllocArgT, UsesAllocLast>*> auto ret =
|
||||
std::uninitialized_construct_using_allocator(ptr, a, std::move(std::as_const(p)));
|
||||
assert(ret->first.allocator_constructed_);
|
||||
assert(&ret->first.alloc_ == &a);
|
||||
assert(ret->first.ref_type_ == RefType::ConstRValue);
|
||||
assert(ret->first.val_ptr_ == &p.first);
|
||||
assert(ret->second.allocator_constructed_);
|
||||
assert(&ret->second.alloc_ == &a);
|
||||
assert(ret->second.ref_type_ == RefType::ConstRValue);
|
||||
assert(ret->second.val_ptr_ == &p.second);
|
||||
std::allocator<std::pair<UsesAllocArgT, UsesAllocLast>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
ConvertibleToPair ctp;
|
||||
auto* ptr = std::allocator<std::pair<int, int>>{}.allocate(1);
|
||||
std::same_as<std::pair<int, int>*> auto ret = std::uninitialized_construct_using_allocator(ptr, a, ctp);
|
||||
assert(ret == ptr);
|
||||
assert(ret->first == 1);
|
||||
assert(ret->second == 2);
|
||||
std::allocator<std::pair<int, int>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
{
|
||||
ConvertibleToPair ctp;
|
||||
auto* ptr = std::allocator<std::pair<int, int>>{}.allocate(1);
|
||||
std::same_as<std::pair<int, int>*> auto ret = std::uninitialized_construct_using_allocator(ptr, a, std::move(ctp));
|
||||
assert(ret == ptr);
|
||||
assert(ret->first == 1);
|
||||
assert(ret->second == 2);
|
||||
std::allocator<std::pair<int, int>>{}.deallocate(ptr, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// template<class T, class Alloc, ...>
|
||||
// constexpr auto uses_allocator_construction_args(const Alloc& alloc, ...) noexcept;
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "common.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
template <class Type, class... Args>
|
||||
constexpr decltype(auto) test_uses_allocator_construction_args(Args&&... args) {
|
||||
static_assert(noexcept(std::uses_allocator_construction_args<Type>(std::forward<Args>(args)...)));
|
||||
return std::uses_allocator_construction_args<Type>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
constexpr bool test() {
|
||||
Alloc a(12);
|
||||
{
|
||||
std::same_as<std::tuple<std::allocator_arg_t, const Alloc&>> auto ret =
|
||||
test_uses_allocator_construction_args<UsesAllocArgT>(a);
|
||||
assert(std::get<1>(ret).get_data() == 12);
|
||||
}
|
||||
{
|
||||
std::same_as<std::tuple<const Alloc&>> auto ret = test_uses_allocator_construction_args<UsesAllocLast>(a);
|
||||
assert(std::get<0>(ret).get_data() == 12);
|
||||
}
|
||||
{
|
||||
[[maybe_unused]] std::same_as<std::tuple<>> auto ret = test_uses_allocator_construction_args<NotAllocatorAware>(a);
|
||||
}
|
||||
{
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&>,
|
||||
std::tuple<const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(
|
||||
a, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<0>(std::get<2>(ret)).get_data() == 12);
|
||||
}
|
||||
{
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&>,
|
||||
std::tuple<const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(a);
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<0>(std::get<2>(ret)).get_data() == 12);
|
||||
}
|
||||
{
|
||||
int val = 0;
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&, int&>,
|
||||
std::tuple<int&, const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(a, val, val);
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<1>(std::get<2>(ret)).get_data() == 12);
|
||||
assert(&std::get<2>(std::get<1>(ret)) == &val);
|
||||
assert(&std::get<0>(std::get<2>(ret)) == &val);
|
||||
}
|
||||
{
|
||||
int val = 0;
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&, int&&>,
|
||||
std::tuple<int&&, const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(
|
||||
a, std::move(val), std::move(val));
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<1>(std::get<2>(ret)).get_data() == 12);
|
||||
assert(&std::get<2>(std::get<1>(ret)) == &val);
|
||||
assert(&std::get<0>(std::get<2>(ret)) == &val);
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
std::pair p{3, 4};
|
||||
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&, int&>,
|
||||
std::tuple<int&, const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(a, p);
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<1>(std::get<2>(ret)).get_data() == 12);
|
||||
assert(std::get<2>(std::get<1>(ret)) == 3);
|
||||
assert(std::get<0>(std::get<2>(ret)) == 4);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
std::pair p{3, 4};
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&, const int&>,
|
||||
std::tuple<const int&, const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(a, std::as_const(p));
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<1>(std::get<2>(ret)).get_data() == 12);
|
||||
assert(std::get<2>(std::get<1>(ret)) == 3);
|
||||
assert(std::get<0>(std::get<2>(ret)) == 4);
|
||||
}
|
||||
{
|
||||
std::pair p{3, 4};
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&, int&&>,
|
||||
std::tuple<int&&, const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(a, std::move(p));
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<1>(std::get<2>(ret)).get_data() == 12);
|
||||
assert(std::get<2>(std::get<1>(ret)) == 3);
|
||||
assert(std::get<0>(std::get<2>(ret)) == 4);
|
||||
}
|
||||
#if TEST_STD_VER >= 23
|
||||
{
|
||||
std::pair p{3, 4};
|
||||
std::same_as<std::tuple<std::piecewise_construct_t,
|
||||
std::tuple<std::allocator_arg_t, const Alloc&, const int&&>,
|
||||
std::tuple<const int&&, const Alloc&>>> auto ret =
|
||||
test_uses_allocator_construction_args<std::pair<UsesAllocArgT, UsesAllocLast>>(a, std::move(std::as_const(p)));
|
||||
assert(std::get<1>(std::get<1>(ret)).get_data() == 12);
|
||||
assert(std::get<1>(std::get<2>(ret)).get_data() == 12);
|
||||
assert(std::get<2>(std::get<1>(ret)) == 3);
|
||||
assert(std::get<0>(std::get<2>(ret)) == 4);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
ConvertibleToPair ctp {};
|
||||
auto ret = test_uses_allocator_construction_args<std::pair<int, int>>(a, ctp);
|
||||
std::pair<int, int> v = std::get<0>(ret);
|
||||
assert(std::get<0>(v) == 1);
|
||||
assert(std::get<1>(v) == 2);
|
||||
}
|
||||
{
|
||||
ConvertibleToPair ctp {};
|
||||
auto ret = test_uses_allocator_construction_args<std::pair<int, int>>(a, std::move(ctp));
|
||||
std::pair<int, int> v = std::get<0>(ret);
|
||||
assert(std::get<0>(v) == 1);
|
||||
assert(std::get<1>(v) == 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
}
|
@ -23,7 +23,7 @@ public:
|
||||
MoveOnly(const MoveOnly&) = delete;
|
||||
MoveOnly& operator=(const MoveOnly&) = delete;
|
||||
|
||||
TEST_CONSTEXPR_CXX14 MoveOnly(MoveOnly&& x)
|
||||
TEST_CONSTEXPR_CXX14 MoveOnly(MoveOnly&& x) TEST_NOEXCEPT
|
||||
: data_(x.data_) {x.data_ = 0;}
|
||||
TEST_CONSTEXPR_CXX14 MoveOnly& operator=(MoveOnly&& x)
|
||||
{data_ = x.data_; x.data_ = 0; return *this;}
|
||||
|
Loading…
Reference in New Issue
Block a user