зеркало из https://github.com/microsoft/STL.git
Родитель
b3976d3921
Коммит
26b06299b0
|
@ -4812,6 +4812,69 @@ _NODISCARD bool lexicographical_compare(
|
|||
}
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
#if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
// FUNCTION TEMPLATE lexicographical_compare_three_way
|
||||
template <class _InIt1, class _InIt2, class _Cmp>
|
||||
_NODISCARD constexpr auto lexicographical_compare_three_way(
|
||||
_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _Cmp _Comp) -> decltype(_Comp(*_First1, *_First2)) {
|
||||
_Adl_verify_range(_First1, _Last1);
|
||||
_Adl_verify_range(_First2, _Last2);
|
||||
auto _UFirst1 = _Get_unwrapped(_First1);
|
||||
const auto _ULast1 = _Get_unwrapped(_Last1);
|
||||
auto _UFirst2 = _Get_unwrapped(_First2);
|
||||
const auto _ULast2 = _Get_unwrapped(_Last2);
|
||||
using _UIt1 = decltype(_UFirst1);
|
||||
using _UIt2 = decltype(_UFirst2);
|
||||
using _Ty1 = remove_const_t<remove_pointer_t<_UIt1>>;
|
||||
using _Ty2 = remove_const_t<remove_pointer_t<_UIt2>>;
|
||||
|
||||
if constexpr (conjunction_v<is_same<_Cmp, compare_three_way>, is_pointer<_UIt1>, is_pointer<_UIt2>,
|
||||
disjunction<
|
||||
#ifdef __cpp_lib_byte
|
||||
conjunction<is_same<_Ty1, byte>, is_same<_Ty2, byte>>,
|
||||
#endif // __cpp_lib_byte
|
||||
conjunction<_Is_character<_Ty1>, is_unsigned<_Ty1>, _Is_character<_Ty2>,
|
||||
is_unsigned<_Ty2>>>>) {
|
||||
#ifdef __cpp_lib_is_constant_evaluated
|
||||
if (!_STD is_constant_evaluated())
|
||||
#endif // __cpp_lib_is_constant_evaluated
|
||||
{
|
||||
const auto _Num1 = static_cast<size_t>(_ULast1 - _UFirst1);
|
||||
const auto _Num2 = static_cast<size_t>(_ULast2 - _UFirst2);
|
||||
const int _Ans = _CSTD memcmp(_UFirst1, _UFirst2, (_STD min)(_Num1, _Num2));
|
||||
if (_Ans == 0) {
|
||||
return _Num1 <=> _Num2;
|
||||
} else {
|
||||
return _Ans <=> 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (_UFirst1 == _ULast1) {
|
||||
return _UFirst2 == _ULast2 ? strong_ordering::equal : strong_ordering::less;
|
||||
}
|
||||
|
||||
if (_UFirst2 == _ULast2) {
|
||||
return strong_ordering::greater;
|
||||
}
|
||||
|
||||
if (const auto _CmpResult = _Comp(*_UFirst1, *_UFirst2); _CmpResult != 0) {
|
||||
return _CmpResult;
|
||||
}
|
||||
|
||||
++_UFirst1;
|
||||
++_UFirst2;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _InIt1, class _InIt2>
|
||||
_NODISCARD constexpr auto lexicographical_compare_three_way(
|
||||
_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2) {
|
||||
return _STD lexicographical_compare_three_way(_First1, _Last1, _First2, _Last2, compare_three_way{});
|
||||
}
|
||||
#endif // defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
|
||||
// FUNCTION TEMPLATE find
|
||||
template <class _Ty>
|
||||
_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, true_type, true_type, _Any_tag) { // signed _Elem, signed _Ty
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <compare>
|
||||
#include <type_traits>
|
||||
|
@ -119,6 +121,74 @@ static_assert(test_common_type<std::strong_ordering, std::partial_ordering>());
|
|||
static_assert(test_common_type<std::strong_ordering, std::weak_ordering>());
|
||||
static_assert(test_common_type<std::strong_ordering, std::strong_ordering>());
|
||||
|
||||
#if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
constexpr auto my_cmp_three_way = [](const auto& left, const auto& right) { return left <=> right; };
|
||||
|
||||
template <class Left, class Right>
|
||||
constexpr auto compare(const Left& left, const Right& right) {
|
||||
using std::begin, std::end;
|
||||
auto ret = std::lexicographical_compare_three_way(begin(left), end(left), begin(right), end(right));
|
||||
auto ret2 =
|
||||
std::lexicographical_compare_three_way(begin(left), end(left), begin(right), end(right), my_cmp_three_way);
|
||||
assert(ret == ret2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class Ty1, class Ty2 = Ty1>
|
||||
constexpr bool test_algorithm2() {
|
||||
std::array<Ty1, 4> original{{0, 1, 2, 3}};
|
||||
|
||||
std::array<Ty2, 4> same{{0, 1, 2, 3}};
|
||||
std::array<Ty2, 4> sameSizeAndLesser{{0, 1, 1, 3}};
|
||||
std::array<Ty2, 4> sameSizeAndGreater{{0, 1, 3, 3}};
|
||||
|
||||
std::array<Ty2, 3> shorter{{0, 1, 2}};
|
||||
std::array<Ty2, 3> shorterAndGreater{{0, 2, 3}};
|
||||
|
||||
std::array<Ty2, 5> longer{{0, 1, 2, 3, 4}};
|
||||
std::array<Ty2, 5> longerAndLesser{{0, 1, 2, 2, 4}};
|
||||
|
||||
assert(compare(original, original) == 0);
|
||||
|
||||
assert(compare(original, same) == 0);
|
||||
assert(compare(same, original) == 0);
|
||||
|
||||
assert(compare(original, sameSizeAndLesser) > 0);
|
||||
assert(compare(sameSizeAndLesser, original) < 0);
|
||||
|
||||
assert(compare(original, sameSizeAndGreater) < 0);
|
||||
assert(compare(sameSizeAndGreater, original) > 0);
|
||||
|
||||
assert(compare(original, shorter) > 0);
|
||||
assert(compare(shorter, original) < 0);
|
||||
|
||||
assert(compare(original, shorterAndGreater) < 0);
|
||||
assert(compare(shorterAndGreater, original) > 0);
|
||||
|
||||
assert(compare(original, longer) < 0);
|
||||
assert(compare(longer, original) > 0);
|
||||
|
||||
assert(compare(original, longerAndLesser) > 0);
|
||||
assert(compare(longerAndLesser, original) < 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Ty1>
|
||||
void test_algorithm() {
|
||||
static_assert(test_algorithm2<Ty1>());
|
||||
assert(test_algorithm2<Ty1>());
|
||||
}
|
||||
|
||||
template <class Ty1, class Ty2>
|
||||
void test_algorithm() {
|
||||
static_assert(test_algorithm2<Ty1, Ty2>());
|
||||
static_assert(test_algorithm2<Ty2, Ty1>());
|
||||
assert((test_algorithm2<Ty1, Ty2>()));
|
||||
assert((test_algorithm2<Ty2, Ty1>()));
|
||||
}
|
||||
#endif // defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
|
||||
int main() {
|
||||
test_ord<comp::equal>(std::partial_ordering::equivalent);
|
||||
test_ord<comp::less>(std::partial_ordering::less);
|
||||
|
@ -133,4 +203,13 @@ int main() {
|
|||
test_ord<comp::equal>(std::strong_ordering::equivalent);
|
||||
test_ord<comp::less>(std::strong_ordering::less);
|
||||
test_ord<comp::greater>(std::strong_ordering::greater);
|
||||
|
||||
#if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
test_algorithm<int>();
|
||||
test_algorithm<char>();
|
||||
test_algorithm<unsigned char>();
|
||||
test_algorithm<int, char>();
|
||||
test_algorithm<int, unsigned char>();
|
||||
test_algorithm<char, unsigned char>();
|
||||
#endif // defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче