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
23struct TrivialSortable {
24 int value;
25 TEST_CONSTEXPR TrivialSortable() : value(0) {}
26 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 }
30 static TEST_CONSTEXPR bool less(const TrivialSortable& a, const TrivialSortable& b) {
31 return a.value < b.value;
32 }
33};
34
35struct NonTrivialSortable {
36 int value;
37 TEST_CONSTEXPR NonTrivialSortable() : value(0) {}
38 TEST_CONSTEXPR NonTrivialSortable(int v) : value(v) {}
39 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 }
44 static TEST_CONSTEXPR bool less(const NonTrivialSortable& a, const NonTrivialSortable& b) {
45 return a.value < b.value;
46 }
47};
48
49
50struct TrivialSortableWithComp {
51 int value;
52 TEST_CONSTEXPR TrivialSortableWithComp() : value(0) {}
53 TEST_CONSTEXPR TrivialSortableWithComp(int v) : value(v) {}
54 struct Comparator {
55 TEST_CONSTEXPR bool operator()(const TrivialSortableWithComp& a, const TrivialSortableWithComp& b) const {
56 return a.value / 10 < b.value / 10;
57 }
58 };
59 static TEST_CONSTEXPR bool less(const TrivialSortableWithComp& a, const TrivialSortableWithComp& b) {
60 return a.value < b.value;
61 }
62};
63
64struct NonTrivialSortableWithComp {
65 int value;
66 TEST_CONSTEXPR NonTrivialSortableWithComp() : value(0) {}
67 TEST_CONSTEXPR NonTrivialSortableWithComp(int v) : value(v) {}
68 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 {
71 TEST_CONSTEXPR bool operator()(const NonTrivialSortableWithComp& a, const NonTrivialSortableWithComp& b) const {
72 return a.value / 10 < b.value / 10;
73 }
74 };
75 static TEST_CONSTEXPR bool less(const NonTrivialSortableWithComp& a, const NonTrivialSortableWithComp& b) {
76 return a.value < b.value;
77 }
78};
79
80static_assert(std::is_trivially_copyable<TrivialSortable>::value, "");
81static_assert(std::is_trivially_copyable<TrivialSortableWithComp>::value, "");
82static_assert(!std::is_trivially_copyable<NonTrivialSortable>::value, "");
83static_assert(!std::is_trivially_copyable<NonTrivialSortableWithComp>::value, "");
84
85#if TEST_STD_VER > 17
86struct TracedCopy {
87 int copied = 0;
88 int data = 0;
89
90 constexpr TracedCopy() = default;
91 constexpr TracedCopy(int i) : data(i) {}
92 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
103 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
109template <class Iter>
110struct 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
120 constexpr NonBorrowedRange(int* d, std::size_t s) : data_{d}, size_{s} {}
121
122 constexpr Iter begin() const { return Iter{data_}; };
123 constexpr Sent end() const { return Sent{Iter{data_ + size_}}; };
124};
125#endif // TEST_STD_VER > 17
126
127#endif // SORTABLE_HELPERS_H
128

source code of libcxx/test/std/algorithms/alg.sorting/sortable_helpers.h