xref: /llvm-project/libcxx/test/std/algorithms/alg.sorting/sortable_helpers.h (revision fb855eb941b6d740cc6560297d0b4d3201dcaf9f)
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