Initial commit

This commit is contained in:
Yervant7
2024-01-16 19:28:29 -03:00
commit 8c0524dc0f
9054 changed files with 1081727 additions and 0 deletions
@@ -0,0 +1,145 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
// <algorithm>
// template<bidirectional_iterator I, sentinel_for<I> S>
// requires permutable<I>
// constexpr I ranges::reverse(I first, S last);
// template<bidirectional_range R>
// requires permutable<iterator_t<R>>
// constexpr borrowed_iterator_t<R> ranges::reverse(R&& r);
#include <algorithm>
#include <array>
#include <concepts>
#include <ranges>
#include "almost_satisfies_types.h"
#include "MoveOnly.h"
#include "test_iterators.h"
template <class Iter, class Sent = sentinel_wrapper<Iter>>
concept HasReverseIt = requires (Iter first, Sent last) { std::ranges::reverse(first, last); };
static_assert(HasReverseIt<int*>);
static_assert(!HasReverseIt<BidirectionalIteratorNotDerivedFrom>);
static_assert(!HasReverseIt<BidirectionalIteratorNotDecrementable>);
static_assert(!HasReverseIt<PermutableNotForwardIterator>);
static_assert(!HasReverseIt<PermutableNotSwappable>);
template <class Range>
concept HasReverseR = requires (Range range) { std::ranges::reverse(range); };
static_assert(HasReverseR<UncheckedRange<int*>>);
static_assert(!HasReverseR<BidirectionalRangeNotDerivedFrom>);
static_assert(!HasReverseR<BidirectionalRangeNotDecrementable>);
static_assert(!HasReverseR<PermutableRangeNotForwardIterator>);
static_assert(!HasReverseR<PermutableRangeNotSwappable>);
template <class Iter, class Sent, size_t N>
constexpr void test(std::array<int, N> value, std::array<int, N> expected) {
{
auto val = value;
std::same_as<Iter> decltype(auto) ret = std::ranges::reverse(Iter(val.data()), Sent(Iter(val.data() + val.size())));
assert(val == expected);
assert(base(ret) == val.data() + val.size());
}
{
auto val = value;
auto range = std::ranges::subrange(Iter(val.data()), Sent(Iter(val.data() + val.size())));
std::same_as<Iter> decltype(auto) ret = std::ranges::reverse(range);
assert(val == expected);
assert(base(ret) == val.data() + val.size());
}
}
template <class Iter, class Sent = Iter>
constexpr void test_iterators() {
// simple test
test<Iter, Sent, 4>({1, 2, 3, 4}, {4, 3, 2, 1});
// check that an odd number of elements works
test<Iter, Sent, 7>({1, 2, 3, 4, 5, 6, 7}, {7, 6, 5, 4, 3, 2, 1});
// check that an empty range works
test<Iter, Sent, 0>({}, {});
// check that a single element works
test<Iter, Sent, 1>({5}, {5});
}
struct SwapCounter {
int* counter;
constexpr SwapCounter(int* counter_) : counter(counter_) {}
friend constexpr void swap(SwapCounter& lhs, SwapCounter&) { ++*lhs.counter; }
};
constexpr bool test() {
test_iterators<bidirectional_iterator<int*>>();
test_iterators<bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>();
test_iterators<random_access_iterator<int*>>();
test_iterators<random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>>>();
test_iterators<contiguous_iterator<int*>>();
test_iterators<contiguous_iterator<int*>, sentinel_wrapper<contiguous_iterator<int*>>>();
test_iterators<int*>();
test_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
test_iterators<ProxyIterator<random_access_iterator<int*>>>();
test_iterators<ProxyIterator<contiguous_iterator<int*>>>();
// check that std::ranges::dangling is returned
{
[[maybe_unused]] std::same_as<std::ranges::dangling> auto ret = std::ranges::reverse(std::array {1, 2, 3, 4});
}
{
{
int counter = 0;
SwapCounter a[] = {&counter, &counter, &counter, &counter};
std::ranges::reverse(a);
assert(counter == 2);
}
{
int counter = 0;
SwapCounter a[] = {&counter, &counter, &counter, &counter};
std::ranges::reverse(a, a + 4);
assert(counter == 2);
}
}
// Move only types work for ProxyIterator
{
{
MoveOnly a[] = {1, 2, 3};
ProxyRange proxyA{a};
std::ranges::reverse(proxyA.begin(), proxyA.end());
assert(a[0].get() == 3);
assert(a[1].get() == 2);
assert(a[2].get() == 1);
}
{
MoveOnly a[] = {1, 2, 3};
ProxyRange proxyA{a};
std::ranges::reverse(proxyA);
assert(a[0].get() == 3);
assert(a[1].get() == 2);
assert(a[2].get() == 1);
}
}
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}
@@ -0,0 +1,141 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
// template<bidirectional_iterator I, sentinel_for<I> S, weakly_incrementable O>
// requires indirectly_copyable<I, O>
// constexpr ranges::reverse_copy_result<I, O>
// ranges::reverse_copy(I first, S last, O result);
// template<bidirectional_range R, weakly_incrementable O>
// requires indirectly_copyable<iterator_t<R>, O>
// constexpr ranges::reverse_copy_result<borrowed_iterator_t<R>, O>
// ranges::reverse_copy(R&& r, O result);
// <algorithm>
#include <algorithm>
#include <array>
#include <cassert>
#include <ranges>
#include "almost_satisfies_types.h"
#include "test_iterators.h"
template <class Iter, class Out = int*, class Sent = sentinel_wrapper<Iter>>
concept HasReverseCopyIt = requires(Iter first, Sent last, Out out) { std::ranges::reverse_copy(first, last, out); };
template <class Range, class Out = int*>
concept HasReverseCopyR = requires(Range range, Out out) { std::ranges::reverse_copy(range, out); };
static_assert(HasReverseCopyIt<int*>);
static_assert(!HasReverseCopyIt<BidirectionalIteratorNotDerivedFrom>);
static_assert(!HasReverseCopyIt<BidirectionalIteratorNotDecrementable>);
static_assert(!HasReverseCopyIt<int*, SentinelForNotSemiregular>);
static_assert(!HasReverseCopyIt<int*, SentinelForNotWeaklyEqualityComparableWith>);
static_assert(!HasReverseCopyIt<int*, OutputIteratorNotIndirectlyWritable>);
static_assert(!HasReverseCopyIt<int*, OutputIteratorNotInputOrOutputIterator>);
static_assert(HasReverseCopyR<UncheckedRange<int*>>);
static_assert(!HasReverseCopyR<BidirectionalRangeNotDerivedFrom>);
static_assert(!HasReverseCopyR<BidirectionalRangeNotDecrementable>);
static_assert(!HasReverseCopyR<UncheckedRange<int*, SentinelForNotSemiregular>>);
static_assert(!HasReverseCopyR<UncheckedRange<int*>, OutputIteratorNotIndirectlyWritable>);
static_assert(!HasReverseCopyR<UncheckedRange<int*>, OutputIteratorNotInputOrOutputIterator>);
static_assert(std::is_same_v<std::ranges::reverse_copy_result<int, int>, std::ranges::in_out_result<int, int>>);
template <class Iter, class OutIter, class Sent, int N>
constexpr void test(std::array<int, N> value, std::array<int, N> expected) {
{
std::array<int, N> out;
std::same_as<std::ranges::in_out_result<Iter, OutIter>> decltype(auto) ret =
std::ranges::reverse_copy(Iter(value.data()),
Sent(Iter(value.data() + value.size())),
OutIter(out.data()));
assert(base(ret.in) == value.data() + value.size());
assert(base(ret.out) == out.data() + out.size());
assert(out == expected);
}
{
std::array<int, N> out;
auto range = std::ranges::subrange(Iter(value.data()), Sent(Iter(value.data() + value.size())));
std::same_as<std::ranges::in_out_result<Iter, OutIter>> decltype(auto) ret =
std::ranges::reverse_copy(range, OutIter(out.data()));
assert(base(ret.in) == value.data() + value.size());
assert(base(ret.out) == out.data() + out.size());
assert(out == expected);
}
}
template <class Iter, class OutIter, class Sent>
constexpr void test_iterators() {
// simple test
test<Iter, OutIter, Sent, 4>({1, 2, 3, 4}, {4, 3, 2, 1});
// check that an empty range works
test<Iter, OutIter, Sent, 0>({}, {});
// check that a single element range works
test<Iter, OutIter, Sent, 1>({1}, {1});
// check that a two element range works
test<Iter, OutIter, Sent, 2>({1, 2}, {2, 1});
}
template <class Iter, class Sent = Iter>
constexpr void test_out_iterators() {
test_iterators<Iter, cpp20_output_iterator<int*>, Sent>();
test_iterators<Iter, forward_iterator<int*>, Sent>();
test_iterators<Iter, bidirectional_iterator<int*>, Sent>();
test_iterators<Iter, random_access_iterator<int*>, Sent>();
test_iterators<Iter, contiguous_iterator<int*>, Sent>();
test_iterators<Iter, int*, Sent>();
}
constexpr bool test() {
test_out_iterators<bidirectional_iterator<int*>>();
test_out_iterators<random_access_iterator<int*>>();
test_out_iterators<contiguous_iterator<int*>>();
test_out_iterators<int*>();
test_out_iterators<const int*>();
{
struct AssignmentCounter {
int* counter;
constexpr AssignmentCounter(int* counter_) : counter(counter_) {}
constexpr AssignmentCounter& operator=(const AssignmentCounter&) { ++*counter; return *this; }
};
{
int c = 0;
AssignmentCounter a[] = {&c, &c, &c, &c};
AssignmentCounter b[] = {&c, &c, &c, &c};
std::ranges::reverse_copy(a, a + 4, b);
assert(c == 4);
}
{
int c = 0;
AssignmentCounter a[] = {&c, &c, &c, &c};
AssignmentCounter b[] = {&c, &c, &c, &c};
std::ranges::reverse_copy(a, b);
assert(c == 4);
}
}
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}
@@ -0,0 +1,70 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// <algorithm>
// template<BidirectionalIterator Iter>
// requires HasSwap<Iter::reference, Iter::reference>
// constexpr void // constexpr in C++20
// reverse(Iter first, Iter last);
#include <algorithm>
#include <cassert>
#include "test_macros.h"
#include "test_iterators.h"
template <class Iter>
TEST_CONSTEXPR_CXX20 bool
test()
{
int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
std::reverse(Iter(ia), Iter(ia));
assert(ia[0] == 0);
std::reverse(Iter(ia), Iter(ia+sa));
assert(ia[0] == 0);
int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
std::reverse(Iter(ib), Iter(ib+sb));
assert(ib[0] == 1);
assert(ib[1] == 0);
int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
std::reverse(Iter(ic), Iter(ic+sc));
assert(ic[0] == 2);
assert(ic[1] == 1);
assert(ic[2] == 0);
int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
std::reverse(Iter(id), Iter(id+sd));
assert(id[0] == 3);
assert(id[1] == 2);
assert(id[2] == 1);
assert(id[3] == 0);
return true;
}
int main(int, char**)
{
test<bidirectional_iterator<int*> >();
test<random_access_iterator<int*> >();
test<int*>();
#if TEST_STD_VER >= 20
static_assert(test<bidirectional_iterator<int*>>());
static_assert(test<random_access_iterator<int*>>());
static_assert(test<int*>());
#endif
return 0;
}
@@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// <algorithm>
// template<BidirectionalIterator InIter, OutputIterator<auto, InIter::reference> OutIter>
// constexpr OutIter // constexpr after C++17
// reverse_copy(InIter first, InIter last, OutIter result);
#include <algorithm>
#include <cassert>
#include "test_macros.h"
#include "test_iterators.h"
#if TEST_STD_VER > 17
TEST_CONSTEXPR bool test_constexpr() {
int ia[] = {1, 3, 5, 2, 5, 6};
int ib[std::size(ia)] = {0};
auto it = std::reverse_copy(std::begin(ia), std::end(ia), std::begin(ib));
return std::distance(std::begin(ib), it) == static_cast<int>(std::size(ia))
&& std::equal (std::begin(ia), std::end(ia), std::rbegin(ib))
;
}
#endif
template <class InIter, class OutIter>
void
test()
{
const int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ja[sa] = {-1};
OutIter r = std::reverse_copy(InIter(ia), InIter(ia), OutIter(ja));
assert(base(r) == ja);
assert(ja[0] == -1);
r = std::reverse_copy(InIter(ia), InIter(ia+sa), OutIter(ja));
assert(ja[0] == 0);
const int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int jb[sb] = {-1};
r = std::reverse_copy(InIter(ib), InIter(ib+sb), OutIter(jb));
assert(base(r) == jb+sb);
assert(jb[0] == 1);
assert(jb[1] == 0);
const int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
int jc[sc] = {-1};
r = std::reverse_copy(InIter(ic), InIter(ic+sc), OutIter(jc));
assert(base(r) == jc+sc);
assert(jc[0] == 2);
assert(jc[1] == 1);
assert(jc[2] == 0);
int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
int jd[sd] = {-1};
r = std::reverse_copy(InIter(id), InIter(id+sd), OutIter(jd));
assert(base(r) == jd+sd);
assert(jd[0] == 3);
assert(jd[1] == 2);
assert(jd[2] == 1);
assert(jd[3] == 0);
}
int main(int, char**)
{
test<bidirectional_iterator<const int*>, cpp17_output_iterator<int*> >();
test<bidirectional_iterator<const int*>, forward_iterator<int*> >();
test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
test<bidirectional_iterator<const int*>, int*>();
test<random_access_iterator<const int*>, cpp17_output_iterator<int*> >();
test<random_access_iterator<const int*>, forward_iterator<int*> >();
test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
test<random_access_iterator<const int*>, random_access_iterator<int*> >();
test<random_access_iterator<const int*>, int*>();
test<const int*, cpp17_output_iterator<int*> >();
test<const int*, forward_iterator<int*> >();
test<const int*, bidirectional_iterator<int*> >();
test<const int*, random_access_iterator<int*> >();
test<const int*, int*>();
#if TEST_STD_VER > 17
static_assert(test_constexpr());
#endif
return 0;
}