You've already forked Zygisk-Assistant
mirror of
https://github.com/snake-4/Zygisk-Assistant.git
synced 2025-09-06 06:37:02 +00:00
Initial commit
This commit is contained in:
+145
@@ -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;
|
||||
}
|
||||
+141
@@ -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;
|
||||
}
|
||||
+70
@@ -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;
|
||||
}
|
||||
+100
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user