1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef SORTABLE_HELPERS_H 10 #define SORTABLE_HELPERS_H 11 12 #include <cstddef> 13 #include <type_traits> 14 15 #include "test_macros.h" 16 17 #if TEST_STD_VER > 17 18 #include <compare> 19 #include <iterator> 20 #include "test_iterators.h" 21 #endif 22 23 struct TrivialSortable { 24 int value; TrivialSortableTrivialSortable25 TEST_CONSTEXPR TrivialSortable() : value(0) {} TrivialSortableTrivialSortable26 TEST_CONSTEXPR TrivialSortable(int v) : value(v) {} 27 friend TEST_CONSTEXPR bool operator<(const TrivialSortable& a, const TrivialSortable& b) { 28 return a.value / 10 < b.value / 10; 29 } lessTrivialSortable30 static TEST_CONSTEXPR bool less(const TrivialSortable& a, const TrivialSortable& b) { 31 return a.value < b.value; 32 } 33 }; 34 35 struct NonTrivialSortable { 36 int value; NonTrivialSortableNonTrivialSortable37 TEST_CONSTEXPR NonTrivialSortable() : value(0) {} NonTrivialSortableNonTrivialSortable38 TEST_CONSTEXPR NonTrivialSortable(int v) : value(v) {} NonTrivialSortableNonTrivialSortable39 TEST_CONSTEXPR NonTrivialSortable(const NonTrivialSortable& rhs) : value(rhs.value) {} 40 TEST_CONSTEXPR_CXX14 NonTrivialSortable& operator=(const NonTrivialSortable& rhs) { value = rhs.value; return *this; } 41 friend TEST_CONSTEXPR bool operator<(const NonTrivialSortable& a, const NonTrivialSortable& b) { 42 return a.value / 10 < b.value / 10; 43 } lessNonTrivialSortable44 static TEST_CONSTEXPR bool less(const NonTrivialSortable& a, const NonTrivialSortable& b) { 45 return a.value < b.value; 46 } 47 }; 48 49 50 struct TrivialSortableWithComp { 51 int value; TrivialSortableWithCompTrivialSortableWithComp52 TEST_CONSTEXPR TrivialSortableWithComp() : value(0) {} TrivialSortableWithCompTrivialSortableWithComp53 TEST_CONSTEXPR TrivialSortableWithComp(int v) : value(v) {} 54 struct Comparator { operatorTrivialSortableWithComp::Comparator55 TEST_CONSTEXPR bool operator()(const TrivialSortableWithComp& a, const TrivialSortableWithComp& b) const { 56 return a.value / 10 < b.value / 10; 57 } 58 }; lessTrivialSortableWithComp59 static TEST_CONSTEXPR bool less(const TrivialSortableWithComp& a, const TrivialSortableWithComp& b) { 60 return a.value < b.value; 61 } 62 }; 63 64 struct NonTrivialSortableWithComp { 65 int value; NonTrivialSortableWithCompNonTrivialSortableWithComp66 TEST_CONSTEXPR NonTrivialSortableWithComp() : value(0) {} NonTrivialSortableWithCompNonTrivialSortableWithComp67 TEST_CONSTEXPR NonTrivialSortableWithComp(int v) : value(v) {} NonTrivialSortableWithCompNonTrivialSortableWithComp68 TEST_CONSTEXPR NonTrivialSortableWithComp(const NonTrivialSortableWithComp& rhs) : value(rhs.value) {} 69 TEST_CONSTEXPR_CXX14 NonTrivialSortableWithComp& operator=(const NonTrivialSortableWithComp& rhs) { value = rhs.value; return *this; } 70 struct Comparator { operatorNonTrivialSortableWithComp::Comparator71 TEST_CONSTEXPR bool operator()(const NonTrivialSortableWithComp& a, const NonTrivialSortableWithComp& b) const { 72 return a.value / 10 < b.value / 10; 73 } 74 }; lessNonTrivialSortableWithComp75 static TEST_CONSTEXPR bool less(const NonTrivialSortableWithComp& a, const NonTrivialSortableWithComp& b) { 76 return a.value < b.value; 77 } 78 }; 79 80 static_assert(std::is_trivially_copyable<TrivialSortable>::value, ""); 81 static_assert(std::is_trivially_copyable<TrivialSortableWithComp>::value, ""); 82 static_assert(!std::is_trivially_copyable<NonTrivialSortable>::value, ""); 83 static_assert(!std::is_trivially_copyable<NonTrivialSortableWithComp>::value, ""); 84 85 #if TEST_STD_VER > 17 86 struct TracedCopy { 87 int copied = 0; 88 int data = 0; 89 90 constexpr TracedCopy() = default; TracedCopyTracedCopy91 constexpr TracedCopy(int i) : data(i) {} TracedCopyTracedCopy92 constexpr TracedCopy(const TracedCopy& other) : copied(other.copied + 1), data(other.data) {} 93 94 constexpr TracedCopy(TracedCopy&& other) = delete; 95 constexpr TracedCopy& operator=(TracedCopy&& other) = delete; 96 97 constexpr TracedCopy& operator=(const TracedCopy& other) { 98 copied = other.copied + 1; 99 data = other.data; 100 return *this; 101 } 102 copiedOnceTracedCopy103 constexpr bool copiedOnce() const { return copied == 1; } 104 105 constexpr bool operator==(const TracedCopy& o) const { return data == o.data; } 106 constexpr auto operator<=>(const TracedCopy& o) const { return data <=> o.data; } 107 }; 108 109 template <class Iter> 110 struct NonBorrowedRange { 111 int* data_; 112 std::size_t size_; 113 114 // TODO: some algorithms calls std::__copy 115 // std::__copy(contiguous_iterator<int*>, sentinel_wrapper<contiguous_iterator<int*>>, contiguous_iterator<int*>) doesn't seem to work. 116 // It seems that it unwraps contiguous_iterator<int*> into int*, and then it failed because there is no == between int* and 117 // sentinel_wrapper<contiguous_iterator<int*>> 118 using Sent = std::conditional_t<std::contiguous_iterator<Iter>, Iter, sentinel_wrapper<Iter>>; 119 NonBorrowedRangeNonBorrowedRange120 constexpr NonBorrowedRange(int* d, std::size_t s) : data_{d}, size_{s} {} 121 beginNonBorrowedRange122 constexpr Iter begin() const { return Iter{data_}; }; endNonBorrowedRange123 constexpr Sent end() const { return Sent{Iter{data_ + size_}}; }; 124 }; 125 #endif // TEST_STD_VER > 17 126 127 #endif // SORTABLE_HELPERS_H 128