зеркало из https://github.com/microsoft/STL.git
`<list>`, `<string>`: Remove allocator-moving tagged internal constructors (#4976)
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
This commit is contained in:
Родитель
722e1507c8
Коммит
1c3e0d6509
|
@ -751,6 +751,10 @@ private:
|
|||
template <class _Traits>
|
||||
class _Hash;
|
||||
|
||||
struct _Move_allocator_tag {
|
||||
explicit _Move_allocator_tag() = default;
|
||||
};
|
||||
|
||||
_EXPORT_STD template <class _Ty, class _Alloc = allocator<_Ty>>
|
||||
class list { // bidirectional linked list
|
||||
private:
|
||||
|
@ -804,8 +808,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
template <class _Any_alloc>
|
||||
explicit list(_Move_allocator_tag, _Any_alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _STD move(_Al)) {
|
||||
template <class _Tag, class _Any_alloc, enable_if_t<is_same_v<_Tag, _Move_allocator_tag>, int> = 0>
|
||||
explicit list(_Tag, _Any_alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _STD move(_Al)) {
|
||||
_Alloc_sentinel_and_proxy();
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ public:
|
|||
// the buffer may already be full, and the terminating char is not '\0'.
|
||||
// In that case, copy the string as usual.
|
||||
_NODISCARD _Mystr str() && {
|
||||
_Mystr _Result{_String_constructor_rvalue_allocator_tag{}, _STD move(_Al)};
|
||||
_Mystr _Result{_Al};
|
||||
const auto _View = _Get_buffer_view();
|
||||
// _Size cannot be larger than _Res, but it could be equal,
|
||||
// because basic_stringbuf doesn't allocate for the terminating '\0'.
|
||||
|
|
|
@ -1535,10 +1535,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct _Move_allocator_tag {
|
||||
explicit _Move_allocator_tag() = default;
|
||||
};
|
||||
|
||||
template <class _Ty>
|
||||
pair<_Ty*, ptrdiff_t> _Get_temporary_buffer(ptrdiff_t _Count) noexcept {
|
||||
if (static_cast<size_t>(_Count) <= static_cast<size_t>(-1) / sizeof(_Ty)) {
|
||||
|
|
|
@ -508,11 +508,6 @@ struct _String_constructor_concat_tag {
|
|||
explicit _String_constructor_concat_tag() = default;
|
||||
};
|
||||
|
||||
struct _String_constructor_rvalue_allocator_tag {
|
||||
// tag to select constructors used by basic_stringbuf's rvalue str()
|
||||
explicit _String_constructor_rvalue_allocator_tag() = default;
|
||||
};
|
||||
|
||||
[[noreturn]] inline void _Xlen_string() {
|
||||
_Xlength_error("string too long");
|
||||
}
|
||||
|
@ -1145,12 +1140,6 @@ public:
|
|||
#endif // _HAS_CXX17
|
||||
|
||||
#if _HAS_CXX20
|
||||
basic_string(_String_constructor_rvalue_allocator_tag, _Alloc&& _Al)
|
||||
: _Mypair(_One_then_variadic_args_t{}, _STD move(_Al)) {
|
||||
// Used exclusively by basic_stringbuf
|
||||
_Construct_empty();
|
||||
}
|
||||
|
||||
_NODISCARD bool _Move_assign_from_buffer(
|
||||
_Elem* const _Right, const size_type _Size, const size_type _Actual_allocation_size) {
|
||||
// Move assign from a buffer, used exclusively by basic_stringbuf; returns _Large_mode_engaged()
|
||||
|
|
|
@ -250,6 +250,7 @@ tests\GH_004618_mixed_operator_usage_keeps_statistical_properties
|
|||
tests\GH_004618_normal_distribution_avoids_resets
|
||||
tests\GH_004657_expected_constraints_permissive
|
||||
tests\GH_004845_logical_operator_traits_with_non_bool_constant
|
||||
tests\GH_004929_internal_tag_constructors
|
||||
tests\GH_004930_char_traits_user_specialization
|
||||
tests\LWG2381_num_get_floating_point
|
||||
tests\LWG2597_complex_branch_cut
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\impure_matrix.lst
|
|
@ -0,0 +1,93 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#if _HAS_CXX17
|
||||
#include <string_view>
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
#if _HAS_CXX20
|
||||
#define CONSTEXPR20 constexpr
|
||||
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
|
||||
#define CONSTEXPR20 inline
|
||||
#endif // ^^^ !_HAS_CXX20 ^^^
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <class>
|
||||
constexpr bool is_initializer_list = false;
|
||||
template <class T>
|
||||
constexpr bool is_initializer_list<initializer_list<T>> = true;
|
||||
|
||||
template <class T>
|
||||
constexpr initializer_list<T> ilist42 = {T{'4'}, T{'2'}};
|
||||
|
||||
template <class>
|
||||
constexpr bool is_basic_string_or_cstr_or_view = false;
|
||||
template <class C, class T, class A>
|
||||
constexpr bool is_basic_string_or_cstr_or_view<basic_string<C, T, A>> = true;
|
||||
template <class C>
|
||||
constexpr bool is_basic_string_or_cstr_or_view<const C*> = true;
|
||||
#if _HAS_CXX17
|
||||
template <class C, class T>
|
||||
constexpr bool is_basic_string_or_cstr_or_view<basic_string_view<C, T>> = true;
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
struct nasty_string_source {
|
||||
template <class IList, enable_if_t<is_initializer_list<IList>, int> = 0>
|
||||
constexpr operator IList() const {
|
||||
return ilist42<typename IList::value_type>;
|
||||
}
|
||||
|
||||
template <class T, enable_if_t<!is_initializer_list<T> && !is_basic_string_or_cstr_or_view<T>, int> = 0>
|
||||
constexpr operator T() const {
|
||||
return T{};
|
||||
}
|
||||
};
|
||||
|
||||
CONSTEXPR20 bool test_nasty_conversion_to_basic_string() {
|
||||
assert(string(nasty_string_source{}, allocator<char>{}) == "42"s);
|
||||
#ifdef __cpp_char8_t
|
||||
assert(u8string(nasty_string_source{}, allocator<char8_t>{}) == u8"42"s);
|
||||
#endif // defined(__cpp_char8_t)
|
||||
assert(u16string(nasty_string_source{}, allocator<char16_t>{}) == u"42"s);
|
||||
assert(u32string(nasty_string_source{}, allocator<char32_t>{}) == U"42"s);
|
||||
assert(wstring(nasty_string_source{}, allocator<wchar_t>{}) == L"42"s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class>
|
||||
constexpr bool is_list = false;
|
||||
template <class T, class A>
|
||||
constexpr bool is_list<list<T, A>> = true;
|
||||
|
||||
struct nasty_list_source {
|
||||
template <class IList, enable_if_t<is_initializer_list<IList>, int> = 0>
|
||||
constexpr operator IList() const {
|
||||
return ilist42<typename IList::value_type>;
|
||||
}
|
||||
|
||||
template <class T, enable_if_t<!is_initializer_list<T> && !is_list<T> && !is_integral_v<T>, int> = 0>
|
||||
constexpr operator T() const {
|
||||
return T{};
|
||||
}
|
||||
};
|
||||
|
||||
void test_nasty_conversion_to_list() {
|
||||
allocator<int> ator{};
|
||||
assert((list<int>{nasty_list_source{}, ator} == list<int>{int{'4'}, int{'2'}}));
|
||||
}
|
||||
|
||||
#if _HAS_CXX20
|
||||
static_assert(test_nasty_conversion_to_basic_string());
|
||||
#endif // _HAS_CXX20
|
||||
|
||||
int main() {
|
||||
test_nasty_conversion_to_basic_string();
|
||||
test_nasty_conversion_to_list();
|
||||
}
|
Загрузка…
Ссылка в новой задаче