_CONSTEXPR20 _Copy_s, simplify char8_t compare. (#861)

This commit is contained in:
Stephan T. Lavavej 2020-05-29 17:41:49 -07:00 коммит произвёл GitHub
Родитель 3ad64fc201
Коммит 191b184004
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 86 добавлений и 13 удалений

Просмотреть файл

@ -65,7 +65,8 @@ struct _Char_traits { // properties of a string or stream element
return _First1;
}
_Pre_satisfies_(_Dest_size >= _Count) static _Elem* _Copy_s(_Out_writes_all_(_Dest_size) _Elem* const _First1,
_Pre_satisfies_(_Dest_size >= _Count) static _CONSTEXPR20 _Elem* _Copy_s(_Out_writes_all_(_Dest_size)
_Elem* const _First1,
const size_t _Dest_size, _In_reads_(_Count) const _Elem* const _First2,
const size_t _Count) noexcept { // copy [_First2, _First2 + _Count) to [_First1, _First1 + _Dest_size)
_STL_VERIFY(_Count <= _Dest_size, "invalid argument");
@ -363,14 +364,7 @@ public:
_In_reads_(_Count) const _Elem* const _First2, const size_t _Count) noexcept /* strengthened */ {
// compare [_First1, _First1 + _Count) with [_First2, ...)
#if _HAS_CXX17
#if _HAS_U8_INTRINSICS
if constexpr (is_same_v<_Elem, char8_t>) {
return __builtin_u8memcmp(_First1, _First2, _Count);
} else
#endif // _HAS_U8_INTRINSICS
{
return __builtin_memcmp(_First1, _First2, _Count);
}
return __builtin_memcmp(_First1, _First2, _Count);
#else // _HAS_CXX17
return _CSTD memcmp(_First1, _First2, _Count);
#endif // _HAS_CXX17
@ -1373,8 +1367,9 @@ public:
return _Count;
}
_Pre_satisfies_(_Dest_size >= _Count) constexpr size_type _Copy_s(_Out_writes_all_(_Dest_size) _Elem* const _Dest,
const size_type _Dest_size, size_type _Count, const size_type _Off = 0) const {
_Pre_satisfies_(_Dest_size >= _Count) _CONSTEXPR20 size_type
_Copy_s(_Out_writes_all_(_Dest_size) _Elem* const _Dest, const size_type _Dest_size, size_type _Count,
const size_type _Off = 0) const {
// copy [_Off, _Off + _Count) to [_Dest, _Dest + _Count)
_Check_offset(_Off);
_Count = _Clamp_suffix_size(_Off, _Count);

Просмотреть файл

@ -1034,11 +1034,11 @@ static_assert(test_case_iterators<char, constexpr_char_traits>());
static_assert(test_case_prefix<char, constexpr_char_traits>());
static_assert(test_case_suffix<char, constexpr_char_traits>());
static_assert(test_case_swap<char, constexpr_char_traits>());
static_assert(test_case_Copy_s<constexpr_char_traits>());
static_assert(test_case_substr<constexpr_char_traits>());
static_assert(test_case_compare<char, constexpr_char_traits>());
#if _HAS_CXX20
static_assert(test_case_copy<constexpr_char_traits>());
static_assert(test_case_Copy_s<constexpr_char_traits>());
static_assert(test_case_starts_with_ends_with<char, constexpr_char_traits, false>());
#endif // _HAS_CXX20
static_assert(test_case_operators<char, constexpr_char_traits>());

Просмотреть файл

@ -272,7 +272,7 @@ constexpr bool run_tests() {
assert(last - first == static_cast<ptrdiff_t>(needle.size()));
}
// test char_traits move/copy/assign and basic_string_view::copy
// test char_traits assign/copy/_Copy_s/move and basic_string_view::copy/_Copy_s
{
using Elem = char;
using Traits = char_traits<Elem>;
@ -314,6 +314,15 @@ constexpr bool run_tests() {
assert(Traits::move(buf + 5, buf + 3, 11) == buf + 5); // overlapping, dest after src
assert(buf == "....a.ababcbabc.c.."sv);
assert(Traits::_Copy_s(buf, 20, src, 18) == buf);
assert(buf == "cute fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 4, 10) == 4);
assert(buf == "abc. fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 11) == 11);
assert(buf == "..........a KITTEN."sv);
}
{
@ -357,6 +366,15 @@ constexpr bool run_tests() {
assert(Traits::move(buf + 5, buf + 3, 11) == buf + 5); // overlapping, dest after src
assert(buf == u"....a.ababcbabc.c.."sv);
assert(Traits::_Copy_s(buf, 20, src, 18) == buf);
assert(buf == u"cute fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 4, 10) == 4);
assert(buf == u"abc. fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 11) == 11);
assert(buf == u"..........a KITTEN."sv);
}
{
@ -400,6 +418,15 @@ constexpr bool run_tests() {
assert(Traits::move(buf + 5, buf + 3, 11) == buf + 5); // overlapping, dest after src
assert(buf == U"....a.ababcbabc.c.."sv);
assert(Traits::_Copy_s(buf, 20, src, 18) == buf);
assert(buf == U"cute fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 4, 10) == 4);
assert(buf == U"abc. fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 11) == 11);
assert(buf == U"..........a KITTEN."sv);
}
{
@ -443,6 +470,15 @@ constexpr bool run_tests() {
assert(Traits::move(buf + 5, buf + 3, 11) == buf + 5); // overlapping, dest after src
assert(buf == L"....a.ababcbabc.c.."sv);
assert(Traits::_Copy_s(buf, 20, src, 18) == buf);
assert(buf == L"cute fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 4, 10) == 4);
assert(buf == L"abc. fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 11) == 11);
assert(buf == L"..........a KITTEN."sv);
}
#ifdef __cpp_lib_char8_t
@ -487,9 +523,51 @@ constexpr bool run_tests() {
assert(Traits::move(buf + 5, buf + 3, 11) == buf + 5); // overlapping, dest after src
assert(buf == u8"....a.ababcbabc.c.."sv);
assert(Traits::_Copy_s(buf, 20, src, 18) == buf);
assert(buf == u8"cute fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 4, 10) == 4);
assert(buf == u8"abc. fluffy KITTEN."sv);
assert(sv._Copy_s(buf, 20, 11) == 11);
assert(buf == u8"..........a KITTEN."sv);
}
#endif // __cpp_lib_char8_t
// test char_traits::compare refactoring through basic_string_view (not part of P1032R1)
{
assert("cat"sv == "cat"sv);
assert("cat"sv < "category"sv);
assert("catastrophe"sv > "cat"sv);
assert("catch"sv < "category"sv);
assert("catenary"sv > "catapult"sv);
assert(u"cat"sv == u"cat"sv);
assert(u"cat"sv < u"category"sv);
assert(u"catastrophe"sv > u"cat"sv);
assert(u"catch"sv < u"category"sv);
assert(u"catenary"sv > u"catapult"sv);
assert(U"cat"sv == U"cat"sv);
assert(U"cat"sv < U"category"sv);
assert(U"catastrophe"sv > U"cat"sv);
assert(U"catch"sv < U"category"sv);
assert(U"catenary"sv > U"catapult"sv);
assert(L"cat"sv == L"cat"sv);
assert(L"cat"sv < L"category"sv);
assert(L"catastrophe"sv > L"cat"sv);
assert(L"catch"sv < L"category"sv);
assert(L"catenary"sv > L"catapult"sv);
assert(u8"cat"sv == u8"cat"sv);
assert(u8"cat"sv < u8"category"sv);
assert(u8"catastrophe"sv > u8"cat"sv);
assert(u8"catch"sv < u8"category"sv);
assert(u8"catenary"sv > u8"catapult"sv);
}
return true;
}