init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s

This commit is contained in:
allhaileris
2026-02-16 15:50:16 +03:00
commit afb81b8278
13816 changed files with 3689732 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
set(CMAKE_FOLDER "${CMAKE_FOLDER}/algorithm")
rv3_add_test(test.alg.adjacent_find alg.adjacent_find adjacent_find.cpp)
rv3_add_test(test.alg.adjacent_remove_if alg.adjacent_remove_if adjacent_remove_if.cpp)
rv3_add_test(test.alg.all_of alg.all_of all_of.cpp)
rv3_add_test(test.alg.any_of alg.any_of any_of.cpp)
rv3_add_test(test.alg.none_of alg.none_of none_of.cpp)
rv3_add_test(test.alg.binary_search alg.binary_search binary_search.cpp)
rv3_add_test(test.alg.contains alg.contains contains.cpp)
rv3_add_test(test.alg.copy alg.copy copy.cpp)
rv3_add_test(test.alg.copy_backward alg.copy_backward copy_backward.cpp)
rv3_add_test(test.alg.copy_if alg.copy_if copy_if.cpp)
rv3_add_test(test.alg.count alg.count count.cpp)
rv3_add_test(test.alg.count_if alg.count_if count_if.cpp)
rv3_add_test(test.alg.ends_with alg.ends_with ends_with.cpp)
rv3_add_test(test.alg.equal alg.equal equal.cpp)
rv3_add_test(test.alg.equal_range alg.equal_range equal_range.cpp)
rv3_add_test(test.alg.fill alg.fill fill.cpp)
rv3_add_test(test.alg.find alg.find find.cpp)
rv3_add_test(test.alg.find_end alg.find_end find_end.cpp)
rv3_add_test(test.alg.find_if alg.find_if find_if.cpp)
rv3_add_test(test.alg.find_if_not alg.find_if_not find_if_not.cpp)
rv3_add_test(test.alg.find_first_of alg.find_first_of find_first_of.cpp)
rv3_add_test(test.alg.fold alg.fold fold.cpp)
rv3_add_test(test.alg.for_each alg.for_each for_each.cpp)
rv3_add_test(test.alg.for_each_n alg.for_each_n for_each_n.cpp)
rv3_add_test(test.alg.generate alg.generate generate.cpp)
rv3_add_test(test.alg.generate_n alg.generate_n generate_n.cpp)
rv3_add_test(test.alg.includes alg.includes includes.cpp)
rv3_add_test(test.alg.inplace_merge alg.inplace_merge inplace_merge.cpp)
rv3_add_test(test.alg.is_heap1 alg.is_heap1 is_heap1.cpp)
rv3_add_test(test.alg.is_heap2 alg.is_heap2 is_heap2.cpp)
rv3_add_test(test.alg.is_heap3 alg.is_heap3 is_heap3.cpp)
rv3_add_test(test.alg.is_heap4 alg.is_heap4 is_heap4.cpp)
rv3_add_test(test.alg.is_heap_until1 alg.is_heap_until1 is_heap_until1.cpp)
rv3_add_test(test.alg.is_heap_until2 alg.is_heap_until2 is_heap_until2.cpp)
rv3_add_test(test.alg.is_heap_until3 alg.is_heap_until3 is_heap_until3.cpp)
rv3_add_test(test.alg.is_heap_until4 alg.is_heap_until4 is_heap_until4.cpp)
rv3_add_test(test.alg.is_partitioned alg.is_partitioned is_partitioned.cpp)
rv3_add_test(test.alg.is_permutation alg.is_permutation is_permutation.cpp)
rv3_add_test(test.alg.is_sorted_until alg.is_sorted_until is_sorted_until.cpp)
rv3_add_test(test.alg.is_sorted alg.is_sorted is_sorted.cpp)
rv3_add_test(test.alg.lexicographical_compare alg.lexicographical_compare lexicographical_compare.cpp)
rv3_add_test(test.alg.lower_bound alg.lower_bound lower_bound.cpp)
rv3_add_test(test.alg.make_heap alg.make_heap make_heap.cpp)
rv3_add_test(test.alg.max alg.max max.cpp)
rv3_add_test(test.alg.max_element alg.max_element max_element.cpp)
rv3_add_test(test.alg.merge alg.merge merge.cpp)
rv3_add_test(test.alg.min alg.min min.cpp)
rv3_add_test(test.alg.min_element alg.min_element min_element.cpp)
rv3_add_test(test.alg.minmax alg.minmax minmax.cpp)
rv3_add_test(test.alg.minmax_element alg.minmax_element minmax_element.cpp)
rv3_add_test(test.alg.mismatch alg.mismatch mismatch.cpp)
rv3_add_test(test.alg.move alg.move move.cpp)
rv3_add_test(test.alg.move_backward alg.move_backward move_backward.cpp)
rv3_add_test(test.alg.next_permutation alg.next_permutation next_permutation.cpp)
rv3_add_test(test.alg.nth_element alg.nth_element nth_element.cpp)
rv3_add_test(test.alg.partial_sort alg.partial_sort partial_sort.cpp)
rv3_add_test(test.alg.partial_sort_copy alg.partial_sort_copy partial_sort_copy.cpp)
rv3_add_test(test.alg.partition alg.partition partition.cpp)
rv3_add_test(test.alg.partition_copy alg.partition_copy partition_copy.cpp)
rv3_add_test(test.alg.partition_point alg.partition_point partition_point.cpp)
rv3_add_test(test.alg.pop_heap alg.pop_heap pop_heap.cpp)
rv3_add_test(test.alg.prev_permutation alg.prev_permutation prev_permutation.cpp)
rv3_add_test(test.alg.push_heap alg.push_heap push_heap.cpp)
rv3_add_test(test.alg.remove alg.remove remove.cpp)
rv3_add_test(test.alg.remove_copy alg.remove_copy remove_copy.cpp)
rv3_add_test(test.alg.remove_copy_if alg.remove_copy_if remove_copy_if.cpp)
rv3_add_test(test.alg.remove_if alg.remove_if remove_if.cpp)
rv3_add_test(test.alg.replace alg.replace replace.cpp)
rv3_add_test(test.alg.replace_copy alg.replace_copy replace_copy.cpp)
rv3_add_test(test.alg.replace_copy_if alg.replace_copy_if replace_copy_if.cpp)
rv3_add_test(test.alg.replace_if alg.replace_if replace_if.cpp)
rv3_add_test(test.alg.reverse alg.reverse reverse.cpp)
rv3_add_test(test.alg.reverse_copy alg.reverse_copy reverse_copy.cpp)
rv3_add_test(test.alg.rotate alg.rotate rotate.cpp)
rv3_add_test(test.alg.rotate_copy alg.rotate_copy rotate_copy.cpp)
rv3_add_test(test.alg.sample alg.sample sample.cpp)
rv3_add_test(test.alg.search alg.search search.cpp)
rv3_add_test(test.alg.search_n alg.search_n search_n.cpp)
rv3_add_test(test.alg.set_difference1 alg.set_difference1 set_difference1.cpp)
rv3_add_test(test.alg.set_difference2 alg.set_difference2 set_difference2.cpp)
rv3_add_test(test.alg.set_difference3 alg.set_difference3 set_difference3.cpp)
rv3_add_test(test.alg.set_difference4 alg.set_difference4 set_difference4.cpp)
rv3_add_test(test.alg.set_difference5 alg.set_difference5 set_difference5.cpp)
rv3_add_test(test.alg.set_difference6 alg.set_difference6 set_difference6.cpp)
rv3_add_test(test.alg.set_intersection1 alg.set_intersection1 set_intersection1.cpp)
rv3_add_test(test.alg.set_intersection2 alg.set_intersection2 set_intersection2.cpp)
rv3_add_test(test.alg.set_intersection3 alg.set_intersection3 set_intersection3.cpp)
rv3_add_test(test.alg.set_intersection4 alg.set_intersection4 set_intersection4.cpp)
rv3_add_test(test.alg.set_intersection5 alg.set_intersection5 set_intersection5.cpp)
rv3_add_test(test.alg.set_intersection6 alg.set_intersection6 set_intersection6.cpp)
rv3_add_test(test.alg.set_symmetric_difference1 alg.set_symmetric_difference1 set_symmetric_difference1.cpp)
rv3_add_test(test.alg.set_symmetric_difference2 alg.set_symmetric_difference2 set_symmetric_difference2.cpp)
rv3_add_test(test.alg.set_symmetric_difference3 alg.set_symmetric_difference3 set_symmetric_difference3.cpp)
rv3_add_test(test.alg.set_symmetric_difference4 alg.set_symmetric_difference4 set_symmetric_difference4.cpp)
rv3_add_test(test.alg.set_symmetric_difference5 alg.set_symmetric_difference5 set_symmetric_difference5.cpp)
rv3_add_test(test.alg.set_symmetric_difference6 alg.set_symmetric_difference6 set_symmetric_difference6.cpp)
rv3_add_test(test.alg.set_union1 alg.set_union1 set_union1.cpp)
rv3_add_test(test.alg.set_union2 alg.set_union2 set_union2.cpp)
rv3_add_test(test.alg.set_union3 alg.set_union3 set_union3.cpp)
rv3_add_test(test.alg.set_union4 alg.set_union4 set_union4.cpp)
rv3_add_test(test.alg.set_union5 alg.set_union5 set_union5.cpp)
rv3_add_test(test.alg.set_union6 alg.set_union6 set_union6.cpp)
rv3_add_test(test.alg.shuffle alg.shuffle shuffle.cpp)
rv3_add_test(test.alg.sort alg.sort sort.cpp)
rv3_add_test(test.alg.sort_heap alg.sort_heap sort_heap.cpp)
rv3_add_test(test.alg.stable_partition alg.stable_partition stable_partition.cpp)
rv3_add_test(test.alg.stable_sort alg.stable_sort stable_sort.cpp)
rv3_add_test(test.alg.starts_with alg.starts_with starts_with.cpp)
rv3_add_test(test.alg.swap_ranges alg.swap_ranges swap_ranges.cpp)
rv3_add_test(test.alg.transform alg.transform transform.cpp)
rv3_add_test(test.alg.unique alg.unique unique.cpp)
rv3_add_test(test.alg.unique_copy alg.unique_copy unique_copy.cpp)
rv3_add_test(test.alg.unstable_remove_if alg.unstable_remove_if unstable_remove_if.cpp)
rv3_add_test(test.alg.upper_bound alg.upper_bound upper_bound.cpp)
rv3_add_test(test.alg.sort_n_with_buffer alg.sort_n_with_buffer sort_n_with_buffer.cpp)

View File

@@ -0,0 +1,41 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <range/v3/core.hpp>
#include <range/v3/algorithm/adjacent_find.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
int main()
{
int v1[] = { 0, 2, 2, 4, 6 };
CHECK(ranges::adjacent_find(ranges::begin(v1), ranges::end(v1)) == &v1[1]);
CHECK(ranges::adjacent_find(v1) == &v1[1]);
std::pair<int, int> v2[] = {{0, 0}, {0, 2}, {0, 2}, {0, 4}, {0, 6}};
CHECK(ranges::adjacent_find(ranges::begin(v2), ranges::end(v2),
ranges::equal_to{}, &std::pair<int, int>::second) == &v2[1]);
CHECK(ranges::adjacent_find(v2, ranges::equal_to{}, &std::pair<int, int>::second) == &v2[1]);
static_assert(std::is_same<std::pair<int,int>*,
decltype(ranges::adjacent_find(v2, ranges::equal_to{},
&std::pair<int, int>::second))>::value, "");
{
using namespace ranges;
constexpr auto a1 = test::array<int, 5>{{0, 2, 2, 4, 6}};
STATIC_CHECK(adjacent_find(begin(a1), end(a1)) == (begin(a1) + 1));
STATIC_CHECK(adjacent_find(a1) == (begin(a1) + 1));
constexpr std::pair<int, int> a2[] = {{0, 0}, {0, 2}, {0, 2}, {0, 4}, {0, 6}};
STATIC_CHECK(adjacent_find(a2, ranges::equal_to{}) == (begin(a2) + 1));
}
return test_result();
}

View File

@@ -0,0 +1,223 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler
// Copyright Christopher Di Bella
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/algorithm/adjacent_remove_if.hpp>
#include <range/v3/core.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, class Sent = Iter>
void
test_iter()
{
int ia[] = {0, 1, 1, 1, 4, 2, 2, 4, 2};
constexpr auto sa = ranges::size(ia);
Iter r = ranges::adjacent_remove_if(Iter(ia), Sent(ia+sa), ranges::equal_to{});
CHECK(base(r) == ia + sa-3);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 4);
CHECK(ia[3] == 2);
CHECK(ia[4] == 4);
CHECK(ia[5] == 2);
}
template<class Iter, class Sent = Iter>
void
test_range()
{
int ia[] = {0, 1, 1, 1, 4, 2, 2, 4, 2};
constexpr auto sa = ranges::size(ia);
Iter r = ranges::adjacent_remove_if(
ranges::make_subrange(Iter(ia), Sent(ia+sa)),
ranges::equal_to{});
CHECK(base(r) == ia + sa-3);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 4);
CHECK(ia[3] == 2);
CHECK(ia[4] == 4);
CHECK(ia[5] == 2);
}
struct pred
{
bool operator()(const std::unique_ptr<int> &i, const std::unique_ptr<int> &j)
{
return *i == 2 && *j == 3;
}
};
template<class Iter, class Sent = Iter>
void
test_iter_rvalue()
{
constexpr unsigned sa = 9;
std::unique_ptr<int> ia[sa];
ia[0].reset(new int(0));
ia[1].reset(new int(1));
ia[2].reset(new int(2));
ia[3].reset(new int(3));
ia[4].reset(new int(4));
ia[5].reset(new int(2));
ia[6].reset(new int(3));
ia[7].reset(new int(4));
ia[8].reset(new int(2));
Iter r = ranges::adjacent_remove_if(Iter(ia), Sent(ia+sa), pred());
CHECK(base(r) == ia + sa-2);
CHECK(*ia[0] == 0);
CHECK(*ia[1] == 1);
CHECK(*ia[2] == 3);
CHECK(*ia[3] == 4);
CHECK(*ia[4] == 3);
CHECK(*ia[5] == 4);
CHECK(*ia[6] == 2);
}
template<class Iter, class Sent = Iter>
void
test_range_rvalue()
{
constexpr unsigned sa = 9;
std::unique_ptr<int> ia[sa];
ia[0].reset(new int(0));
ia[1].reset(new int(1));
ia[2].reset(new int(2));
ia[3].reset(new int(3));
ia[4].reset(new int(4));
ia[5].reset(new int(2));
ia[6].reset(new int(3));
ia[7].reset(new int(4));
ia[8].reset(new int(2));
Iter r = ranges::adjacent_remove_if(ranges::make_subrange(Iter(ia), Sent(ia+sa)), pred());
CHECK(base(r) == ia + sa-2);
CHECK(*ia[0] == 0);
CHECK(*ia[1] == 1);
CHECK(*ia[2] == 3);
CHECK(*ia[3] == 4);
CHECK(*ia[4] == 3);
CHECK(*ia[5] == 4);
CHECK(*ia[6] == 2);
}
template<class Iter, class Sent = Iter>
bool constexpr test_constexpr()
{
int ia[] = {0, 1, 1, 1, 4, 2, 2, 4, 2};
constexpr auto sa = ranges::size(ia);
Iter r = ranges::adjacent_remove_if(ranges::make_subrange(Iter(ia), Sent(ia + sa)),
ranges::equal_to{});
STATIC_CHECK_RETURN(base(r) == ia + sa - 3);
STATIC_CHECK_RETURN(ia[0] == 0);
STATIC_CHECK_RETURN(ia[1] == 1);
STATIC_CHECK_RETURN(ia[2] == 4);
STATIC_CHECK_RETURN(ia[3] == 2);
STATIC_CHECK_RETURN(ia[4] == 4);
STATIC_CHECK_RETURN(ia[5] == 2);
return true;
}
struct S
{
int i;
};
int main()
{
test_iter<ForwardIterator<int*> >();
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<ForwardIterator<int*>, Sentinel<int*>>();
test_iter<BidirectionalIterator<int*>, Sentinel<int*>>();
test_iter<RandomAccessIterator<int*>, Sentinel<int*>>();
test_range<ForwardIterator<int*> >();
test_range<BidirectionalIterator<int*> >();
test_range<RandomAccessIterator<int*> >();
test_range<int*>();
test_range<ForwardIterator<int*>, Sentinel<int*>>();
test_range<BidirectionalIterator<int*>, Sentinel<int*>>();
test_range<RandomAccessIterator<int*>, Sentinel<int*>>();
test_iter_rvalue<ForwardIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<BidirectionalIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<RandomAccessIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<std::unique_ptr<int>*>();
test_iter_rvalue<ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_iter_rvalue<BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_iter_rvalue<RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<ForwardIterator<std::unique_ptr<int>*> >();
test_range_rvalue<BidirectionalIterator<std::unique_ptr<int>*> >();
test_range_rvalue<RandomAccessIterator<std::unique_ptr<int>*> >();
test_range_rvalue<std::unique_ptr<int>*>();
test_range_rvalue<ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
{
// Check projection
S ia[] = {S{0}, S{1}, S{1}, S{1}, S{4}, S{2}, S{2}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
S* r = ranges::adjacent_remove_if(ia, ranges::equal_to{}, &S::i);
CHECK(r == ia + sa-3);
CHECK(ia[0].i == 0);
CHECK(ia[1].i == 1);
CHECK(ia[2].i == 4);
CHECK(ia[3].i == 2);
CHECK(ia[4].i == 4);
CHECK(ia[5].i == 2);
}
{
// Check rvalue range
S ia[] = {S{0}, S{1}, S{1}, S{2}, S{3}, S{5}, S{8}, S{13}, S{21}};
constexpr auto sa = ranges::size(ia);
using namespace std::placeholders;
auto r = ranges::adjacent_remove_if(
ranges::views::all(ia),
[](int x, int y) noexcept { return (x + y) % 2 == 0; },
&S::i);
CHECK(r == ia + sa-3);
CHECK(ia[0].i == 0);
CHECK(ia[1].i == 1);
CHECK(ia[2].i == 2);
CHECK(ia[3].i == 5);
CHECK(ia[4].i == 8);
CHECK(ia[5].i == 21);
}
STATIC_CHECK(test_constexpr<ForwardIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<int *>());
STATIC_CHECK(test_constexpr<ForwardIterator<int *>, Sentinel<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<int *>, Sentinel<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<int *>, Sentinel<int *>>());
return ::test_result();
}

View File

@@ -0,0 +1,75 @@
// Range v3 library
//
// Copyright Andrew Sutton 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/all_of.hpp>
#include "../simple_test.hpp"
constexpr bool even(int n)
{
return n % 2 == 0;
}
struct S {
S(bool p) : test(p) { }
bool p() const { return test; }
bool test;
};
constexpr bool test_constexpr(std::initializer_list<int> il)
{
return ranges::all_of(il, even);
}
int main()
{
std::vector<int> all_even { 0, 2, 4, 6 };
std::vector<int> one_even { 1, 3, 4, 7 };
std::vector<int> none_even { 1, 3, 5, 7 };
CHECK(ranges::all_of(all_even.begin(), all_even.end(), even));
CHECK(!ranges::all_of(one_even.begin(), one_even.end(), even));
CHECK(!ranges::all_of(none_even.begin(), none_even.end(), even));
CHECK(ranges::all_of(all_even, even));
CHECK(!ranges::all_of(one_even, even));
CHECK(!ranges::all_of(none_even, even));
using ILI = std::initializer_list<int>;
CHECK(ranges::all_of(ILI{0, 2, 4, 6}, [](int n) { return n % 2 == 0; }));
CHECK(!ranges::all_of(ILI{1, 3, 4, 7}, [](int n) { return n % 2 == 0; }));
CHECK(!ranges::all_of(ILI{1, 3, 5, 7}, [](int n) { return n % 2 == 0; }));
std::vector<S> all_true { true, true, true };
std::vector<S> one_true { false, false, true };
std::vector<S> none_true { false, false, false };
CHECK(ranges::all_of(all_true.begin(), all_true.end(), &S::p));
CHECK(!ranges::all_of(one_true.begin(), one_true.end(), &S::p));
CHECK(!ranges::all_of(none_true.begin(), none_true.end(), &S::p));
CHECK(ranges::all_of(all_true, &S::p));
CHECK(!ranges::all_of(one_true, &S::p));
CHECK(!ranges::all_of(none_true, &S::p));
using ILS = std::initializer_list<S>;
CHECK(ranges::all_of(ILS{S(true), S(true), S(true)}, &S::p));
CHECK(!ranges::all_of(ILS{S(false), S(true), S(false)}, &S::p));
CHECK(!ranges::all_of(ILS{S(false), S(false), S(false)}, &S::p));
STATIC_CHECK(test_constexpr({0, 2, 4, 6}));
STATIC_CHECK(!test_constexpr({0, 2, 4, 5}));
STATIC_CHECK(!test_constexpr({1, 3, 4, 7}));
STATIC_CHECK(!test_constexpr({1, 3, 5, 7}));
return ::test_result();
}

View File

@@ -0,0 +1,75 @@
// Range v3 library
//
// Copyright Andrew Sutton 2014
// Copyright Gonzalo Brito Gadeschi 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/any_of.hpp>
#include "../simple_test.hpp"
constexpr bool even(int n)
{
return n % 2 == 0;
}
struct S {
S(bool p) : test(p) { }
bool p() const { return test; }
bool test;
};
constexpr bool test_constexpr(std::initializer_list<int> il)
{
return ranges::any_of(il, even);
}
int main()
{
std::vector<int> all_even { 0, 2, 4, 6 };
std::vector<int> one_even { 1, 3, 4, 7 };
std::vector<int> none_even { 1, 3, 5, 7 };
CHECK(ranges::any_of(all_even.begin(), all_even.end(), even));
CHECK(ranges::any_of(one_even.begin(), one_even.end(), even));
CHECK(!ranges::any_of(none_even.begin(), none_even.end(), even));
CHECK(ranges::any_of(all_even, even));
CHECK(ranges::any_of(one_even, even));
CHECK(!ranges::any_of(none_even, even));
using ILI = std::initializer_list<int>;
CHECK(ranges::any_of(ILI{0, 2, 4, 6}, [](int n) { return n % 2 == 0; }));
CHECK(ranges::any_of(ILI{1, 3, 4, 7}, [](int n) { return n % 2 == 0; }));
CHECK(!ranges::any_of(ILI{1, 3, 5, 7}, [](int n) { return n % 2 == 0; }));
std::vector<S> all_true { true, true, true };
std::vector<S> one_true { false, false, true };
std::vector<S> none_true { false, false, false };
CHECK(ranges::any_of(all_true.begin(), all_true.end(), &S::p));
CHECK(ranges::any_of(one_true.begin(), one_true.end(), &S::p));
CHECK(!ranges::any_of(none_true.begin(), none_true.end(), &S::p));
CHECK(ranges::any_of(all_true, &S::p));
CHECK(ranges::any_of(one_true, &S::p));
CHECK(!ranges::any_of(none_true, &S::p));
using ILS = std::initializer_list<S>;
CHECK(ranges::any_of(ILS{S(true), S(true), S(true)}, &S::p));
CHECK(ranges::any_of(ILS{S(false), S(true), S(false)}, &S::p));
CHECK(!ranges::any_of(ILS{S(false), S(false), S(false)}, &S::p));
STATIC_CHECK(test_constexpr({0, 2, 4, 6}));
STATIC_CHECK(test_constexpr({1, 3, 4, 7}));
STATIC_CHECK(!test_constexpr({1, 3, 5, 7}));
return ::test_result();
}

View File

@@ -0,0 +1,61 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/binary_search.hpp>
#include "../simple_test.hpp"
int main()
{
using ranges::begin;
using ranges::end;
using ranges::size;
using ranges::less;
constexpr std::pair<int, int> a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};
constexpr const std::pair<int, int> c[] = {
{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};
CHECK(ranges::binary_search(begin(a), end(a), a[0]));
CHECK(ranges::binary_search(begin(a), end(a), a[1], less()));
CHECK(ranges::binary_search(begin(a), end(a), 1, less(), &std::pair<int, int>::first));
CHECK(ranges::binary_search(a, a[2]));
CHECK(ranges::binary_search(c, c[3]));
CHECK(ranges::binary_search(a, a[4], less()));
CHECK(ranges::binary_search(c, c[5], less()));
CHECK(ranges::binary_search(a, 1, less(), &std::pair<int, int>::first));
CHECK(ranges::binary_search(c, 1, less(), &std::pair<int, int>::first));
CHECK(ranges::binary_search(a, 0, less(), &std::pair<int, int>::first));
CHECK(ranges::binary_search(c, 0, less(), &std::pair<int, int>::first));
CHECK(!ranges::binary_search(a, -1, less(), &std::pair<int, int>::first));
CHECK(!ranges::binary_search(c, -1, less(), &std::pair<int, int>::first));
CHECK(!ranges::binary_search(a, 4, less(), &std::pair<int, int>::first));
CHECK(!ranges::binary_search(c, 4, less(), &std::pair<int, int>::first));
STATIC_CHECK(ranges::binary_search(begin(a), end(a), a[0]));
STATIC_CHECK(ranges::binary_search(begin(a), end(a), a[1], less()));
STATIC_CHECK(ranges::binary_search(a, a[2]));
STATIC_CHECK(ranges::binary_search(a, a[4], less()));
STATIC_CHECK(!ranges::binary_search(a, std::make_pair(-1, -1), less()));
return test_result();
}

View File

@@ -0,0 +1,39 @@
// Range v3 library
//
// Copyright Johel Guerrero 2019
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#include <range/v3/algorithm/contains.hpp>
#include "../simple_test.hpp"
int main()
{
using ranges::contains;
constexpr int rng[] = {4, 2};
const auto first = rng;
const auto last = rng + 2;
CHECK(!contains(first, first, 0));
CHECK(!contains(first, last, 1));
CHECK(contains(first, last, 2));
CHECK(!contains(first, last, 3));
CHECK(contains(first, last, 4));
#ifndef RANGES_WORKAROUND_CLANG_23135
static_assert(!contains(rng, 1), "");
static_assert(contains(rng, 2), "");
static_assert(!contains(rng, 3), "");
static_assert(contains(rng, 4), "");
#endif
return ::test_result();
}

View File

@@ -0,0 +1,116 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <vector>
#include <sstream>
#include <cstring>
#include <utility>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/view/delimit.hpp>
#include <range/v3/iterator/stream_iterators.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#if RANGES_CXX_CONSTEXPR >= RANGES_CXX_CONSTEXPR_14 && RANGES_CONSTEXPR_INVOKE
constexpr /*c++14*/
bool test_constexpr_copy()
{
int a[4] = {0, 0, 0, 0};
int const b[4] = {1, 2, 3, 4};
ranges::copy(b, a);
return ranges::equal(b, a);
}
static_assert(test_constexpr_copy(), "");
#endif
constexpr bool test_constexpr()
{
using IL = std::initializer_list<int>;
constexpr test::array<int, 4> input{{0, 1, 2, 3}};
test::array<int, 4> tmp{{0, 0, 0, 0}};
auto res = ranges::copy(input, ranges::begin(tmp));
STATIC_CHECK_RETURN(res.in == ranges::end(input));
STATIC_CHECK_RETURN(res.out == ranges::end(tmp));
STATIC_CHECK_RETURN(ranges::equal(tmp, IL{0, 1, 2, 3}));
return true;
}
int main()
{
using ranges::begin;
using ranges::end;
using ranges::size;
std::pair<int, int> const a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};
static_assert(size(a) == 6, "");
std::pair<int, int> out[size(a)] = {};
auto res = ranges::copy(begin(a), end(a), out);
CHECK(res.in == end(a));
CHECK(res.out == out + size(out));
CHECK(std::equal(a, a + size(a), out));
std::fill_n(out, size(out), std::make_pair(0, 0));
CHECK(!std::equal(a, a + size(a), out));
res = ranges::copy(a, out);
CHECK(res.in == a + size(a));
CHECK(res.out == out + size(out));
CHECK(std::equal(a, a + size(a), out));
std::fill_n(out, size(out), std::make_pair(0, 0));
using ranges::views::delimit;
{
char const *sz = "hello world";
char buf[50];
auto str = delimit(sz, '\0');
auto res3 = ranges::copy(str, buf);
*res3.out = '\0';
CHECK(res3.in == std::next(begin(str), static_cast<std::ptrdiff_t>(std::strlen(sz))));
CHECK(res3.out == buf + std::strlen(sz));
CHECK(std::strcmp(sz, buf) == 0);
}
{
char const *sz = "hello world";
char buf[50];
auto str = delimit(sz, '\0');
auto res3 = ranges::copy(std::move(str), buf);
*res3.out = '\0';
CHECK(!::is_dangling(res3.in));
CHECK(res3.out == buf + std::strlen(sz));
CHECK(std::strcmp(sz, buf) == 0);
}
{
using namespace ranges;
std::ostringstream sout;
std::vector<int> copy_vec{1,1,1,1,1};
copy(copy_vec, ostream_iterator<>(sout, " "));
CHECK(sout.str() == "1 1 1 1 1 ");
}
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,92 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <cstring>
#include <algorithm>
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/copy_backward.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#include "../test_utils.hpp"
constexpr bool test_constexpr()
{
using IL = std::initializer_list<int>;
constexpr test::array<int, 4> input{{0, 1, 2, 3}};
test::array<int, 4> a1{{0, 0, 0, 0}};
auto res = ranges::copy_backward(input, ranges::end(a1));
STATIC_CHECK_RETURN(res.in == ranges::end(input));
STATIC_CHECK_RETURN(res.out == ranges::begin(a1));
STATIC_CHECK_RETURN(ranges::equal(a1, IL{0, 1, 2, 3}));
return true;
}
int main()
{
using ranges::begin;
using ranges::end;
using ranges::size;
std::pair<int, int> const a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};
static_assert(size(a) == 6, "");
std::pair<int, int> out[size(a)] = {};
{
auto res = ranges::copy_backward(begin(a), end(a), end(out));
CHECK(res.in == end(a));
CHECK(res.out == begin(out));
CHECK(std::equal(a, a + size(a), out));
}
{
std::fill_n(out, size(out), std::make_pair(0, 0));
auto res = ranges::copy_backward(a, end(out));
CHECK(res.in == end(a));
CHECK(res.out == begin(out));
CHECK(std::equal(a, a + size(a), out));
}
#ifndef RANGES_WORKAROUND_MSVC_573728
{
std::fill_n(out, size(out), std::make_pair(0, 0));
auto res = ranges::copy_backward(std::move(a), end(out));
CHECK(::is_dangling(res.in));
CHECK(res.out == begin(out));
CHECK(std::equal(a, a + size(a), out));
}
#endif
{
std::fill_n(out, size(out), std::make_pair(0, 0));
std::vector<std::pair<int, int>> vec(begin(a), end(a));
auto res = ranges::copy_backward(std::move(vec), end(out));
CHECK(::is_dangling(res.in));
CHECK(res.out == begin(out));
CHECK(std::equal(a, a + size(a), out));
}
{
std::fill_n(out, size(out), std::make_pair(0, 0));
auto res = ranges::copy_backward(ranges::views::all(a), end(out));
CHECK(res.in == end(a));
CHECK(res.out == begin(out));
CHECK(std::equal(a, a + size(a), out));
}
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,47 @@
// Range v3 library
//
// Copyright Eric Niebler 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <range/v3/algorithm/copy_if.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
constexpr bool is_even(int i)
{
return i % 2 == 0;
}
constexpr bool test_constexpr()
{
using namespace ranges;
test::array<int, 4> a{{1, 2, 3, 4}};
test::array<int, 4> b{{0, 0, 0, 0}};
const auto res = copy_if(a, ranges::begin(b), is_even);
STATIC_CHECK_RETURN(res.in == end(a));
STATIC_CHECK_RETURN(res.out == begin(b) + 2);
STATIC_CHECK_RETURN(a[0] == 1);
STATIC_CHECK_RETURN(a[1] == 2);
STATIC_CHECK_RETURN(a[2] == 3);
STATIC_CHECK_RETURN(a[3] == 4);
STATIC_CHECK_RETURN(b[0] == 2);
STATIC_CHECK_RETURN(b[1] == 4);
STATIC_CHECK_RETURN(b[2] == 0);
STATIC_CHECK_RETURN(b[3] == 0);
return true;
}
int main()
{
STATIC_CHECK(test_constexpr());
return test_result();
}

View File

@@ -0,0 +1,44 @@
// Range v3 library
//
// Copyright Eric Niebler 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <range/v3/algorithm/copy_n.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
constexpr bool test_constexpr()
{
using namespace ranges;
test::array<int, 4> a{{1, 2, 3, 4}};
test::array<int, 4> b{{0, 0, 0, 0}};
const auto res = copy_n(begin(a), 2, ranges::begin(b));
STATIC_CHECK_RETURN(res.first == begin(a) + 2);
STATIC_CHECK_RETURN(res.second == begin(b) + 2);
STATIC_CHECK_RETURN(a[0] == 1);
STATIC_CHECK_RETURN(a[1] == 2);
STATIC_CHECK_RETURN(a[2] == 3);
STATIC_CHECK_RETURN(a[3] == 4);
STATIC_CHECK_RETURN(b[0] == 1);
STATIC_CHECK_RETURN(b[1] == 2);
STATIC_CHECK_RETURN(b[2] == 0);
STATIC_CHECK_RETURN(b[3] == 0);
return true;
}
int main()
{
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,67 @@
// Range v3 library
//
// Copyright Andrew Sutton 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <range/v3/core.hpp>
#include <range/v3/algorithm/count.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct S
{
int i;
};
int main()
{
using namespace ranges;
int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
constexpr auto cia = size(ia);
CHECK(count(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia), 2) == 3);
CHECK(count(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia), 7) == 0);
CHECK(count(InputIterator<const int*>(ia),
Sentinel<const int*>(ia), 2) == 0);
CHECK(count(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia)), 2) == 3);
CHECK(count(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia)), 7) == 0);
CHECK(count(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia)), 2) == 0);
S sa[] = {{0}, {1}, {2}, {2}, {0}, {1}, {2}, {3}};
constexpr auto csa = size(ia);
CHECK(count(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa), 2, &S::i) == 3);
CHECK(count(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa), 7, &S::i) == 0);
CHECK(count(InputIterator<const S*>(sa),
Sentinel<const S*>(sa), 2, &S::i) == 0);
CHECK(count(make_subrange(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa)), 2, &S::i) == 3);
CHECK(count(make_subrange(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa)), 7, &S::i) == 0);
CHECK(count(make_subrange(InputIterator<const S*>(sa),
Sentinel<const S*>(sa)), 2, &S::i) == 0);
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ranges::count(IL{0, 1, 2, 1, 3, 1, 4}, 1) == 3);
STATIC_CHECK(ranges::count(IL{0, 1, 2, 1, 3, 1, 4}, 5) == 0);
}
return ::test_result();
}

View File

@@ -0,0 +1,89 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <range/v3/core.hpp>
#include <range/v3/algorithm/count_if.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct S
{
int i;
};
struct T
{
bool b;
bool m() { return b; }
};
constexpr bool even(int i)
{
return i % 2 == 0;
}
int main()
{
using namespace ranges;
auto equals = [](int i){ return std::bind(equal_to{}, i, std::placeholders::_1); };
int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
constexpr auto cia = size(ia);
CHECK(count_if(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia), equals(2)) == 3);
CHECK(count_if(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia), equals(7)) == 0);
CHECK(count_if(InputIterator<const int*>(ia),
Sentinel<const int*>(ia), equals(2)) == 0);
CHECK(count_if(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia)), equals(2)) == 3);
CHECK(count_if(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + cia)), equals(7)) == 0);
CHECK(count_if(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia)), equals(2)) == 0);
S sa[] = {{0}, {1}, {2}, {2}, {0}, {1}, {2}, {3}};
constexpr auto csa = size(ia);
CHECK(count_if(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa), equals(2), &S::i) == 3);
CHECK(count_if(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa), equals(7), &S::i) == 0);
CHECK(count_if(InputIterator<const S*>(sa),
Sentinel<const S*>(sa), equals(2), &S::i) == 0);
CHECK(count_if(make_subrange(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa)), equals(2), &S::i) == 3);
CHECK(count_if(make_subrange(InputIterator<const S*>(sa),
Sentinel<const S*>(sa + csa)), equals(7), &S::i) == 0);
CHECK(count_if(make_subrange(InputIterator<const S*>(sa),
Sentinel<const S*>(sa)), equals(2), &S::i) == 0);
T ta[] = {{true}, {false}, {true}, {false}, {false}, {true}, {false}, {false}, {true}, {false}};
CHECK(count_if(InputIterator<T*>(ta),
Sentinel<T*>(ta + size(ta)), &T::m) == 4);
CHECK(count_if(InputIterator<T*>(ta),
Sentinel<T*>(ta + size(ta)), &T::b) == 4);
CHECK(count_if(make_subrange(InputIterator<T*>(ta),
Sentinel<T*>(ta + size(ta))), &T::m) == 4);
CHECK(count_if(make_subrange(InputIterator<T*>(ta),
Sentinel<T*>(ta + size(ta))), &T::b) == 4);
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ranges::count_if(IL{0, 1, 2, 1, 3, 1, 4}, even) == 3);
STATIC_CHECK(ranges::count_if(IL{1, 1, 3, 1}, even) == 0);
}
return ::test_result();
}

View File

@@ -0,0 +1,111 @@
// Range v3 library
//
// Copyright Johel Guerrero 2019
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#include <initializer_list>
#include <range/v3/algorithm/ends_with.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/view/subrange.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
int comparison_count = 0;
template<typename T>
bool counting_equals(const T &a, const T &b)
{
++comparison_count;
return a == b;
}
int main()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
constexpr auto as = distance(ia);
int ib[] = {5, 6, 7, 8, 9};
constexpr auto bs = distance(ib);
CHECK(ends_with(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + as),
RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib + bs)));
CHECK(!ends_with(InputIterator<const int*>(ia),
InputIterator<const int*, true>(ia + as),
InputIterator<const int*>(ib),
InputIterator<const int*, true>(ib + bs - 1)));
CHECK(!ends_with(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + as),
ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + bs - 1)));
CHECK(!ends_with(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + as)),
make_subrange(RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib + bs - 1))));
CHECK(ends_with(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*, true>(ia + as)),
make_subrange(InputIterator<const int*>(ib),
InputIterator<const int*, true>(ib + bs))));
CHECK(ends_with(make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + as)),
make_subrange(ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + bs))));
comparison_count = 0;
CHECK(!ends_with(RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib + bs),
RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + as),
counting_equals<int>));
CHECK(comparison_count == 0);
comparison_count = 0;
CHECK(ends_with(InputIterator<const int*>(ia),
InputIterator<const int*, true>(ia + as),
InputIterator<const int*>(ib),
InputIterator<const int*, true>(ib + bs),
counting_equals<int>));
CHECK(comparison_count > 0);
comparison_count = 0;
CHECK(ends_with(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + as),
ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + bs),
counting_equals<int>));
CHECK(comparison_count > 0);
comparison_count = 0;
CHECK(ends_with(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + as)),
make_subrange(RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib + bs)),
counting_equals<int>));
CHECK(comparison_count > 0);
comparison_count = 0;
CHECK(!ends_with(make_subrange(InputIterator<const int*>(ib),
InputIterator<const int*, true>(ib + bs - 1)),
make_subrange(InputIterator<const int*>(ib),
InputIterator<const int*, true>(ib + bs)),
counting_equals<int>));
CHECK(comparison_count == 0);
comparison_count = 0;
CHECK(!ends_with(make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia)),
make_subrange(ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + bs)),
counting_equals<int>));
CHECK(comparison_count == 0);
#if RANGES_CXX_CONSTEXPR >= RANGES_CXX_CONSTEXPR_14 && RANGES_CONSTEXPR_INVOKE
using IL = std::initializer_list<int>;
static_assert(ends_with(IL{0, 1, 2, 3, 4}, IL{3, 4}), "");
static_assert(!ends_with(IL{0, 1, 2, 3, 4}, IL{2, 3}), "");
static_assert(ends_with(IL{}, IL{}), "");
#endif
return ::test_result();
}

View File

@@ -0,0 +1,295 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/core.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/view/unbounded.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
void test()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5};
constexpr auto s = size(ia);
int ib[s] = {0, 1, 2, 5, 4, 5};
CHECK(equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ia)));
CHECK(equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)));
CHECK(equal(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + s)));
CHECK(equal(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s)));
CHECK(!equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ib)));
CHECK(!equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ib),
Sentinel<const int*>(ib + s)));
CHECK(!equal(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib+s)));
CHECK(!equal(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
RandomAccessIterator<const int*>(ib),
Sentinel<const int*>(ib + s)));
CHECK(!equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1)));
CHECK(!equal(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s-1)));
CHECK(!equal(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1)));
}
void test_rng()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5};
constexpr auto s = size(ia);
int ib[s] = {0, 1, 2, 5, 4, 5};
CHECK(equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
InputIterator<const int*>(ia)));
CHECK(equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s))));
CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + s))));
CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s))));
CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
InputIterator<const int*>(ib)));
CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(InputIterator<const int*>(ib),
Sentinel<const int*>(ib + s))));
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib+s))));
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ib),
Sentinel<const int*>(ib + s))));
CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1))));
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s-1))));
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1))));
}
int comparison_count = 0;
template<typename T>
bool counting_equals(const T &a, const T &b)
{
++comparison_count;
return a == b;
}
void test_pred()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5};
constexpr auto s = size(ia);
int ib[s] = {0, 1, 2, 5, 4, 5};
CHECK(equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ia),
std::equal_to<int>()));
CHECK(equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ia),
Sentinel<const int*>(ia + s),
std::equal_to<int>()));
CHECK(equal(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
std::equal_to<int>()));
CHECK(equal(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s),
std::equal_to<int>()));
comparison_count = 0;
CHECK(!equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1),
counting_equals<int>));
CHECK(comparison_count > 0);
comparison_count = 0;
CHECK(!equal(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s-1),
counting_equals<int>));
CHECK(comparison_count == 0);
comparison_count = 0;
CHECK(!equal(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1),
counting_equals<int>));
CHECK(comparison_count > 0);
CHECK(!equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ib),
std::equal_to<int>()));
CHECK(!equal(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
InputIterator<const int*>(ib),
Sentinel<const int*>(ib + s),
std::equal_to<int>()));
CHECK(!equal(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s),
RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib+s),
std::equal_to<int>()));
CHECK(!equal(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
RandomAccessIterator<const int*>(ib),
Sentinel<const int*>(ib + s),
std::equal_to<int>()));
}
void test_rng_pred()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5};
constexpr auto s = size(ia);
int ib[s] = {0, 1, 2, 5, 4, 5};
CHECK(equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
InputIterator<const int*>(ia),
std::equal_to<int>()));
CHECK(equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + s)),
std::equal_to<int>()));
CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
std::equal_to<int>()));
CHECK(equal(make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s)),
std::equal_to<int>()));
comparison_count = 0;
CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1)),
counting_equals<int>));
CHECK(comparison_count > 0);
comparison_count = 0;
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s-1)),
counting_equals<int>));
CHECK(comparison_count == 0);
comparison_count = 0;
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia + s - 1)),
counting_equals<int>));
CHECK(comparison_count > 0);
CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
InputIterator<const int*>(ib),
std::equal_to<int>()));
CHECK(!equal(make_subrange(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(InputIterator<const int*>(ib),
Sentinel<const int*>(ib + s)),
std::equal_to<int>()));
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib+s)),
std::equal_to<int>()));
CHECK(!equal(make_subrange(RandomAccessIterator<const int*>(ia),
Sentinel<const int*>(ia+s)),
make_subrange(RandomAccessIterator<const int*>(ib),
Sentinel<const int*>(ib + s)),
std::equal_to<int>()));
}
int main()
{
::test();
::test_rng();
::test_pred();
::test_rng_pred();
using IL = std::initializer_list<int>;
int *p = nullptr;
static_assert(std::is_same<bool, decltype(ranges::equal(IL{1, 2, 3, 4}, p))>::value, "");
static_assert(std::is_same<bool, decltype(ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 3, 4}))>::value, "");
static_assert(std::is_same<bool, decltype(ranges::equal(IL{1, 2, 3, 4}, ranges::views::unbounded(p)))>::value, "");
#if RANGES_CXX_CONSTEXPR >= RANGES_CXX_CONSTEXPR_14 && RANGES_CONSTEXPR_INVOKE
static_assert(ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 3, 4}), "");
static_assert(!ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 3}), "");
static_assert(!ranges::equal(IL{1, 2, 3, 4}, IL{1, 2, 4, 3}), "");
static_assert(ranges::equal(IL{}, IL{}), "");
#endif
return ::test_result();
}

View File

@@ -0,0 +1,209 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include <iterator>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/equal_range.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/insert_iterators.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/join.hpp>
#include <range/v3/view/repeat_n.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/view/transform.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct my_int
{
int value;
};
bool compare(my_int lhs, my_int rhs)
{
return lhs.value < rhs.value;
}
void not_totally_ordered()
{
// This better compile!
std::vector<my_int> vec;
ranges::equal_range(vec, my_int{10}, compare);
}
template<class Iter, class Sent, class T, class Proj = ranges::identity>
void
test_it(Iter first, Sent last, const T& value, Proj proj = Proj{})
{
ranges::subrange<Iter, Iter> i =
ranges::equal_range(first, last, value, ranges::less{}, proj);
for (Iter j = first; j != i.begin(); ++j)
CHECK(ranges::invoke(proj, *j) < value);
for (Iter j = i.begin(); j != last; ++j)
CHECK(!(ranges::invoke(proj, *j) < value));
for (Iter j = first; j != i.end(); ++j)
CHECK(!(value < ranges::invoke(proj, *j)));
for (Iter j = i.end(); j != last; ++j)
CHECK(value < ranges::invoke(proj, *j));
auto res = ranges::equal_range(
ranges::make_subrange(first, last), value, ranges::less{}, proj);
for (Iter j = first; j != res.begin(); ++j)
CHECK(ranges::invoke(proj, *j) < value);
for (Iter j = res.begin(); j != last; ++j)
CHECK(!(ranges::invoke(proj, *j) < value));
for (Iter j = first; j != res.end(); ++j)
CHECK(!(value < ranges::invoke(proj, *j)));
for (Iter j = res.end(); j != last; ++j)
CHECK(value < ranges::invoke(proj, *j));
}
template<class Iter, class Sent = Iter>
void
test_it()
{
using namespace ranges::views;
static constexpr unsigned M = 10;
std::vector<int> v;
auto input = ints | take(100) | transform([](int i){return repeat_n(i,M);}) | join;
ranges::copy(input, ranges::back_inserter(v));
for (int x = 0; x <= (int)M; ++x)
test_it(Iter(v.data()), Sent(v.data()+v.size()), x);
}
template<class Iter, class Sent, class T>
constexpr bool test_constexpr(Iter first, Sent last, const T & value)
{
bool result = true;
const auto i = ranges::equal_range(first, last, value);
for(Iter j = first; j != i.begin(); ++j)
{
STATIC_CHECK_RETURN(*j < value);
}
for(Iter j = i.begin(); j != last; ++j)
{
STATIC_CHECK_RETURN(!(*j < value));
}
for(Iter j = first; j != i.end(); ++j)
{
STATIC_CHECK_RETURN(!(value < *j));
}
for(Iter j = i.end(); j != last; ++j)
{
STATIC_CHECK_RETURN(value < *j);
}
const auto res = ranges::equal_range(ranges::make_subrange(first, last), value);
for(Iter j = first; j != res.begin(); ++j)
{
STATIC_CHECK_RETURN(*j < value);
}
for(Iter j = res.begin(); j != last; ++j)
{
STATIC_CHECK_RETURN(!(*j < value));
}
for(Iter j = first; j != res.end(); ++j)
{
STATIC_CHECK_RETURN(!(value < *j));
}
for(Iter j = res.end(); j != last; ++j)
{
STATIC_CHECK_RETURN(value < *j);
}
return result;
}
template<class Iter, class Sent = Iter>
constexpr bool test_constexpr()
{
constexpr unsigned M = 10;
constexpr unsigned N = 10;
test::array<int, N * M> v{{0}};
for(unsigned i = 0; i < N; ++i)
{
for(unsigned j = 0; j < M; ++j)
{
v[i * M + j] = (int)i;
}
}
for(int x = 0; x <= (int)M; ++x)
{
STATIC_CHECK_RETURN(test_constexpr(Iter(v.data()), Sent(v.data() + v.size()), x));
}
return true;
}
constexpr bool test_constexpr_some()
{
constexpr int d[] = {0, 1, 2, 3};
for(auto e = ranges::begin(d); e < ranges::end(d); ++e)
{
for(int x = -1; x <= 4; ++x)
{
STATIC_CHECK_RETURN(test_constexpr(d, e, x));
}
}
return true;
}
int main()
{
int d[] = {0, 1, 2, 3};
for (int* e = d; e <= d+4; ++e)
for (int x = -1; x <= 4; ++x)
test_it(d, e, x);
test_it<ForwardIterator<const int*> >();
test_it<BidirectionalIterator<const int*> >();
test_it<RandomAccessIterator<const int*> >();
test_it<const int*>();
test_it<ForwardIterator<const int*>, Sentinel<const int*> >();
test_it<BidirectionalIterator<const int*>, Sentinel<const int*> >();
test_it<RandomAccessIterator<const int*>, Sentinel<const int*> >();
{
struct foo { int i; };
foo some_foos[] = {{1}, {2}, {4}};
test_it(some_foos, some_foos + 3, 2, &foo::i);
}
{
STATIC_CHECK(test_constexpr_some());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>>());
STATIC_CHECK(test_constexpr<const int *>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>, Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>, Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>, Sentinel<const int *>>());
}
return ::test_result();
}

View File

@@ -0,0 +1,124 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstring>
#include <string>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/fill.hpp>
#include <range/v3/algorithm/equal.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, class Sent = Iter>
void
test_char()
{
const unsigned n = 4;
char ca[n] = {0};
auto i = ranges::fill(Iter(ca), Sent(ca+n), char(1));
CHECK(ca[0] == 1);
CHECK(ca[1] == 1);
CHECK(ca[2] == 1);
CHECK(ca[3] == 1);
CHECK(i == Iter(ca + 4));
auto rng = ranges::make_subrange(Iter(ca), Sent(ca+n));
i = ranges::fill(rng, char(2));
CHECK(ca[0] == 2);
CHECK(ca[1] == 2);
CHECK(ca[2] == 2);
CHECK(ca[3] == 2);
CHECK(i == Iter(ca + 4));
auto j = ranges::fill(::MakeTestRange(Iter(ca), Sent(ca+n)), char(3));
CHECK(ca[0] == 3);
CHECK(ca[1] == 3);
CHECK(ca[2] == 3);
CHECK(ca[3] == 3);
CHECK(::is_dangling(j));
}
template<class Iter, class Sent = Iter>
void
test_int()
{
const unsigned n = 4;
int ia[n] = {0};
ranges::fill(Iter(ia), Sent(ia+n), 1);
CHECK(ia[0] == 1);
CHECK(ia[1] == 1);
CHECK(ia[2] == 1);
CHECK(ia[3] == 1);
auto rng = ranges::make_subrange(Iter(ia), Sent(ia+n));
ranges::fill(rng, 2);
CHECK(ia[0] == 2);
CHECK(ia[2] == 2);
CHECK(ia[2] == 2);
CHECK(ia[3] == 2);
}
constexpr auto fives()
{
test::array<int, 4> a{{0}};
ranges::fill(a, 5);
return a;
}
constexpr auto fives(int n)
{
test::array<int, 4> a{{0}};
ranges::fill_n(ranges::begin(a), n, 5);
return a;
}
int main()
{
test_char<ForwardIterator<char*> >();
test_char<BidirectionalIterator<char*> >();
test_char<RandomAccessIterator<char*> >();
test_char<char*>();
test_char<ForwardIterator<char*>, Sentinel<char*> >();
test_char<BidirectionalIterator<char*>, Sentinel<char*> >();
test_char<RandomAccessIterator<char*>, Sentinel<char*> >();
test_int<ForwardIterator<int*> >();
test_int<BidirectionalIterator<int*> >();
test_int<RandomAccessIterator<int*> >();
test_int<int*>();
test_int<ForwardIterator<int*>, Sentinel<int*> >();
test_int<BidirectionalIterator<int*>, Sentinel<int*> >();
test_int<RandomAccessIterator<int*>, Sentinel<int*> >();
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ranges::equal(fives(), IL{5, 5, 5, 5}));
STATIC_CHECK(ranges::equal(fives(2), IL{5, 5, 0, 0}));
STATIC_CHECK(!ranges::equal(fives(2), IL{5, 5, 5, 5}));
}
return ::test_result();
}

View File

@@ -0,0 +1,81 @@
// Range v3 library
//
// Copyright Eric Niebler 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstring>
#include <string>
#include <vector>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/algorithm/fill.hpp>
#include <range/v3/core.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#include "../test_utils.hpp"
#ifdef RANGES_CXX_GREATER_THAN_11
RANGES_CXX14_CONSTEXPR auto fives()
{
array<int, 4> a{{0}};
ranges::fill(a, 5);
return a;
}
RANGES_CXX14_CONSTEXPR auto fives(int n)
{
array<int, 4> a{{0}};
ranges::fill_n(ranges::begin(a), n, 5);
return a;
}
#endif
int main()
{
test_char<forward_iterator<char *>>();
test_char<bidirectional_iterator<char *>>();
test_char<random_access_iterator<char *>>();
test_char<char *>();
test_char<forward_iterator<char *>, sentinel<char *>>();
test_char<bidirectional_iterator<char *>, sentinel<char *>>();
test_char<random_access_iterator<char *>, sentinel<char *>>();
test_int<forward_iterator<int *>>();
test_int<bidirectional_iterator<int *>>();
test_int<random_access_iterator<int *>>();
test_int<int *>();
test_int<forward_iterator<int *>, sentinel<int *>>();
test_int<bidirectional_iterator<int *>, sentinel<int *>>();
test_int<random_access_iterator<int *>, sentinel<int *>>();
#ifdef RANGES_CXX_GREATER_THAN_11
{
STATIC_CHECK(ranges::equal(fives(), {5, 5, 5, 5}));
STATIC_CHECK(ranges::equal(fives(2), {5, 5, 0, 0}));
STATIC_CHECK(!ranges::equal(fives(2), {5, 5, 5, 5}));
}
#endif
return ::test_result();
}

View File

@@ -0,0 +1,113 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/find.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct S
{
int i_;
};
template<class Rng, class T>
constexpr T ret_val(Rng r, T val)
{
auto rng = r;
auto pi = ranges::find(rng, val);
return *pi;
}
template<class Rng, class T>
constexpr bool found(Rng r, T val)
{
auto rng = r;
auto pi = ranges::find(rng, val);
return pi != ranges::end(rng);
}
int main()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5};
constexpr auto s = size(ia);
{
InputIterator<const int*> r = find(InputIterator<const int*>(ia),
InputIterator<const int*>(ia+s), 3);
CHECK(*r == 3);
r = find(InputIterator<const int*>(ia),
InputIterator<const int*>(ia+s), 10);
CHECK(r == InputIterator<const int*>(ia+s));
r = find(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s), 3);
CHECK(*r == 3);
r = find(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s), 10);
CHECK(r == InputIterator<const int*>(ia+s));
}
{
int *pi = find(ia, 3);
CHECK(*pi == 3);
pi = find(ia, 10);
CHECK(pi == ia+s);
}
{
#ifndef RANGES_WORKAROUND_MSVC_573728
auto pj0 = find(std::move(ia), 3);
CHECK(::is_dangling(pj0));
#endif // RANGES_WORKAROUND_MSVC_573728
std::vector<int> vec(begin(ia), end(ia));
auto pj1 = find(std::move(vec), 3);
CHECK(::is_dangling(pj1));
auto pj2 = find(views::all(ia), 10);
CHECK(pj2 == ia+s);
}
{
S sa[] = {{0}, {1}, {2}, {3}, {4}, {5}};
S *ps = find(sa, 3, &S::i_);
CHECK(ps->i_ == 3);
ps = find(sa, 10, &S::i_);
CHECK(ps == end(sa));
}
{
// https://github.com/Microsoft/Range-V3-VS2015/issues/9
auto vec = std::vector<std::string>{{"a"}, {"b"}, {"c"}};
auto it = ranges::find(vec, "b");
CHECK(it == vec.begin() + 1);
}
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ret_val(IL{1, 2}, 2) == 2);
STATIC_CHECK(found(IL{1, 3, 4}, 4));
STATIC_CHECK(!found(IL{1, 3, 4}, 5));
}
return ::test_result();
}

View File

@@ -0,0 +1,349 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/find_end.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 0, 1, 0};
auto ia_b = begin(ia);
auto ia_e = end(ia);
constexpr auto sa = size(ia);
int b[] = {0};
int c[] = {0, 1};
int d[] = {0, 1, 2};
int e[] = {0, 1, 2, 3};
int f[] = {0, 1, 2, 3, 4};
int g[] = {0, 1, 2, 3, 4, 5};
int h[] = {0, 1, 2, 3, 4, 5, 6};
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(b), b + 1).begin() == ia + sa - 1);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(c), c + 2).begin() == ia + 18);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(d), d + 3).begin() == ia + 15);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(e), e + 4).begin() == ia + 11);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(f), f + 5).begin() == ia + 6);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(g), g + 6).begin() == ia);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(h), h + 7).begin() == ia + sa);
STATIC_CHECK_RETURN(find_end(ia_b, ia_e, begin(b), b).begin() == ia + sa);
STATIC_CHECK_RETURN(find_end(ia_b, ia_b, begin(b), b + 1).begin() == ia);
auto ir = make_subrange(ia_b, ia_e);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(b), b + 1)).begin() == ia + sa - 1);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(c), c + 2)).begin() == ia + 18);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(d), d + 3)).begin() == ia + 15);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(e), e + 4)).begin() == ia + 11);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(f), f + 5)).begin() == ia + 6);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(g), g + 6)).begin() == ia);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(h), h + 7)).begin() == ia + sa);
STATIC_CHECK_RETURN(find_end(ir, make_subrange(begin(b), b)).begin() == ia + sa);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(b), b + 1)).begin() == ia + sa - 1);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(c), c + 2)).begin() == ia + 18);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(d), d + 3)).begin() == ia + 15);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(e), e + 4)).begin() == ia + 11);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(f), f + 5)).begin() == ia + 6);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(g), g + 6)).begin() == ia);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(h), h + 7)).begin() == ia + sa);
STATIC_CHECK_RETURN(find_end(std::move(ir), make_subrange(begin(b), b)).begin() == ia + sa);
auto er = make_subrange(ia_b, ia);
STATIC_CHECK_RETURN(find_end(er, make_subrange(b, b + 1)).begin() == ia);
STATIC_CHECK_RETURN(find_end(std::move(er), make_subrange(b, b + 1)).begin() == ia);
return true;
}
template<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>
void
test()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 0, 1, 0};
constexpr auto sa = size(ia);
int b[] = {0};
int c[] = {0, 1};
int d[] = {0, 1, 2};
int e[] = {0, 1, 2, 3};
int f[] = {0, 1, 2, 3, 4};
int g[] = {0, 1, 2, 3, 4, 5};
int h[] = {0, 1, 2, 3, 4, 5, 6};
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1)).begin() == Iter1(ia + sa - 1));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1)).end() == Iter1(ia + sa - 1 + 1));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2)).begin() == Iter1(ia + 18));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2)).end() == Iter1(ia + 18 + 2));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3)).begin() == Iter1(ia + 15));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3)).end() == Iter1(ia + 15 + 3));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4)).begin() == Iter1(ia + 11));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4)).end() == Iter1(ia + 11 + 4));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5)).begin() == Iter1(ia + 6));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5)).end() == Iter1(ia + 6 + 5));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6)).begin() == Iter1(ia));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6)).end() == Iter1(ia + 6));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7)).begin() == Iter1(ia + sa));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7)).end() == Iter1(ia + sa));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b)).begin() == Iter1(ia + sa));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b)).end() == Iter1(ia + sa));
CHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1)).begin() == Iter1(ia));
CHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1)).end() == Iter1(ia));
auto ir = make_subrange(Iter1(ia), Sent1(ia + sa));
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b + 1))).begin() == Iter1(ia + sa - 1));
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b + 1))).end() == Iter1(ia + sa - 1 + 1));
CHECK(find_end(ir, make_subrange(Iter2(c), Sent2(c + 2))).begin() == Iter1(ia + 18));
CHECK(find_end(ir, make_subrange(Iter2(c), Sent2(c + 2))).end() == Iter1(ia + 18 + 2));
CHECK(find_end(ir, make_subrange(Iter2(d), Sent2(d + 3))).begin() == Iter1(ia + 15));
CHECK(find_end(ir, make_subrange(Iter2(d), Sent2(d + 3))).end() == Iter1(ia + 15 + 3));
CHECK(find_end(ir, make_subrange(Iter2(e), Sent2(e + 4))).begin() == Iter1(ia + 11));
CHECK(find_end(ir, make_subrange(Iter2(e), Sent2(e + 4))).end() == Iter1(ia + 11 + 4));
CHECK(find_end(ir, make_subrange(Iter2(f), Sent2(f + 5))).begin() == Iter1(ia + 6));
CHECK(find_end(ir, make_subrange(Iter2(f), Sent2(f + 5))).end() == Iter1(ia + 6 + 5));
CHECK(find_end(ir, make_subrange(Iter2(g), Sent2(g + 6))).begin() == Iter1(ia));
CHECK(find_end(ir, make_subrange(Iter2(g), Sent2(g + 6))).end() == Iter1(ia + 6));
CHECK(find_end(ir, make_subrange(Iter2(h), Sent2(h + 7))).begin() == Iter1(ia + sa));
CHECK(find_end(ir, make_subrange(Iter2(h), Sent2(h + 7))).end() == Iter1(ia + sa));
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b))).begin() == Iter1(ia + sa));
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b))).end() == Iter1(ia + sa));
CHECK(find_end(std::move(ir), make_subrange(Iter2(b), Sent2(b + 1))).begin() == Iter1(ia + sa - 1));
CHECK(find_end(std::move(ir), make_subrange(Iter2(c), Sent2(c + 2))).begin() == Iter1(ia + 18));
CHECK(find_end(std::move(ir), make_subrange(Iter2(c), Sent2(c + 2))).end() == Iter1(ia + 18 + 2));
CHECK(find_end(std::move(ir), make_subrange(Iter2(d), Sent2(d + 3))).begin() == Iter1(ia + 15));
CHECK(find_end(std::move(ir), make_subrange(Iter2(d), Sent2(d + 3))).end() == Iter1(ia + 15 + 3));
CHECK(find_end(std::move(ir), make_subrange(Iter2(e), Sent2(e + 4))).begin() == Iter1(ia + 11));
CHECK(find_end(std::move(ir), make_subrange(Iter2(e), Sent2(e + 4))).end() == Iter1(ia + 11 + 4));
CHECK(find_end(std::move(ir), make_subrange(Iter2(f), Sent2(f + 5))).begin() == Iter1(ia + 6));
CHECK(find_end(std::move(ir), make_subrange(Iter2(f), Sent2(f + 5))).end() == Iter1(ia + 6 + 5));
CHECK(find_end(std::move(ir), make_subrange(Iter2(g), Sent2(g + 6))).begin() == Iter1(ia));
CHECK(find_end(std::move(ir), make_subrange(Iter2(g), Sent2(g + 6))).end() == Iter1(ia + 6));
CHECK(find_end(std::move(ir), make_subrange(Iter2(h), Sent2(h + 7))).begin() == Iter1(ia + sa));
CHECK(find_end(std::move(ir), make_subrange(Iter2(h), Sent2(h + 7))).end() == Iter1(ia + sa));
CHECK(find_end(std::move(ir), make_subrange(Iter2(b), Sent2(b))).begin() == Iter1(ia + sa));
auto er = make_subrange(Iter1(ia), Sent1(ia));
CHECK(find_end(er, make_subrange(Iter2(b), Sent2(b + 1))).begin() == Iter1(ia));
CHECK(find_end(er, make_subrange(Iter2(b), Sent2(b + 1))).end() == Iter1(ia));
CHECK(find_end(std::move(er), make_subrange(Iter2(b), Sent2(b + 1))).begin() == Iter1(ia));
CHECK(find_end(std::move(er), make_subrange(Iter2(b), Sent2(b + 1))).end() == Iter1(ia));
}
struct count_equal
{
static unsigned count;
template<class T>
bool operator()(const T& x, const T& y)
{
++count; return x == y;
}
};
unsigned count_equal::count = 0;
template<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>
void
test_pred()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 0, 1, 0};
constexpr auto sa = size(ia);
int b[] = {0};
int c[] = {0, 1};
int d[] = {0, 1, 2};
int e[] = {0, 1, 2, 3};
int f[] = {0, 1, 2, 3, 4};
int g[] = {0, 1, 2, 3, 4, 5};
int h[] = {0, 1, 2, 3, 4, 5, 6};
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1), count_equal()).begin() == Iter1(ia + sa - 1));
CHECK(count_equal::count <= 1 * (sa - 1 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2), count_equal()).begin() == Iter1(ia + 18));
CHECK(count_equal::count <= 2 * (sa - 2 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3), count_equal()).begin() == Iter1(ia + 15));
CHECK(count_equal::count <= 3 * (sa - 3 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4), count_equal()).begin() == Iter1(ia + 11));
CHECK(count_equal::count <= 4 * (sa - 4 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5), count_equal()).begin() == Iter1(ia + 6));
CHECK(count_equal::count <= 5 * (sa - 5 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6), count_equal()).begin() == Iter1(ia));
CHECK(count_equal::count <= 6 * (sa - 6 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7), count_equal()).begin() == Iter1(ia + sa));
CHECK(count_equal::count <= 7 * (sa - 7 + 1));
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b), count_equal()).begin() == Iter1(ia + sa));
CHECK(count_equal::count == 0u);
count_equal::count = 0;
CHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1), count_equal()).begin() == Iter1(ia));
CHECK(count_equal::count == 0u);
auto ir = make_subrange(Iter1(ia), Sent1(ia + sa));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b + 1)), count_equal()).begin() == Iter1(ia + sa - 1));
CHECK(count_equal::count <= 1 * (sa - 1 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(c), Sent2(c + 2)), count_equal()).begin() == Iter1(ia + 18));
CHECK(count_equal::count <= 2 * (sa - 2 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(d), Sent2(d + 3)), count_equal()).begin() == Iter1(ia + 15));
CHECK(count_equal::count <= 3 * (sa - 3 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(e), Sent2(e + 4)), count_equal()).begin() == Iter1(ia + 11));
CHECK(count_equal::count <= 4 * (sa - 4 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(f), Sent2(f + 5)), count_equal()).begin() == Iter1(ia + 6));
CHECK(count_equal::count <= 5 * (sa - 5 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(g), Sent2(g + 6)), count_equal()).begin() == Iter1(ia));
CHECK(count_equal::count <= 6 * (sa - 6 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(h), Sent2(h + 7)), count_equal()).begin() == Iter1(ia + sa));
CHECK(count_equal::count <= 7 * (sa - 7 + 1));
count_equal::count = 0;
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b)), count_equal()).begin() == Iter1(ia + sa));
CHECK(count_equal::count == 0u);
count_equal::count = 0;
auto er = make_subrange(Iter1(ia), Sent1(ia));
CHECK(find_end(er, make_subrange(Iter2(b), Sent2(b + 1)), count_equal()).begin() == Iter1(ia));
CHECK(count_equal::count == 0u);
static_assert(std::is_same<subrange<Iter1>, decltype(find_end(er, {1, 2, 3}))>::value, "");
}
struct S
{
int i_;
};
template<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>
void
test_proj()
{
using namespace ranges;
S ia[] = {{0}, {1}, {2}, {3}, {4}, {5}, {0}, {1}, {2}, {3}, {4}, {0}, {1}, {2}, {3}, {0}, {1}, {2}, {0}, {1}, {0}};
constexpr auto sa = size(ia);
int b[] = {0};
int c[] = {0, 1};
int d[] = {0, 1, 2};
int e[] = {0, 1, 2, 3};
int f[] = {0, 1, 2, 3, 4};
int g[] = {0, 1, 2, 3, 4, 5};
int h[] = {0, 1, 2, 3, 4, 5, 6};
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1), equal_to(), &S::i_).begin() == Iter1(ia + sa - 1));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2), equal_to(), &S::i_).begin() == Iter1(ia + 18));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3), equal_to(), &S::i_).begin() == Iter1(ia + 15));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4), equal_to(), &S::i_).begin() == Iter1(ia + 11));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5), equal_to(), &S::i_).begin() == Iter1(ia + 6));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6), equal_to(), &S::i_).begin() == Iter1(ia));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7), equal_to(), &S::i_).begin() == Iter1(ia + sa));
CHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b), equal_to(), &S::i_).begin() == Iter1(ia + sa));
CHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1), equal_to(), &S::i_).begin() == Iter1(ia));
auto ir = make_subrange(Iter1(ia), Sent1(ia + sa));
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b + 1)), equal_to(), &S::i_).begin() == Iter1(ia + sa - 1));
CHECK(find_end(ir, make_subrange(Iter2(c), Sent2(c + 2)), equal_to(), &S::i_).begin() == Iter1(ia + 18));
CHECK(find_end(ir, make_subrange(Iter2(d), Sent2(d + 3)), equal_to(), &S::i_).begin() == Iter1(ia + 15));
CHECK(find_end(ir, make_subrange(Iter2(e), Sent2(e + 4)), equal_to(), &S::i_).begin() == Iter1(ia + 11));
CHECK(find_end(ir, make_subrange(Iter2(f), Sent2(f + 5)), equal_to(), &S::i_).begin() == Iter1(ia + 6));
CHECK(find_end(ir, make_subrange(Iter2(g), Sent2(g + 6)), equal_to(), &S::i_).begin() == Iter1(ia));
CHECK(find_end(ir, make_subrange(Iter2(h), Sent2(h + 7)), equal_to(), &S::i_).begin() == Iter1(ia + sa));
CHECK(find_end(ir, make_subrange(Iter2(b), Sent2(b)), equal_to(), &S::i_).begin() == Iter1(ia + sa));
auto er = make_subrange(Iter1(ia), Sent1(ia));
CHECK(find_end(er, make_subrange(Iter2(b), Sent2(b + 1)), equal_to(), &S::i_).begin() == Iter1(ia));
}
int main()
{
test<ForwardIterator<const int*>, ForwardIterator<const int*> >();
// test<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
// test<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
// test<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
// test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
// test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
// test<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
// test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
// test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
// test<ForwardIterator<const int*>, ForwardIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<ForwardIterator<const int*>, ForwardIterator<const int*> >();
// test_pred<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
// test_pred<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
// test_pred<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
// test_pred<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
// test_pred<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
// test_pred<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
// test_pred<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
// test_pred<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
// test_pred<ForwardIterator<const int*>, ForwardIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<ForwardIterator<const int*>, BidirectionalIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<ForwardIterator<const int*>, RandomAccessIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<BidirectionalIterator<const int*>, ForwardIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<RandomAccessIterator<const int*>, ForwardIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_pred<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, Sentinel<const int*>, Sentinel<const int *> >();
// test_proj<ForwardIterator<const S*>, ForwardIterator<const int*> >();
// test_proj<ForwardIterator<const S*>, BidirectionalIterator<const int*> >();
// test_proj<ForwardIterator<const S*>, RandomAccessIterator<const int*> >();
// test_proj<BidirectionalIterator<const S*>, ForwardIterator<const int*> >();
// test_proj<BidirectionalIterator<const S*>, BidirectionalIterator<const int*> >();
// test_proj<BidirectionalIterator<const S*>, RandomAccessIterator<const int*> >();
// test_proj<RandomAccessIterator<const S*>, ForwardIterator<const int*> >();
// test_proj<RandomAccessIterator<const S*>, BidirectionalIterator<const int*> >();
// test_proj<RandomAccessIterator<const S*>, RandomAccessIterator<const int*> >();
// test_proj<ForwardIterator<const S*>, ForwardIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<ForwardIterator<const S*>, BidirectionalIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<ForwardIterator<const S*>, RandomAccessIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<BidirectionalIterator<const S*>, ForwardIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<BidirectionalIterator<const S*>, BidirectionalIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<BidirectionalIterator<const S*>, RandomAccessIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<RandomAccessIterator<const S*>, ForwardIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<RandomAccessIterator<const S*>, BidirectionalIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
// test_proj<RandomAccessIterator<const S*>, RandomAccessIterator<const int*>, Sentinel<const S*>, Sentinel<const int *> >();
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,255 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/core.hpp>
#include <range/v3/algorithm/find_first_of.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#include "../test_utils.hpp"
namespace rng = ranges;
void test_iter()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
static constexpr auto sa = size(ia);
int ib[] = {1, 3, 5, 7};
static constexpr auto sb = size(ib);
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sb)) ==
InputIterator<const int*>(ia+1));
int ic[] = {7};
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ic),
Sentinel<const int*>(ic + 1)) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ic),
Sentinel<const int*>(ic)) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia),
ForwardIterator<const int*>(ic),
Sentinel<const int*>(ic+1)) ==
InputIterator<const int*>(ia));
}
void test_iter_pred()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
static constexpr auto sa = size(ia);
int ib[] = {1, 3, 5, 7};
static constexpr auto sb = size(ib);
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sb),
std::equal_to<int>()) ==
InputIterator<const int*>(ia+1));
int ic[] = {7};
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ic),
Sentinel<const int*>(ic + 1),
std::equal_to<int>()) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ic),
Sentinel<const int*>(ic),
std::equal_to<int>()) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(InputIterator<const int*>(ia),
Sentinel<const int*>(ia),
ForwardIterator<const int*>(ic),
Sentinel<const int*>(ic+1),
std::equal_to<int>()) ==
InputIterator<const int*>(ia));
}
void test_rng()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
static constexpr auto sa = size(ia);
int ib[] = {1, 3, 5, 7};
static constexpr auto sb = size(ib);
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sb))) ==
InputIterator<const int*>(ia+1));
CHECK(::is_dangling(rng::find_first_of(::MakeTestRange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sb)))));
int ic[] = {7};
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic + 1))) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic))) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic+1))) ==
InputIterator<const int*>(ia));
CHECK(::is_dangling(rng::find_first_of(::MakeTestRange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic + 1)))));
CHECK(::is_dangling(rng::find_first_of(::MakeTestRange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic)))));
CHECK(::is_dangling(rng::find_first_of(::MakeTestRange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic+1)))));
}
void test_rng_pred()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
static constexpr auto sa = size(ia);
int ib[] = {1, 3, 5, 7};
static constexpr auto sb = size(ib);
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sb)),
std::equal_to<int>()) ==
InputIterator<const int*>(ia+1));
int ic[] = {7};
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic + 1)),
std::equal_to<int>()) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + sa)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic)),
std::equal_to<int>()) ==
InputIterator<const int*>(ia+sa));
CHECK(rng::find_first_of(make_subrange(InputIterator<const int*>(ia),
InputIterator<const int*>(ia)),
make_subrange(ForwardIterator<const int*>(ic),
ForwardIterator<const int*>(ic+1)),
std::equal_to<int>()) ==
InputIterator<const int*>(ia));
}
struct S
{
int i;
};
void test_rng_pred_proj()
{
using namespace ranges;
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{0}, S{1}, S{2}, S{3}};
static constexpr auto sa = size(ia);
S ib[] = {S{1}, S{3}, S{5}, S{7}};
static constexpr auto sb = size(ib);
CHECK(rng::find_first_of(make_subrange(InputIterator<const S*>(ia),
InputIterator<const S*>(ia + sa)),
make_subrange(ForwardIterator<const S*>(ib),
ForwardIterator<const S*>(ib + sb)),
std::equal_to<int>(), &S::i, &S::i) ==
InputIterator<const S*>(ia+1));
S ic[] = {S{7}};
CHECK(rng::find_first_of(make_subrange(InputIterator<const S*>(ia),
InputIterator<const S*>(ia + sa)),
make_subrange(ForwardIterator<const S*>(ic),
ForwardIterator<const S*>(ic + 1)),
std::equal_to<int>(), &S::i, &S::i) ==
InputIterator<const S*>(ia+sa));
CHECK(rng::find_first_of(make_subrange(InputIterator<const S*>(ia),
InputIterator<const S*>(ia + sa)),
make_subrange(ForwardIterator<const S*>(ic),
ForwardIterator<const S*>(ic)),
std::equal_to<int>(), &S::i, &S::i) ==
InputIterator<const S*>(ia+sa));
CHECK(rng::find_first_of(make_subrange(InputIterator<const S*>(ia),
InputIterator<const S*>(ia)),
make_subrange(ForwardIterator<const S*>(ic),
ForwardIterator<const S*>(ic+1)),
std::equal_to<int>(), &S::i, &S::i) ==
InputIterator<const S*>(ia));
}
void test_constexpr()
{
using namespace ranges;
constexpr int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
constexpr auto sa = size(ia);
constexpr int ib[] = {1, 3, 5, 7};
constexpr auto sb = size(ib);
STATIC_CHECK(
rng::find_first_of(as_lvalue(make_subrange(InputIterator<const int *>(ia),
InputIterator<const int *>(ia + sa))),
make_subrange(ForwardIterator<const int *>(ib),
ForwardIterator<const int *>(ib + sb)),
equal_to{}) == InputIterator<const int *>(ia + 1));
constexpr int ic[] = {7};
STATIC_CHECK(
rng::find_first_of(as_lvalue(make_subrange(InputIterator<const int *>(ia),
InputIterator<const int *>(ia + sa))),
make_subrange(ForwardIterator<const int *>(ic),
ForwardIterator<const int *>(ic + 1)),
equal_to{}) == InputIterator<const int *>(ia + sa));
STATIC_CHECK(
rng::find_first_of(as_lvalue(make_subrange(InputIterator<const int *>(ia),
InputIterator<const int *>(ia + sa))),
make_subrange(ForwardIterator<const int *>(ic),
ForwardIterator<const int *>(ic)),
equal_to{}) == InputIterator<const int *>(ia + sa));
STATIC_CHECK(
rng::find_first_of(as_lvalue(make_subrange(InputIterator<const int *>(ia),
InputIterator<const int *>(ia))),
make_subrange(ForwardIterator<const int *>(ic),
ForwardIterator<const int *>(ic + 1)),
equal_to{}) == InputIterator<const int *>(ia));
}
int main()
{
::test_iter();
::test_iter_pred();
::test_rng();
::test_rng_pred();
::test_rng_pred_proj();
return ::test_result();
}

View File

@@ -0,0 +1,116 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/find_if.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct S
{
int i_;
};
constexpr bool is_three(int i)
{
return i == 3;
}
template<class Rng>
constexpr bool contains_three(Rng r)
{
auto it = ranges::find_if(r, is_three);
return it != ranges::end(r);
}
int main()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 5};
constexpr auto s = size(ia);
{
InputIterator<const int*> r = find_if(InputIterator<const int*>(ia),
InputIterator<const int*>(ia + s),
[](int i){return i == 3;});
CHECK(*r == 3);
r = find_if(InputIterator<const int*>(ia),
InputIterator<const int*>(ia+s),
[](int i){return i == 10;});
CHECK(r == InputIterator<const int*>(ia+s));
r = find_if(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
[](int i){return i == 3;});
CHECK(*r == 3);
r = find_if(InputIterator<const int*>(ia),
Sentinel<const int*>(ia+s),
[](int i){return i == 10;});
CHECK(r == InputIterator<const int*>(ia+s));
}
{
int *pi = find_if(ia, [](int i){return i == 3;});
CHECK(*pi == 3);
pi = find_if(ia, [](int i){return i == 10;});
CHECK(pi == ia+s);
}
#ifndef RANGES_WORKAROUND_MSVC_573728
{
auto pj0 = find_if(std::move(ia), [](int i){return i == 3;});
CHECK(::is_dangling(pj0));
auto pj1 = find_if(std::move(ia), [](int i){return i == 10;});
CHECK(::is_dangling(pj1));
}
#endif // RANGES_WORKAROUND_MSVC_573728
{
std::vector<int> const vec(begin(ia), end(ia));
auto pj0 = find_if(std::move(vec), [](int i){return i == 3;});
CHECK(::is_dangling(pj0));
auto pj1 = find_if(std::move(vec), [](int i){return i == 10;});
CHECK(::is_dangling(pj1));
}
{
auto* ignore = find_if(ranges::views::all(ia), [](int i){return i == 10;});
(void)ignore;
}
{
S sa[] = {{0}, {1}, {2}, {3}, {4}, {5}};
S *ps = find_if(sa, [](int i){return i == 3;}, &S::i_);
CHECK(ps->i_ == 3);
ps = find_if(sa, [](int i){return i == 10;}, &S::i_);
CHECK(ps == end(sa));
}
{
using IL = std::initializer_list<int>;
STATIC_CHECK(contains_three(IL{0, 1, 2, 3}));
STATIC_CHECK(!contains_three(IL{0, 1, 2}));
}
return ::test_result();
}

View File

@@ -0,0 +1,52 @@
// Range v3 library
//
// Copyright Eric Niebler 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <range/v3/algorithm/find_if_not.hpp>
#include <range/v3/core.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
constexpr bool is_three(int i)
{
return i == 3;
}
template<class Rng>
constexpr bool contains_other_than_three(Rng r)
{
auto it = ranges::find_if_not(r, is_three);
return it != ranges::end(r);
}
int main()
{
using namespace ranges;
{
using IL = std::initializer_list<int>;
STATIC_CHECK(contains_other_than_three(IL{3, 3, 2, 3}));
STATIC_CHECK(!contains_other_than_three(IL{3, 3, 3}));
}
return ::test_result();
}

View File

@@ -0,0 +1,103 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cmath>
#include <functional>
#include <range/v3/algorithm/fold.hpp>
#include <range/v3/algorithm/min.hpp>
#include <range/v3/core.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct Approx
{
double value;
Approx(double v)
: value(v)
{}
friend bool operator==(Approx a, double d)
{
return std::fabs(a.value - d) < 0.001;
}
friend bool operator==(double d, Approx a)
{
return a == d;
}
};
template<class Iter, class Sent = Iter>
void test_left()
{
double da[] = {0.25, 0.75};
CHECK(ranges::fold_left(Iter(da), Sent(da), 1, std::plus<>()) == Approx{1.0});
CHECK(ranges::fold_left(Iter(da), Sent(da + 2), 1, std::plus<>()) == Approx{2.0});
CHECK(ranges::fold_left_first(Iter(da), Sent(da), ranges::min) == ranges::nullopt);
CHECK(ranges::fold_left_first(Iter(da), Sent(da + 2), ranges::min) ==
ranges::optional<Approx>(0.25));
using ranges::make_subrange;
CHECK(ranges::fold_left(make_subrange(Iter(da), Sent(da)), 1, std::plus<>()) ==
Approx{1.0});
CHECK(ranges::fold_left(make_subrange(Iter(da), Sent(da + 2)), 1, std::plus<>()) ==
Approx{2.0});
CHECK(ranges::fold_left_first(make_subrange(Iter(da), Sent(da)), ranges::min) ==
ranges::nullopt);
CHECK(ranges::fold_left_first(make_subrange(Iter(da), Sent(da + 2)), ranges::min) ==
ranges::optional<Approx>(0.25));
}
void test_right()
{
double da[] = {0.25, 0.75};
CHECK(ranges::fold_right(da, da + 2, 1, std::plus<>()) == Approx{2.0});
CHECK(ranges::fold_right(da, 1, std::plus<>()) == Approx{2.0});
// f(0.25, f(0.75, 1))
CHECK(ranges::fold_right(da, da + 2, 1, std::minus<>()) == Approx{0.5});
CHECK(ranges::fold_right(da, 1, std::minus<>()) == Approx{0.5});
int xs[] = {1, 2, 3};
auto concat = [](int i, std::string s) { return s + std::to_string(i); };
CHECK(ranges::fold_right(xs, xs + 2, std::string(), concat) == "21");
CHECK(ranges::fold_right(xs, std::string(), concat) == "321");
}
int main()
{
test_left<InputIterator<const double *>>();
test_left<ForwardIterator<const double *>>();
test_left<BidirectionalIterator<const double *>>();
test_left<RandomAccessIterator<const double *>>();
test_left<const double *>();
test_left<InputIterator<const double *>, Sentinel<const double *>>();
test_left<ForwardIterator<const double *>, Sentinel<const double *>>();
test_left<BidirectionalIterator<const double *>, Sentinel<const double *>>();
test_left<RandomAccessIterator<const double *>, Sentinel<const double *>>();
test_right();
return ::test_result();
}

View File

@@ -0,0 +1,63 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/for_each.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
struct S
{
void p() const { *p_ += i_; }
int *p_;
int i_;
};
constexpr int void_f(int const &)
{
return 3;
}
int main()
{
int sum = 0;
auto fun = [&](int i){sum += i; };
std::vector<int> v1 { 0, 2, 4, 6 };
CHECK(ranges::for_each(v1.begin(), v1.end(), fun).in == v1.end());
CHECK(ranges::for_each(v1, fun).in == v1.end());
CHECK(sum == 24);
sum = 0;
auto rfun = [&](int & i){sum += i; };
CHECK(ranges::for_each(v1.begin(), v1.end(), rfun).in == v1.end());
CHECK(ranges::for_each(v1, rfun).in == v1.end());
CHECK(sum == 24);
sum = 0;
std::vector<S> v2{{&sum, 0}, {&sum, 2}, {&sum, 4}, {&sum, 6}};
CHECK(ranges::for_each(v2.begin(), v2.end(), &S::p).in == v2.end());
CHECK(ranges::for_each(v2, &S::p).in == v2.end());
CHECK(sum == 24);
sum = 0;
CHECK(::is_dangling(ranges::for_each(::MakeTestRange(v1.begin(), v1.end()), fun).in));
CHECK(sum == 12);
{
constexpr auto rng = test::array<int, 4>{{0, 2, 4, 6}};
STATIC_CHECK(ranges::for_each(rng, void_f).in == ranges::end(rng));
}
return ::test_result();
}

View File

@@ -0,0 +1,77 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Rostislav Khlebnikov 2017
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/for_each_n.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
struct S
{
void p() const { *p_ += i_; }
int *p_;
int i_;
};
constexpr bool test_constexpr()
{
// lambda closure types are non-literal types before C++17
struct
{
constexpr void operator()(int i)
{
sum_ += i;
}
int sum_ = 0;
} fun;
constexpr test::array<int, 5> v1{{1, 2, 4, 6}};
STATIC_CHECK_RETURN(ranges::for_each_n(v1.begin(), 2, ranges::ref(fun)) ==
v1.begin() + 2);
STATIC_CHECK_RETURN(ranges::for_each_n(v1, 2, ranges::ref(fun)) == v1.begin() + 2);
STATIC_CHECK_RETURN(fun.sum_ == 3 * 2);
return true;
}
int main()
{
int sum = 0;
auto const fun = [&](int i){ sum += i; };
std::vector<int> v1 { 1, 2, 4, 6 };
CHECK(ranges::for_each_n(v1.begin(), 2, fun) == v1.begin() + 2);
CHECK(ranges::for_each_n(v1, 2, fun) == v1.begin() + 2);
CHECK(sum == 3 * 2);
sum = 0;
auto const rfun = [&](int & i){ sum += i; };
auto const sz = static_cast<int>(v1.size());
CHECK(ranges::for_each_n(v1.begin(), sz, rfun) == v1.end());
CHECK(ranges::for_each_n(v1, sz, rfun) == v1.end());
CHECK(sum == 13 * 2);
sum = 0;
std::vector<S> v2{{&sum, 1}, {&sum, 2}, {&sum, 4}, {&sum, 6}};
CHECK(ranges::for_each_n(v2.begin(), 3, &S::p) == v2.begin() + 3);
CHECK(ranges::for_each_n(v2, 3, &S::p) == v2.begin() + 3);
CHECK(sum == 7 * 2);
sum = 0;
CHECK(ranges::for_each_n(v2.begin(), 4, fun, &S::i_) == v2.begin() + 4);
CHECK(ranges::for_each_n(v2, 4, fun, &S::i_) == v2.begin() + 4);
CHECK(sum == 13 * 2);
STATIC_CHECK(test_constexpr());
return ::test_result();
}

View File

@@ -0,0 +1,146 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/generate.hpp>
#include <range/v3/iterator/insert_iterators.hpp>
#include <range/v3/view/counted.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
struct gen_test
{
int i_;
constexpr gen_test()
: i_{}
{}
constexpr gen_test(int i)
: i_(i)
{}
constexpr int operator()()
{
return i_++;
}
};
template<class Iter, class Sent = Iter>
void
test()
{
const unsigned n = 4;
int ia[n] = {0};
ranges::generate_result<Iter, gen_test> res = ranges::generate(Iter(ia), Sent(ia + n), gen_test(1));
CHECK(ia[0] == 1);
CHECK(ia[1] == 2);
CHECK(ia[2] == 3);
CHECK(ia[3] == 4);
CHECK(res.out == Iter(ia + n));
CHECK(res.fun.i_ == 5);
auto rng = ::MakeTestRange(Iter(ia), Sent(ia + n));
res = ranges::generate(rng, res.fun);
CHECK(ia[0] == 5);
CHECK(ia[1] == 6);
CHECK(ia[2] == 7);
CHECK(ia[3] == 8);
CHECK(res.out == Iter(ia + n));
CHECK(res.fun.i_ == 9);
auto res2 = ranges::generate(std::move(rng), res.fun);
CHECK(ia[0] == 9);
CHECK(ia[1] == 10);
CHECK(ia[2] == 11);
CHECK(ia[3] == 12);
CHECK(::is_dangling(res2.out));
CHECK(res2.fun.i_ == 13);
}
void test2()
{
// Test ranges::generate with a genuine output range
std::vector<int> v;
auto rng = ranges::views::counted(ranges::back_inserter(v), 5);
ranges::generate(rng, gen_test(1));
CHECK(v.size() == 5u);
CHECK(v[0] == 1);
CHECK(v[1] == 2);
CHECK(v[2] == 3);
CHECK(v[3] == 4);
CHECK(v[4] == 5);
}
template<class Iter, class Sent = Iter>
constexpr bool test_constexpr()
{
const unsigned n = 4;
int ia[n] = {0};
const auto res = ranges::generate(Iter(ia), Sent(ia + n), gen_test(1));
STATIC_CHECK_RETURN(ia[0] == 1);
STATIC_CHECK_RETURN(ia[1] == 2);
STATIC_CHECK_RETURN(ia[2] == 3);
STATIC_CHECK_RETURN(ia[3] == 4);
STATIC_CHECK_RETURN(res.out == Iter(ia + n));
STATIC_CHECK_RETURN(res.fun.i_ == 5);
auto rng = ranges::make_subrange(Iter(ia), Sent(ia + n));
const auto res2 = ranges::generate(rng, res.fun);
STATIC_CHECK_RETURN(ia[0] == 5);
STATIC_CHECK_RETURN(ia[1] == 6);
STATIC_CHECK_RETURN(ia[2] == 7);
STATIC_CHECK_RETURN(ia[3] == 8);
STATIC_CHECK_RETURN(res2.out == Iter(ia + n));
STATIC_CHECK_RETURN(res2.fun.i_ == 9);
const auto res3 = ranges::generate(std::move(rng), res2.fun);
STATIC_CHECK_RETURN(ia[0] == 9);
STATIC_CHECK_RETURN(ia[1] == 10);
STATIC_CHECK_RETURN(ia[2] == 11);
STATIC_CHECK_RETURN(ia[3] == 12);
STATIC_CHECK_RETURN(res3.out == Iter(ia + n));
STATIC_CHECK_RETURN(res3.fun.i_ == 13);
return true;
}
int main()
{
test<ForwardIterator<int*> >();
test<BidirectionalIterator<int*> >();
test<RandomAccessIterator<int*> >();
test<int*>();
test<ForwardIterator<int*>, Sentinel<int*> >();
test<BidirectionalIterator<int*>, Sentinel<int*> >();
test<RandomAccessIterator<int*>, Sentinel<int*> >();
test2();
STATIC_CHECK(test_constexpr<ForwardIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<int *>());
STATIC_CHECK(test_constexpr<ForwardIterator<int *>, Sentinel<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<int *>, Sentinel<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<int *>, Sentinel<int *>>());
return ::test_result();
}

View File

@@ -0,0 +1,131 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/generate_n.hpp>
#include <range/v3/iterator/insert_iterators.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
struct gen_test
{
int i_;
constexpr gen_test()
: i_{}
{}
constexpr gen_test(int i)
: i_(i)
{}
constexpr int operator()()
{
return i_++;
}
};
template<class Iter, class Sent = Iter>
void
test()
{
const unsigned n = 4;
int ia[n] = {0};
ranges::generate_n_result<Iter, gen_test> res = ranges::generate_n(Iter(ia), n, gen_test(1));
CHECK(ia[0] == 1);
CHECK(ia[1] == 2);
CHECK(ia[2] == 3);
CHECK(ia[3] == 4);
CHECK(res.out == Iter(ia + n));
CHECK(res.fun.i_ == 5);
}
void test2()
{
// Test ranges::generate with a genuine output range
std::vector<int> v;
ranges::generate_n(ranges::back_inserter(v), 5, gen_test(1));
CHECK(v.size() == 5u);
CHECK(v[0] == 1);
CHECK(v[1] == 2);
CHECK(v[2] == 3);
CHECK(v[3] == 4);
CHECK(v[4] == 5);
}
template<class Iter, class Sent = Iter>
constexpr bool test_constexpr()
{
bool r = true;
const unsigned n = 4;
int ia[n] = {0};
const auto res = ranges::generate_n(Iter(ia), n, gen_test(1));
if(ia[0] != 1)
{
r = false;
}
if(ia[1] != 2)
{
r = false;
}
if(ia[2] != 3)
{
r = false;
}
if(ia[3] != 4)
{
r = false;
}
if(res.out != Iter(ia + n))
{
r = false;
}
if(res.fun.i_ != 5)
{
r = false;
}
return r;
}
int main()
{
test<ForwardIterator<int*> >();
test<BidirectionalIterator<int*> >();
test<RandomAccessIterator<int*> >();
test<int*>();
test<ForwardIterator<int*>, Sentinel<int*> >();
test<BidirectionalIterator<int*>, Sentinel<int*> >();
test<RandomAccessIterator<int*>, Sentinel<int*> >();
test2();
{
STATIC_CHECK(test_constexpr<ForwardIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<int *>());
STATIC_CHECK(test_constexpr<ForwardIterator<int *>, Sentinel<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<int *>, Sentinel<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<int *>, Sentinel<int *>>());
}
return ::test_result();
}

View File

@@ -0,0 +1,159 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <functional>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/set_algorithm.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
auto const true_ = [](bool b){CHECK(b);};
auto const false_ = [](bool b){CHECK(!b);};
template<class Iter1, class Iter2>
void
test_iter()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int ic[] = {1, 2};
int id[] = {3, 3, 3, 3};
auto includes = make_testable_2<true, true>(ranges::includes);
includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib)).check(true_);
includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib+1)).check(false_);
includes(Iter1(ia), Iter1(ia+1), Iter2(ib), Iter2(ib)).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa)).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb)).check(true_);
includes(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa)).check(false_);
includes(Iter1(ia), Iter1(ia+2), Iter2(ic), Iter2(ic+2)).check(true_);
includes(Iter1(ia), Iter1(ia+2), Iter2(ib), Iter2(ib+2)).check(false_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+1)).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+2)).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+3)).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+4)).check(false_);
}
template<class Iter1, class Iter2>
void
test_comp()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int ic[] = {1, 2};
int id[] = {3, 3, 3, 3};
auto includes = make_testable_2<true, true>(ranges::includes);
includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib+1), std::less<int>()).check(false_);
includes(Iter1(ia), Iter1(ia+1), Iter2(ib), Iter2(ib), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), std::less<int>()).check(true_);
includes(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), std::less<int>()).check(false_);
includes(Iter1(ia), Iter1(ia+2), Iter2(ic), Iter2(ic+2), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia+2), Iter2(ib), Iter2(ib+2), std::less<int>()).check(false_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+1), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+2), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+3), std::less<int>()).check(true_);
includes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+4), std::less<int>()).check(false_);
}
template<class Iter1, class Iter2>
void test()
{
test_iter<Iter1, Iter2>();
test_comp<Iter1, Iter2>();
}
struct S
{
int i;
};
struct T
{
int j;
};
}
int main()
{
test<InputIterator<const int*>, InputIterator<const int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*> >();
test<InputIterator<const int*>, const int*>();
test<ForwardIterator<const int*>, InputIterator<const int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
test<ForwardIterator<const int*>, const int*>();
test<BidirectionalIterator<const int*>, InputIterator<const int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
test<BidirectionalIterator<const int*>, const int*>();
test<RandomAccessIterator<const int*>, InputIterator<const int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
test<RandomAccessIterator<const int*>, const int*>();
test<const int*, InputIterator<const int*> >();
test<const int*, ForwardIterator<const int*> >();
test<const int*, BidirectionalIterator<const int*> >();
test<const int*, RandomAccessIterator<const int*> >();
test<const int*, const int*>();
// Test projections
{
S ia[] = {{1}, {2}, {2}, {3}, {3}, {3}, {4}, {4}, {4}, {4}};
T id[] = {{3}, {3}, {3}};
CHECK(ranges::includes(ia, id, std::less<int>(), &S::i, &T::j));
}
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ranges::includes(
IL{1, 2, 2, 3, 3, 3, 4, 4, 4, 4}, IL{3, 3, 3}, std::less<int>()));
}
return ::test_result();
}

View File

@@ -0,0 +1,142 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <random>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/inplace_merge.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
template<class Iter, typename Sent = Iter>
void
test_one_iter(unsigned N, unsigned M)
{
RANGES_ENSURE(M <= N);
int* ia = new int[N];
for (unsigned i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::sort(ia, ia+M);
std::sort(ia+M, ia+N);
auto res = ranges::inplace_merge(Iter(ia), Iter(ia+M), Sent(ia+N));
CHECK(res == Iter(ia+N));
if(N > 0)
{
CHECK(ia[0] == 0);
CHECK(ia[N-1] == (int)N-1);
CHECK(std::is_sorted(ia, ia+N));
}
delete [] ia;
}
template<class Iter, typename Sent = Iter>
void
test_one_rng(unsigned N, unsigned M)
{
RANGES_ENSURE(M <= N);
int* ia = new int[N];
for (unsigned i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::sort(ia, ia+M);
std::sort(ia+M, ia+N);
auto res = ranges::inplace_merge(ranges::make_subrange(Iter(ia), Sent(ia+N)), Iter(ia+M));
CHECK(res == Iter(ia+N));
if(N > 0)
{
CHECK(ia[0] == 0);
CHECK(ia[N-1] == (int)N-1);
CHECK(std::is_sorted(ia, ia+N));
}
std::shuffle(ia, ia+N, gen);
std::sort(ia, ia+M);
std::sort(ia+M, ia+N);
auto res2 = ranges::inplace_merge(::MakeTestRange(Iter(ia), Sent(ia+N)), Iter(ia+M));
CHECK(::is_dangling(res2));
if(N > 0)
{
CHECK(ia[0] == 0);
CHECK(ia[N-1] == (int)N-1);
CHECK(std::is_sorted(ia, ia+N));
}
delete [] ia;
}
template<class Iter>
void
test_one(unsigned N, unsigned M)
{
test_one_iter<Iter>(N, M);
test_one_iter<Iter, typename sentinel_type<Iter>::type>(N, M);
test_one_rng<Iter>(N, M);
test_one_rng<Iter, typename sentinel_type<Iter>::type>(N, M);
}
template<class Iter>
void
test(unsigned N)
{
test_one<Iter>(N, 0);
test_one<Iter>(N, N/4);
test_one<Iter>(N, N/2);
test_one<Iter>(N, 3*N/4);
test_one<Iter>(N, N);
}
template<class Iter>
void
test()
{
test_one<Iter>(0, 0);
test_one<Iter>(1, 0);
test_one<Iter>(1, 1);
test_one<Iter>(2, 0);
test_one<Iter>(2, 1);
test_one<Iter>(2, 2);
test_one<Iter>(3, 0);
test_one<Iter>(3, 1);
test_one<Iter>(3, 2);
test_one<Iter>(3, 3);
test<Iter>(4);
test<Iter>(100);
test<Iter>(1000);
}
}
int main()
{
// test<ForwardIterator<int*> >();
test<BidirectionalIterator<int*> >();
test<RandomAccessIterator<int*> >();
test<int*>();
return ::test_result();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_1
#include "./is_heap.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_2
#include "./is_heap.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_3
#include "./is_heap.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_4
#include "./is_heap.hpp"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_UNTIL_1
#include "./is_heap_until.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_UNTIL_2
#include "./is_heap_until.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_UNTIL_3
#include "./is_heap_until.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define IS_HEAP_UNTIL_4
#include "./is_heap_until.hpp"

View File

@@ -0,0 +1,137 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/is_partitioned.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
struct is_odd
{
constexpr bool operator()(const int & i) const
{
return i & 1;
}
};
template<class Iter, class Sent = Iter>
void
test_iter()
{
{
const int ia[] = {1, 2, 3, 4, 5, 6};
CHECK(!ranges::is_partitioned(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6};
CHECK( ranges::is_partitioned(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()));
}
{
const int ia[] = {2, 4, 6, 1, 3, 5};
CHECK(!ranges::is_partitioned(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK(!ranges::is_partitioned(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK( ranges::is_partitioned(Iter(ranges::begin(ia)),
Sent(ranges::begin(ia)),
is_odd()));
}
}
template<class Iter, class Sent = Iter>
void
test_range()
{
{
const int ia[] = {1, 2, 3, 4, 5, 6};
CHECK(!ranges::is_partitioned(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia))),
is_odd()));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6};
CHECK( ranges::is_partitioned(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia))),
is_odd()));
}
{
const int ia[] = {2, 4, 6, 1, 3, 5};
CHECK(!ranges::is_partitioned(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia))),
is_odd()));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK(!ranges::is_partitioned(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia))),
is_odd()));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK( ranges::is_partitioned(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::begin(ia))),
is_odd()));
}
}
struct S
{
int i;
};
int main()
{
test_iter<InputIterator<const int*> >();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_range<InputIterator<const int*> >();
test_range<InputIterator<const int*>, Sentinel<const int*>>();
// Test projections
const S ia[] = {S{1}, S{3}, S{5}, S{2}, S{4}, S{6}};
CHECK( ranges::is_partitioned(ia, is_odd(), &S::i) );
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ranges::is_partitioned(IL{1, 3, 5, 2, 4, 6}, is_odd()));
STATIC_CHECK(!ranges::is_partitioned(IL{1, 3, 1, 2, 5, 6}, is_odd()));
}
return ::test_result();
}

View File

@@ -0,0 +1,854 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/permutation.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
int comparison_count = 0;
template<typename T>
bool counting_equals( T const &a, T const &b )
{
++comparison_count;
return a == b;
}
struct S
{
int i;
};
struct T
{
int i;
};
int main()
{
{
const int ia[] = {0};
const int ib[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + 0),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0};
const int ib[] = {1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0};
const int ib[] = {0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0};
const int ib[] = {0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0};
const int ib[] = {1, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0};
const int ib[] = {1, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1};
const int ib[] = {0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1};
const int ib[] = {0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1};
const int ib[] = {1, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1};
const int ib[] = {1, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 0};
const int ib[] = {0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 0};
const int ib[] = {0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 0};
const int ib[] = {1, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 0};
const int ib[] = {1, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 1};
const int ib[] = {0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 1};
const int ib[] = {0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 1};
const int ib[] = {1, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {1, 1};
const int ib[] = {1, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 0, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 1, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 1, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 1, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 2, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 2, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 0};
const int ib[] = {1, 2, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 1};
const int ib[] = {1, 0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 1};
const int ib[] = {1, 0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1, 2};
const int ib[] = {1, 0, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1, 2};
const int ib[] = {1, 2, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1, 2};
const int ib[] = {2, 1, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1, 2};
const int ib[] = {2, 0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 1};
const int ib[] = {1, 0, 1};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 0, 1};
const int ib[] = {1, 0, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib + 1),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
}
{
const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
const int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib + 1),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
std::equal_to<const int>()) == false);
comparison_count = 0;
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1),
counting_equals<const int>) == false);
CHECK( comparison_count > 0 );
comparison_count = 0;
CHECK(ranges::is_permutation(RandomAccessIterator<const int*>(ia),
RandomAccessIterator<const int*>(ia + sa),
RandomAccessIterator<const int*>(ib),
RandomAccessIterator<const int*>(ib + sa - 1),
counting_equals<const int>) == false);
CHECK ( comparison_count == 0 );
}
{
const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
const int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
std::equal_to<const int>()) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa),
std::equal_to<const int>()) == false);
}
// Iterator tests, without predicate:
{
const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
const int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib)) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa)) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib + 1),
ForwardIterator<const int*>(ib + sa)) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
ForwardIterator<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
ForwardIterator<const int*>(ib + sa - 1)) == false);
}
// Iterator tests, with sentinels:
{
const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
const int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ib)) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sa)) == true);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ib + 1),
Sentinel<const int*>(ib + sa)) == false);
CHECK(ranges::is_permutation(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa),
ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sa - 1)) == false);
}
// common_range tests, with sentinels:
{
const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
const int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ForwardIterator<const int*>(ib)) == true);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sa))) == true);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const int*>(ib + 1),
Sentinel<const int*>(ib + sa))) == false);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sa - 1))) == false);
}
// common_range tests, with sentinels, with predicate:
{
const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
const int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 2};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ForwardIterator<const int*>(ib),
std::equal_to<int const>()) == true);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sa)),
std::equal_to<int const>()) == true);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const int*>(ib + 1),
Sentinel<const int*>(ib + sa)),
std::equal_to<int const>()) == false);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const int*>(ia),
Sentinel<const int*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const int*>(ib),
Sentinel<const int*>(ib + sa - 1)),
std::equal_to<int const>()) == false);
}
// common_range tests, with sentinels, with predicate and projections:
{
const S ia[] = {{0}, {1}, {2}, {3}, {0}, {5}, {6}, {2}, {4}, {4}};
const T ib[] = {{4}, {2}, {3}, {0}, {1}, {4}, {0}, {5}, {6}, {2}};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ia, &ib[0], std::equal_to<int const>(), &S::i, &T::i) == true);
CHECK(ranges::is_permutation(ia, ib, std::equal_to<int const>(), &S::i, &T::i) == true);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const S*>(ia),
Sentinel<const S*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const T*>(ib + 1),
Sentinel<const T*>(ib + sa)),
std::equal_to<int const>(), &S::i, &T::i) == false);
CHECK(ranges::is_permutation(ranges::make_subrange(ForwardIterator<const S*>(ia),
Sentinel<const S*>(ia + sa)),
ranges::make_subrange(ForwardIterator<const T*>(ib),
Sentinel<const T*>(ib + sa - 1)),
std::equal_to<int const>(), &S::i, &T::i) == false);
}
// Iterator tests, with sentinels, with predicate and projections:
{
const S ia[] = {{0}, {1}, {2}, {3}, {0}, {5}, {6}, {2}, {4}, {4}};
const T ib[] = {{4}, {2}, {3}, {0}, {1}, {4}, {0}, {5}, {6}, {2}};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::is_permutation(ForwardIterator<const S*>(ia),
Sentinel<const S*>(ia + sa),
ForwardIterator<const T*>(ib),
std::equal_to<int const>(), &S::i, &T::i) == true);
CHECK(ranges::is_permutation(ForwardIterator<const S*>(ia),
Sentinel<const S*>(ia + sa),
ForwardIterator<const T*>(ib),
Sentinel<const T*>(ib + sa),
std::equal_to<int const>(), &S::i, &T::i) == true);
CHECK(ranges::is_permutation(ForwardIterator<const S*>(ia),
Sentinel<const S*>(ia + sa),
ForwardIterator<const T*>(ib + 1),
Sentinel<const T*>(ib + sa),
std::equal_to<int const>(), &S::i, &T::i) == false);
CHECK(ranges::is_permutation(ForwardIterator<const S*>(ia),
Sentinel<const S*>(ia + sa),
ForwardIterator<const T*>(ib),
Sentinel<const T*>(ib + sa - 1),
std::equal_to<int const>(), &S::i, &T::i) == false);
}
return ::test_result();
}

View File

@@ -0,0 +1,417 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Gonzalo Brito Gadeschi 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Implementation based on the code in libc++
// http://http://libcxx.llvm.org/
#include <range/v3/core.hpp>
#include <range/v3/algorithm/is_sorted.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
/// Calls the iterator interface of the algorithm
template<class Iter>
struct iter_call
{
using begin_t = Iter;
using sentinel_t = typename sentinel_type<Iter>::type;
template<class B, class E, class... Args>
auto operator()(B &&b, E &&e, Args &&... args)
-> decltype(ranges::is_sorted(begin_t{b}, sentinel_t{e},
std::forward<Args>(args)...))
{
return ranges::is_sorted(begin_t{b}, sentinel_t{e}, std::forward<Args>(args)...);
}
};
/// Calls the range interface of the algorithm
template<class Iter>
struct range_call
{
using begin_t = Iter;
using sentinel_t = typename sentinel_type<Iter>::type;
template<class B, class E>
auto operator()(B && b, E && e)
-> decltype(ranges::is_sorted(ranges::make_subrange(begin_t{b}, sentinel_t{e})))
{
return ranges::is_sorted(ranges::make_subrange(begin_t{b}, sentinel_t{e}));
}
template<class B, class E, class A0>
auto operator()(B && b, E && e, A0 && a0)
-> decltype(ranges::is_sorted(ranges::make_subrange(begin_t{b}, sentinel_t{e}),
static_cast<A0 &&>(a0)))
{
return ranges::is_sorted(ranges::make_subrange(begin_t{b}, sentinel_t{e}),
static_cast<A0 &&>(a0));
}
template<class B, class E, class A0, class A1>
auto operator()(B && b, E && e, A0 && a0, A1 && a1)
-> decltype(ranges::is_sorted(ranges::make_subrange(begin_t{b}, sentinel_t{e}),
static_cast<A0 &&>(a0), static_cast<A1 &&>(a1)))
{
return ranges::is_sorted(ranges::make_subrange(begin_t{b}, sentinel_t{e}),
static_cast<A0 &&>(a0),
static_cast<A1 &&>(a1));
}
};
template<class Fun>
void test()
{
{
int a[] = {0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a));
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {0, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {0, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {0, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {0, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {1, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa));
}
{
int a[] = {1, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa));
}
{
int a[] = {0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a));
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {0, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(!Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
{
int a[] = {1, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()));
}
}
struct A { int a; };
int main()
{
test<iter_call<ForwardIterator<const int *>>>();
test<iter_call<BidirectionalIterator<const int *>>>();
test<iter_call<RandomAccessIterator<const int *>>>();
test<iter_call<const int *>>();
test<range_call<ForwardIterator<const int *>>>();
test<range_call<BidirectionalIterator<const int *>>>();
test<range_call<RandomAccessIterator<const int *>>>();
test<range_call<const int *>>();
/// Projection test:
{
A as[] = {{0}, {1}, {2}, {3}, {4}};
CHECK(ranges::is_sorted(as, std::less<int>{}, &A::a));
CHECK(!ranges::is_sorted(as, std::greater<int>{}, &A::a));
}
{
using IL = std::initializer_list<int>;
STATIC_CHECK(ranges::is_sorted(IL{0, 1, 2, 3}));
STATIC_CHECK(ranges::is_sorted(IL{0, 1, 2, 3}, std::less<>{}));
STATIC_CHECK(!ranges::is_sorted(IL{3, 2, 1, 0}));
STATIC_CHECK(ranges::is_sorted(IL{3, 2, 1, 0}, std::greater<>{}));
}
return ::test_result();
}

View File

@@ -0,0 +1,469 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Gonzalo Brito Gadeschi 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Implementation based on the code in libc++
// http://http://libcxx.llvm.org/
#include <vector>
#include <range/v3/algorithm/is_sorted_until.hpp>
#include <range/v3/core.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#include "../test_utils.hpp"
/// Calls the iterator interface of the algorithm
template<class Iter>
struct iter_call
{
using begin_t = Iter;
using sentinel_t = typename sentinel_type<Iter>::type;
template<class B, class E, class... Args>
auto operator()(B && It, E && e, Args &&... args)
-> decltype(ranges::is_sorted_until(begin_t{It}, sentinel_t{e},
std::forward<Args>(args)...))
{
return ranges::is_sorted_until(
begin_t{It}, sentinel_t{e}, std::forward<Args>(args)...);
}
};
/// Calls the range interface of the algorithm
template<class Iter>
struct range_call
{
using begin_t = Iter;
using sentinel_t = typename sentinel_type<Iter>::type;
template<class B, class E, class... Args>
static auto _impl(B && It, E && e, Args &&... args)
-> decltype(ranges::is_sorted_until(
::as_lvalue(ranges::make_subrange(begin_t{It}, sentinel_t{e})),
std::forward<Args>(args)...))
{
return ranges::is_sorted_until(
::as_lvalue(ranges::make_subrange(begin_t{It}, sentinel_t{e})),
std::forward<Args>(args)...);
}
template<class B, class E>
auto operator()(B && It, E && e) const -> decltype(ranges::is_sorted_until(
::as_lvalue(ranges::make_subrange(begin_t{It}, sentinel_t{e}))))
{
return range_call::_impl(static_cast<B &&>(It), static_cast<E &&>(e));
}
template<class B, class E, class A0>
auto operator()(B && It, E && e, A0 && a0) const
-> decltype(ranges::is_sorted_until(::as_lvalue(
ranges::make_subrange(begin_t{It}, sentinel_t{e})), static_cast<A0 &&>(a0)))
{
return range_call::_impl(
static_cast<B &&>(It), static_cast<E &&>(e), static_cast<A0 &&>(a0));
}
template<class B, class E, class A0, class A1>
auto operator()(B && It, E && e, A0 && a0, A1 && a1) const
-> decltype(ranges::is_sorted_until(::as_lvalue(ranges::make_subrange(
begin_t{It}, sentinel_t{e})), static_cast<A0 &&>(a0), static_cast<A1 &&>(a1)))
{
return range_call::_impl(
static_cast<B &&>(It), static_cast<E &&>(e), static_cast<A0 &&>(a0), static_cast<A1 &&>(a1));
}
};
template<class It, template<class> class FunT>
void test_basic()
{
using Fun = FunT<It>;
{
int a[] = {0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a) == It(a));
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 2));
}
{
int a[] = {0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 2));
}
{
int a[] = {1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 3));
}
{
int a[] = {0, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 2));
}
{
int a[] = {0, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 2));
}
{
int a[] = {0, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 3));
}
{
int a[] = {0, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {1, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 1));
}
{
int a[] = {1, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 2));
}
{
int a[] = {1, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 2));
}
{
int a[] = {1, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + 3));
}
{
int a[] = {1, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa) == It(a + sa));
}
{
int a[] = {0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a, std::greater<int>()) == It(a));
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));
}
{
int a[] = {0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));
}
{
int a[] = {1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {0, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {0, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 3));
}
{
int a[] = {0, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));
}
{
int a[] = {0, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));
}
{
int a[] = {0, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {0, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {0, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {0, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));
}
{
int a[] = {1, 0, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {1, 0, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 3));
}
{
int a[] = {1, 0, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));
}
{
int a[] = {1, 0, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));
}
{
int a[] = {1, 1, 0, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {1, 1, 0, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 3));
}
{
int a[] = {1, 1, 1, 0};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
{
int a[] = {1, 1, 1, 1};
unsigned sa = sizeof(a) / sizeof(a[0]);
CHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));
}
}
struct A
{
int a;
};
constexpr bool test_constexpr()
{
test::array<int, 4> a{{1, 2, 3, 4}};
auto b = ranges::begin(a);
auto b1 = ++b;
auto end = ranges::end(a);
STATIC_CHECK_RETURN(ranges::is_sorted_until(a) == end);
STATIC_CHECK_RETURN(ranges::is_sorted_until(a, std::less<>{}) == end);
STATIC_CHECK_RETURN(ranges::is_sorted_until(a, std::greater<>{}) == b1);
return true;
}
int main()
{
test_basic<ForwardIterator<const int *>, iter_call>();
test_basic<BidirectionalIterator<const int *>, iter_call>();
test_basic<RandomAccessIterator<const int *>, iter_call>();
test_basic<const int *, iter_call>();
test_basic<ForwardIterator<const int *>, range_call>();
test_basic<BidirectionalIterator<const int *>, range_call>();
test_basic<RandomAccessIterator<const int *>, range_call>();
test_basic<const int *, range_call>();
/// Initializer list test:
{
std::initializer_list<int> r = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
CHECK(ranges::is_sorted_until(r) == ranges::end(r));
}
/// Projection test:
{
A as[] = {{0}, {1}, {2}, {3}, {4}};
CHECK(ranges::is_sorted_until(as, std::less<int>{}, &A::a) == ranges::end(as));
CHECK(ranges::is_sorted_until(as, std::greater<int>{}, &A::a) ==
ranges::next(ranges::begin(as), 1));
}
/// Rvalue range test:
{
A as[] = {{0}, {1}, {2}, {3}, {4}};
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(
ranges::is_sorted_until(std::move(as), std::less<int>{}, &A::a)));
CHECK(::is_dangling(
ranges::is_sorted_until(std::move(as), std::greater<int>{}, &A::a)));
#endif // RANGES_WORKAROUND_MSVC_573728
std::vector<A> vec(ranges::begin(as), ranges::end(as));
CHECK(::is_dangling(
ranges::is_sorted_until(std::move(vec), std::less<int>{}, &A::a)));
CHECK(::is_dangling(
ranges::is_sorted_until(std::move(vec), std::greater<int>{}, &A::a)));
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,208 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/core.hpp>
#include <range/v3/algorithm/lexicographical_compare.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter1, class Iter2, class Sent1 = Iter1, class Sent2 = Iter2>
void
test_iter1()
{
int ia[] = {1, 2, 3, 4};
constexpr auto sa = ranges::size(ia);
int ib[] = {1, 2, 3};
CHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+2)));
CHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+2), Iter2(ia), Sent2(ia+sa)));
CHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+3)));
CHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+3), Iter2(ia), Sent2(ia+sa)));
CHECK(ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib+1), Sent2(ib+3)));
CHECK(!ranges::lexicographical_compare(Iter1(ib+1), Sent1(ib+3), Iter2(ia), Sent2(ia+sa)));
}
void test_iter()
{
typedef Sentinel<const int*> S;
test_iter1<InputIterator<const int*>, InputIterator<const int*> >();
test_iter1<InputIterator<const int*>, ForwardIterator<const int*> >();
test_iter1<InputIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter1<InputIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter1<InputIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter1<InputIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter1<InputIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter1<InputIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter1<InputIterator<const int*>, const int*>();
test_iter1<ForwardIterator<const int*>, InputIterator<const int*> >();
test_iter1<ForwardIterator<const int*>, ForwardIterator<const int*> >();
test_iter1<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter1<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter1<ForwardIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter1<ForwardIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter1<ForwardIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter1<ForwardIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter1<ForwardIterator<const int*>, const int*>();
test_iter1<BidirectionalIterator<const int*>, InputIterator<const int*> >();
test_iter1<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
test_iter1<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter1<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter1<BidirectionalIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter1<BidirectionalIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter1<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter1<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter1<BidirectionalIterator<const int*>, const int*>();
test_iter1<RandomAccessIterator<const int*>, InputIterator<const int*> >();
test_iter1<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
test_iter1<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter1<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter1<RandomAccessIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter1<RandomAccessIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter1<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter1<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter1<RandomAccessIterator<const int*>, const int*>();
test_iter1<const int*, InputIterator<const int*> >();
test_iter1<const int*, ForwardIterator<const int*> >();
test_iter1<const int*, BidirectionalIterator<const int*> >();
test_iter1<const int*, RandomAccessIterator<const int*> >();
test_iter1<const int*, InputIterator<const int*>, const int*, S>();
test_iter1<const int*, ForwardIterator<const int*>, const int*, S>();
test_iter1<const int*, BidirectionalIterator<const int*>, const int*, S>();
test_iter1<const int*, RandomAccessIterator<const int*>, const int*, S>();
test_iter1<const int*, const int*>();
}
template<class Iter1, class Iter2, class Sent1 = Iter1, class Sent2 = Iter2>
void
test_iter_comp1()
{
int ia[] = {1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {1, 2, 3};
typedef std::greater<int> C;
C c;
CHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+2), c));
CHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+2), Iter2(ia), Sent2(ia+sa), c));
CHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+3), c));
CHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+3), Iter2(ia), Sent2(ia+sa), c));
CHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib+1), Sent2(ib+3), c));
CHECK(ranges::lexicographical_compare(Iter1(ib+1), Sent1(ib+3), Iter2(ia), Sent2(ia+sa), c));
}
void test_iter_comp()
{
typedef Sentinel<const int*> S;
test_iter_comp1<InputIterator<const int*>, InputIterator<const int*> >();
test_iter_comp1<InputIterator<const int*>, ForwardIterator<const int*> >();
test_iter_comp1<InputIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter_comp1<InputIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter_comp1<InputIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter_comp1<InputIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter_comp1<InputIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter_comp1<InputIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter_comp1<InputIterator<const int*>, const int*>();
test_iter_comp1<ForwardIterator<const int*>, InputIterator<const int*> >();
test_iter_comp1<ForwardIterator<const int*>, ForwardIterator<const int*> >();
test_iter_comp1<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter_comp1<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter_comp1<ForwardIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter_comp1<ForwardIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter_comp1<ForwardIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter_comp1<ForwardIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter_comp1<ForwardIterator<const int*>, const int*>();
test_iter_comp1<BidirectionalIterator<const int*>, InputIterator<const int*> >();
test_iter_comp1<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
test_iter_comp1<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter_comp1<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter_comp1<BidirectionalIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter_comp1<BidirectionalIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter_comp1<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter_comp1<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter_comp1<BidirectionalIterator<const int*>, const int*>();
test_iter_comp1<RandomAccessIterator<const int*>, InputIterator<const int*> >();
test_iter_comp1<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
test_iter_comp1<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
test_iter_comp1<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
test_iter_comp1<RandomAccessIterator<const int*>, InputIterator<const int*>, S, S>();
test_iter_comp1<RandomAccessIterator<const int*>, ForwardIterator<const int*>, S, S>();
test_iter_comp1<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, S, S>();
test_iter_comp1<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, S, S>();
test_iter_comp1<RandomAccessIterator<const int*>, const int*>();
test_iter_comp1<const int*, InputIterator<const int*> >();
test_iter_comp1<const int*, ForwardIterator<const int*> >();
test_iter_comp1<const int*, BidirectionalIterator<const int*> >();
test_iter_comp1<const int*, RandomAccessIterator<const int*> >();
test_iter_comp1<const int*, InputIterator<const int*>, const int*, S>();
test_iter_comp1<const int*, ForwardIterator<const int*>, const int*, S>();
test_iter_comp1<const int*, BidirectionalIterator<const int*>, const int*, S>();
test_iter_comp1<const int*, RandomAccessIterator<const int*>, const int*, S>();
test_iter_comp1<const int*, const int*>();
}
constexpr bool test_constexpr()
{
test::array<int, 4> ia{{1, 2, 3, 4}};
test::array<int, 3> ib{{1, 2, 3}};
auto ia_b = ranges::begin(ia);
auto ia_e = ranges::end(ia);
auto ib_b = ranges::begin(ib);
auto ib_1 = ib_b + 1;
auto ib_2 = ib_b + 2;
auto ib_3 = ib_b + 3;
STATIC_CHECK_RETURN(!ranges::lexicographical_compare(ia_b, ia_e, ib_b, ib_2));
STATIC_CHECK_RETURN(ranges::lexicographical_compare(ib_b, ib_2, ia_b, ia_e));
STATIC_CHECK_RETURN(!ranges::lexicographical_compare(ia_b, ia_e, ib_b, ib_3));
STATIC_CHECK_RETURN(ranges::lexicographical_compare(ib_b, ib_3, ia_b, ia_e));
STATIC_CHECK_RETURN(ranges::lexicographical_compare(ia_b, ia_e, ib_1, ib_3));
STATIC_CHECK_RETURN(!ranges::lexicographical_compare(ib_1, ib_3, ia_b, ia_e));
typedef std::greater<int> C;
C c{};
STATIC_CHECK_RETURN(!ranges::lexicographical_compare(ia_b, ia_e, ib_b, ib_2, c));
STATIC_CHECK_RETURN(ranges::lexicographical_compare(ib_b, ib_2, ia_b, ia_e, c));
STATIC_CHECK_RETURN(!ranges::lexicographical_compare(ia_b, ia_e, ib_b, ib_3, c));
STATIC_CHECK_RETURN(ranges::lexicographical_compare(ib_b, ib_3, ia_b, ia_e, c));
STATIC_CHECK_RETURN(!ranges::lexicographical_compare(ia_b, ia_e, ib_1, ib_3, c));
STATIC_CHECK_RETURN(ranges::lexicographical_compare(ib_1, ib_3, ia_b, ia_e, c));
return true;
}
int main()
{
test_iter();
test_iter_comp();
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,102 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/lower_bound.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#include "../test_utils.hpp"
struct my_int
{
int value;
};
bool compare(my_int lhs, my_int rhs)
{
return lhs.value < rhs.value;
}
void not_totally_ordered()
{
// This better compile!
std::vector<my_int> vec;
ranges::lower_bound(vec, my_int{10}, compare);
}
int main()
{
using ranges::begin;
using ranges::end;
using ranges::size;
using ranges::less;
constexpr std::pair<int, int> a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};
constexpr const std::pair<int, int> c[] = {
{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};
CHECK(ranges::aux::lower_bound_n(begin(a), size(a), a[0]) == &a[0]);
CHECK(ranges::aux::lower_bound_n(begin(a), size(a), a[1], less()) == &a[1]);
CHECK(ranges::aux::lower_bound_n(begin(a), size(a), 1, less(), &std::pair<int, int>::first) == &a[2]);
CHECK(ranges::lower_bound(begin(a), end(a), a[0]) == &a[0]);
CHECK(ranges::lower_bound(begin(a), end(a), a[1], less()) == &a[1]);
CHECK(ranges::lower_bound(begin(a), end(a), 1, less(), &std::pair<int, int>::first) == &a[2]);
CHECK(ranges::lower_bound(a, a[2]) == &a[2]);
CHECK(ranges::lower_bound(c, c[3]) == &c[3]);
CHECK(ranges::lower_bound(a, a[4], less()) == &a[4]);
CHECK(ranges::lower_bound(c, c[5], less()) == &c[5]);
CHECK(ranges::lower_bound(a, 1, less(), &std::pair<int, int>::first) == &a[2]);
CHECK(ranges::lower_bound(c, 1, less(), &std::pair<int, int>::first) == &c[2]);
CHECK(ranges::lower_bound(ranges::views::all(a), 1, less(), &std::pair<int, int>::first) == &a[2]);
CHECK(ranges::lower_bound(ranges::views::all(c), 1, less(), &std::pair<int, int>::first) == &c[2]);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(ranges::lower_bound(std::move(a), 1, less(), &std::pair<int, int>::first)));
CHECK(::is_dangling(ranges::lower_bound(std::move(c), 1, less(), &std::pair<int, int>::first)));
#endif // RANGES_WORKAROUND_MSVC_573728
{
std::vector<std::pair<int, int>> vec_a(ranges::begin(a), ranges::end(a));
CHECK(::is_dangling(ranges::lower_bound(std::move(vec_a), 1, less(), &std::pair<int, int>::first)));
}
{
std::vector<std::pair<int, int>> const vec_c(ranges::begin(c), ranges::end(c));
CHECK(::is_dangling(ranges::lower_bound(std::move(vec_c), 1, less(), &std::pair<int, int>::first)));
}
{
using namespace ranges;
STATIC_CHECK(aux::lower_bound_n(begin(a), size(a), a[0]) == &a[0]);
STATIC_CHECK(aux::lower_bound_n(begin(a), size(a), a[1], less()) == &a[1]);
STATIC_CHECK(lower_bound(begin(a), end(a), a[0]) == &a[0]);
STATIC_CHECK(lower_bound(begin(a), end(a), a[1], less()) == &a[1]);
STATIC_CHECK(lower_bound(a, a[2]) == &a[2]);
STATIC_CHECK(lower_bound(a, a[4], less()) == &a[4]);
STATIC_CHECK(lower_bound(a, std::make_pair(1, 2), less()) == &a[2]);
#if RANGES_CXX_CONSTEXPR >= RANGES_CXX_CONSTEXPR_17
// requires constexpr std::addressof
STATIC_CHECK(lower_bound(views::all(a), std::make_pair(1, 2), less()) == &a[2]);
#endif
}
return test_result();
}

View File

@@ -0,0 +1,230 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <random>
#include <algorithm>
#include <functional>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/heap_algorithm.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
void test_1(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ia, ia+N) == ia+N);
CHECK(std::is_heap(ia, ia+N));
delete [] ia;
}
void test_2(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ia, Sentinel<int*>(ia+N)) == ia+N);
CHECK(std::is_heap(ia, ia+N));
delete [] ia;
}
void test_3(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ranges::make_subrange(ia, ia+N)) == ia+N);
CHECK(std::is_heap(ia, ia+N));
std::shuffle(ia, ia+N, gen);
CHECK(::is_dangling(ranges::make_heap(::MakeTestRange(ia, ia+N))));
CHECK(std::is_heap(ia, ia+N));
delete [] ia;
}
void test_4(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ranges::make_subrange(ia, Sentinel<int*>(ia+N))) == ia+N);
CHECK(std::is_heap(ia, ia+N));
std::shuffle(ia, ia+N, gen);
CHECK(::is_dangling(ranges::make_heap(::MakeTestRange(ia, Sentinel<int*>(ia+N)))));
CHECK(std::is_heap(ia, ia+N));
delete [] ia;
}
void test_5(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ia, ia+N, std::greater<int>()) == ia+N);
CHECK(std::is_heap(ia, ia+N, std::greater<int>()));
delete [] ia;
}
void test_6(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ia, Sentinel<int*>(ia+N), std::greater<int>()) == ia+N);
CHECK(std::is_heap(ia, ia+N, std::greater<int>()));
delete [] ia;
}
void test_7(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ranges::make_subrange(ia, ia+N), std::greater<int>()) == ia+N);
CHECK(std::is_heap(ia, ia+N, std::greater<int>()));
std::shuffle(ia, ia+N, gen);
CHECK(::is_dangling(ranges::make_heap(::MakeTestRange(ia, ia+N), std::greater<int>())));
CHECK(std::is_heap(ia, ia+N, std::greater<int>()));
delete [] ia;
}
void test_8(int N)
{
int* ia = new int [N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ranges::make_subrange(ia, Sentinel<int*>(ia+N)), std::greater<int>()) == ia+N);
CHECK(std::is_heap(ia, ia+N, std::greater<int>()));
std::shuffle(ia, ia+N, gen);
CHECK(::is_dangling(ranges::make_heap(::MakeTestRange(ia, Sentinel<int*>(ia+N)), std::greater<int>())));
CHECK(std::is_heap(ia, ia+N, std::greater<int>()));
delete [] ia;
}
struct indirect_less
{
template<class P>
bool operator()(const P& x, const P& y)
{return *x < *y;}
};
void test_9(int N)
{
std::unique_ptr<int>* ia = new std::unique_ptr<int> [N];
for (int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ia, ia+N, indirect_less()) == ia+N);
CHECK(std::is_heap(ia, ia+N, indirect_less()));
delete [] ia;
}
struct S
{
int i;
};
void test_10(int N)
{
int* ia = new int [N];
S* ib = new S [N];
for (int i = 0; i < N; ++i)
ib[i].i = i;
std::shuffle(ia, ia+N, gen);
CHECK(ranges::make_heap(ib, ib+N, std::less<int>(), &S::i) == ib+N);
std::transform(ib, ib+N, ia, std::mem_fn(&S::i));
CHECK(std::is_heap(ia, ia+N));
delete [] ia;
delete [] ib;
}
void test_all(int N)
{
test_1(N);
test_2(N);
test_3(N);
test_4(N);
test_5(N);
test_6(N);
test_7(N);
test_8(N);
}
constexpr bool test_constexpr()
{
using namespace ranges;
constexpr int N = 100;
test::array<int, N> ia{{0}};
for(int i = 0; i < N; ++i)
ia[i] = N - 1 - i;
STATIC_CHECK_RETURN(make_heap(begin(ia), end(ia), std::less<int>{}) == end(ia));
STATIC_CHECK_RETURN(is_heap(begin(ia), end(ia)));
return true;
}
}
int main()
{
test_all(0);
test_all(1);
test_all(2);
test_all(3);
test_all(10);
test_all(1000);
test_9(1000);
test_10(1000);
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,142 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Casey Carter 2015
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/algorithm/max.hpp>
#include <range/v3/view/subrange.hpp>
#include <memory>
#include <numeric>
#include <random>
#include <algorithm>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
std::mt19937 gen;
template<class Iter, class Sent = Iter>
void
test_iter(Iter first, Sent last)
{
RANGES_ENSURE(first != last);
auto rng = ranges::make_subrange(first, last);
auto v = ranges::max(rng);
for (Iter i = first; i != last; ++i)
CHECK(!(v < *i));
}
template<class Iter, class Sent = Iter>
void
test_iter(unsigned N)
{
RANGES_ENSURE(N > 0);
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter()
{
test_iter<Iter, Sent>(1);
test_iter<Iter, Sent>(2);
test_iter<Iter, Sent>(3);
test_iter<Iter, Sent>(10);
test_iter<Iter, Sent>(1000);
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(Iter first, Sent last)
{
RANGES_ENSURE(first != last);
auto rng = ranges::make_subrange(first, last);
auto comp = std::greater<int>();
auto v = ranges::max(rng, comp);
for (Iter i = first; i != last; ++i)
CHECK(!comp(v, *i));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(unsigned N)
{
RANGES_ENSURE(N > 0);
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter_comp(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp()
{
test_iter_comp<Iter, Sent>(1);
test_iter_comp<Iter, Sent>(2);
test_iter_comp<Iter, Sent>(3);
test_iter_comp<Iter, Sent>(10);
test_iter_comp<Iter, Sent>(1000);
}
struct S
{
int i;
};
}
int main()
{
test_iter<InputIterator<const int*> >();
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<InputIterator<const int*> >();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s[] = {S{1},S{2},S{3},S{4},S{40},S{5},S{6},S{7},S{8},S{9}};
S v = ranges::max(s, std::less<int>{}, &S::i);
CHECK(v.i == 40);
// Works with initializer_lists? (Regression test for #1004)
CHECK(ranges::max({4,3,1,2,6,5}) == 6);
return test_result();
}

View File

@@ -0,0 +1,172 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <numeric>
#include <random>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/max_element.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
std::mt19937 gen;
template<class Iter, class Sent = Iter>
void
test_iter(Iter first, Sent last)
{
Iter i = ranges::max_element(first, last);
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!(*i < *j));
}
else
CHECK(i == last);
auto rng = ::MakeTestRange(first, last);
i = ranges::max_element(rng);
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!(*i < *j));
}
else
CHECK(i == last);
auto j = ranges::max_element(std::move(rng));
CHECK(::is_dangling(j));
}
template<class Iter, class Sent = Iter>
void
test_iter(unsigned N)
{
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter()
{
test_iter<Iter, Sent>(0);
test_iter<Iter, Sent>(1);
test_iter<Iter, Sent>(2);
test_iter<Iter, Sent>(3);
test_iter<Iter, Sent>(10);
test_iter<Iter, Sent>(1000);
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(Iter first, Sent last)
{
Iter i = ranges::max_element(first, last, std::greater<int>());
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!std::greater<int>()(*i, *j));
}
else
CHECK(i == last);
auto rng = ::MakeTestRange(first, last);
i = ranges::max_element(rng, std::greater<int>());
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!std::greater<int>()(*i, *j));
}
else
CHECK(i == last);
auto res = ranges::max_element(std::move(rng), std::greater<int>());
CHECK(::is_dangling(res));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(unsigned N)
{
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter_comp(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp()
{
test_iter_comp<Iter, Sent>(0);
test_iter_comp<Iter, Sent>(1);
test_iter_comp<Iter, Sent>(2);
test_iter_comp<Iter, Sent>(3);
test_iter_comp<Iter, Sent>(10);
test_iter_comp<Iter, Sent>(1000);
}
struct S
{
int i;
};
}
int main()
{
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s[] = {S{1},S{2},S{3},S{4},S{40},S{5},S{6},S{7},S{8},S{9}};
S const *ps = ranges::max_element(s, std::less<int>{}, &S::i);
CHECK(ps->i == 40);
{
constexpr auto a = test::array<int, 10>{{1, 2, 3, 4, 40, 5, 6, 7, 8, 9}};
STATIC_CHECK(ranges::max_element(a) == ranges::begin(a) + 4);
}
return test_result();
}

View File

@@ -0,0 +1,120 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
#include <memory>
#include <utility>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/merge.hpp>
#include <range/v3/algorithm/is_sorted.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
constexpr bool test_constexpr()
{
using namespace ranges;
constexpr unsigned N = 100;
test::array<int, N> ia{{0}};
test::array<int, N> ib{{0}};
test::array<int, 2 * N> ic{{0}};
for(unsigned i = 0; i < N; ++i)
ia[i] = 2 * i;
for(unsigned i = 0; i < N; ++i)
ib[i] = 2 * i + 1;
auto r = merge(ia, ib, begin(ic));
STATIC_CHECK_RETURN(r.in1 == end(ia));
STATIC_CHECK_RETURN(r.in2 == end(ib));
STATIC_CHECK_RETURN(r.out == end(ic));
STATIC_CHECK_RETURN(ic[0] == 0);
STATIC_CHECK_RETURN(ic[2 * N - 1] == (int)(2 * N - 1));
STATIC_CHECK_RETURN(is_sorted(ic));
return true;
}
int main()
{
{
int N = 100000;
std::unique_ptr<int[]> ia{new int[N]};
std::unique_ptr<int[]> ib{new int[N]};
std::unique_ptr<int[]> ic{new int[2 * N]};
for(int i = 0; i < N; ++i)
ia[i] = 2 * i;
for(int i = 0; i < N; ++i)
ib[i] = 2 * i + 1;
auto r = ranges::merge(ia.get(), ia.get() + N,
ib.get(), ib.get() + N, ic.get());
CHECK(r.in1 == ia.get() + N);
CHECK(r.in2 == ib.get() + N);
CHECK(r.out == ic.get() + 2 * N);
CHECK(ic[0] == 0);
CHECK(ic[2 * N - 1] == 2 * N - 1);
CHECK(std::is_sorted(ic.get(), ic.get() + 2 * N));
}
{
int N = 100000;
std::unique_ptr<int[]> ia{new int[N]};
std::unique_ptr<int[]> ib{new int[N]};
std::unique_ptr<int[]> ic{new int[2 * N]};
for(int i = 0; i < N; ++i)
ia[i] = 2 * i;
for(int i = 0; i < N; ++i)
ib[i] = 2 * i + 1;
auto r0 = ranges::make_subrange(ia.get(), ia.get() + N);
auto r1 = ranges::make_subrange(ib.get(), ib.get() + N);
auto r = ranges::merge(r0, r1, ic.get());
CHECK(r.in1 == ia.get() + N);
CHECK(r.in2 == ib.get() + N);
CHECK(r.out == ic.get() + 2 * N);
CHECK(ic[0] == 0);
CHECK(ic[2 * N - 1] == 2 * N - 1);
CHECK(std::is_sorted(ic.get(), ic.get() + 2 * N));
}
{
int N = 100000;
std::unique_ptr<int[]> ia{new int[N]};
std::unique_ptr<int[]> ib{new int[N]};
std::unique_ptr<int[]> ic{new int[2 * N]};
for(int i = 0; i < N; ++i)
ia[i] = 2 * i;
for(int i = 0; i < N; ++i)
ib[i] = 2 * i + 1;
auto r0 = ::MakeTestRange(ia.get(), ia.get() + N);
auto r1 = ::MakeTestRange(ib.get(), ib.get() + N);
auto r = ranges::merge(std::move(r0), std::move(r1), ic.get());
CHECK(::is_dangling(r.in1));
CHECK(::is_dangling(r.in2));
CHECK(r.out == ic.get() + 2 * N);
CHECK(ic[0] == 0);
CHECK(ic[2 * N - 1] == 2 * N - 1);
CHECK(std::is_sorted(ic.get(), ic.get() + 2 * N));
static_assert(std::is_same<decltype(r),
ranges::merge_result<ranges::dangling, ranges::dangling, int *>>::value, "");
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,141 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Casey Carter 2015
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/algorithm/min.hpp>
#include <range/v3/view/subrange.hpp>
#include <memory>
#include <random>
#include <numeric>
#include <algorithm>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
std::mt19937 gen;
template<class Iter, class Sent = Iter>
void
test_iter(Iter first, Sent last)
{
RANGES_ENSURE(first != last);
auto rng = ranges::make_subrange(first, last);
auto v1 = ranges::min(rng);
for (Iter i = first; i != last; ++i)
CHECK(!(*i < v1));
}
template<class Iter, class Sent = Iter>
void
test_iter(unsigned N)
{
RANGES_ENSURE(N > 0);
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter()
{
test_iter<Iter, Sent>(1);
test_iter<Iter, Sent>(2);
test_iter<Iter, Sent>(3);
test_iter<Iter, Sent>(10);
test_iter<Iter, Sent>(1000);
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(Iter first, Sent last)
{
RANGES_ENSURE(first != last);
auto rng = ranges::make_subrange(first, last);
auto v = ranges::min(rng, std::greater<int>());
for (Iter i = first; i != last; ++i)
CHECK(!std::greater<int>()(*i, v));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(unsigned N)
{
RANGES_ENSURE(N > 0);
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter_comp(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp()
{
test_iter_comp<Iter, Sent>(1);
test_iter_comp<Iter, Sent>(2);
test_iter_comp<Iter, Sent>(3);
test_iter_comp<Iter, Sent>(10);
test_iter_comp<Iter, Sent>(1000);
}
struct S
{
int i;
};
}
int main()
{
test_iter<InputIterator<const int*> >();
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<InputIterator<const int*> >();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{7},S{8},S{9}};
S v = ranges::min(s, std::less<int>{}, &S::i);
CHECK(v.i == -4);
// Works with initializer_lists? (Regression test for #1004)
CHECK(ranges::min({4,3,1,2,6,5}) == 1);
return test_result();
}

View File

@@ -0,0 +1,172 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <random>
#include <numeric>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/min_element.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
std::mt19937 gen;
template<class Iter, class Sent = Iter>
void
test_iter(Iter first, Sent last)
{
Iter i = ranges::min_element(first, last);
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!(*j < *i));
}
else
CHECK(i == last);
auto rng = ::MakeTestRange(first, last);
i = ranges::min_element(rng);
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!(*j < *i));
}
else
CHECK(i == last);
auto res = ranges::min_element(std::move(rng));
CHECK(::is_dangling(res));
}
template<class Iter, class Sent = Iter>
void
test_iter(unsigned N)
{
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter()
{
test_iter<Iter, Sent>(0);
test_iter<Iter, Sent>(1);
test_iter<Iter, Sent>(2);
test_iter<Iter, Sent>(3);
test_iter<Iter, Sent>(10);
test_iter<Iter, Sent>(1000);
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(Iter first, Sent last)
{
Iter i = ranges::min_element(first, last, std::greater<int>());
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!std::greater<int>()(*j, *i));
}
else
CHECK(i == last);
auto rng = ::MakeTestRange(first, last);
i = ranges::min_element(rng, std::greater<int>());
if (first != last)
{
for (Iter j = first; j != last; ++j)
CHECK(!std::greater<int>()(*j, *i));
}
else
CHECK(i == last);
auto res = ranges::min_element(std::move(rng), std::greater<int>());
CHECK(::is_dangling(res));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(unsigned N)
{
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter_comp(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp()
{
test_iter_comp<Iter, Sent>(0);
test_iter_comp<Iter, Sent>(1);
test_iter_comp<Iter, Sent>(2);
test_iter_comp<Iter, Sent>(3);
test_iter_comp<Iter, Sent>(10);
test_iter_comp<Iter, Sent>(1000);
}
struct S
{
int i;
};
}
int main()
{
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{7},S{8},S{9}};
S const *ps = ranges::min_element(s, std::less<int>{}, &S::i);
CHECK(ps->i == -4);
{
constexpr auto a = test::array<int, 10>{{1, 2, 3, 4, -4, 5, 6, 7, 8, 9}};
STATIC_CHECK(ranges::min_element(a) == ranges::begin(a) + 4);
}
return test_result();
}

View File

@@ -0,0 +1,171 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Casey Carter 2015
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <range/v3/algorithm/minmax.hpp>
#include <range/v3/view/subrange.hpp>
#include <memory>
#include <numeric>
#include <random>
#include <algorithm>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
std::mt19937 gen;
template<class Iter, class Sent = Iter>
void
test_iter(Iter first, Sent last)
{
RANGES_ENSURE(first != last);
auto rng = ranges::make_subrange(first, last);
auto res = ranges::minmax(rng);
for (Iter i = first; i != last; ++i) {
CHECK(!(*i < res.min));
CHECK(!(res.max < *i));
}
}
template<class Iter, class Sent = Iter>
void
test_iter(unsigned N)
{
RANGES_ENSURE(N > 0);
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter()
{
test_iter<Iter, Sent>(1);
test_iter<Iter, Sent>(2);
test_iter<Iter, Sent>(3);
test_iter<Iter, Sent>(10);
test_iter<Iter, Sent>(1000);
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(Iter first, Sent last)
{
RANGES_ENSURE(first != last);
typedef std::greater<int> Compare;
Compare comp;
auto rng = ranges::make_subrange(first, last);
auto res = ranges::minmax(rng, comp);
for (Iter i = first; i != last; ++i) {
CHECK(!comp(*i, res.min));
CHECK(!comp(res.max, *i));
}
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(unsigned N)
{
RANGES_ENSURE(N > 0);
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter_comp(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp()
{
test_iter_comp<Iter, Sent>(1);
test_iter_comp<Iter, Sent>(2);
test_iter_comp<Iter, Sent>(3);
test_iter_comp<Iter, Sent>(10);
test_iter_comp<Iter, Sent>(1000);
}
struct S
{
int value;
int index;
};
}
int main()
{
test_iter<InputIterator<const int*> >();
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter<InputIterator<const int*> >();
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<InputIterator<const int*> >();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<InputIterator<const int*> >();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<InputIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s[] = {S{1,0},S{2,1},S{3,2},S{4,3},S{-4,4},S{40,5},S{-4,6},S{40,7},S{7,8},S{8,9},S{9,10}};
auto res = ranges::minmax(s, std::less<int>{}, &S::value);
CHECK(res.min.value == -4);
CHECK(res.min.index == 4);
CHECK(res.max.value == 40);
CHECK(res.max.index == 7);
// Works with initializer_lists? (Regression test for #1004)
CHECK(ranges::minmax({4,3,1,2,6,5}) == ranges::minmax_result<int>{1,6});
return test_result();
}

View File

@@ -0,0 +1,249 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <numeric>
#include <random>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/minmax_element.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
namespace
{
std::mt19937 gen;
template<class Iter, class Sent = Iter>
void
test_iter(Iter first, Sent last)
{
ranges::minmax_element_result<Iter> p = ranges::minmax_element(first, last);
if (first != last)
{
for (Iter j = first; j != last; ++j)
{
CHECK(!(*j < *p.min));
CHECK(!(*p.max < *j));
}
}
else
{
CHECK(p.min == last);
CHECK(p.max == last);
}
auto rng = ::MakeTestRange(first, last);
p = ranges::minmax_element(rng);
if (first != last)
{
for (Iter j = first; j != last; ++j)
{
CHECK(!(*j < *p.min));
CHECK(!(*p.max < *j));
}
}
else
{
CHECK(p.min == last);
CHECK(p.max == last);
}
auto res = ranges::minmax_element(std::move(rng));
if (first != last)
{
for (Iter j = first; j != last; ++j)
{
CHECK(is_dangling(res.min));
CHECK(!(*p.max < *j));
}
}
else
{
CHECK(is_dangling(res.min));
CHECK(is_dangling(res.max));
}
}
template<class Iter, class Sent = Iter>
void
test_iter(unsigned N)
{
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter()
{
test_iter<Iter, Sent>(0);
test_iter<Iter, Sent>(1);
test_iter<Iter, Sent>(2);
test_iter<Iter, Sent>(3);
test_iter<Iter, Sent>(10);
test_iter<Iter, Sent>(1000);
{
const unsigned N = 100;
std::unique_ptr<int[]> a{new int[N]};
std::fill_n(a.get(), N, 5);
std::shuffle(a.get(), a.get()+N, gen);
ranges::minmax_element_result<Iter> p = ranges::minmax_element(Iter(a.get()), Sent(a.get()+N));
CHECK(base(p.min) == a.get());
CHECK(base(p.max) == a.get()+N-1);
}
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(Iter first, Sent last)
{
typedef std::greater<int> Compare;
Compare comp;
ranges::minmax_element_result<Iter> p = ranges::minmax_element(first, last, comp);
if (first != last)
{
for (Iter j = first; j != last; ++j)
{
CHECK(!comp(*j, *p.min));
CHECK(!comp(*p.max, *j));
}
}
else
{
CHECK(p.min == last);
CHECK(p.max == last);
}
auto rng = ::MakeTestRange(first, last);
p = ranges::minmax_element(rng, comp);
if (first != last)
{
for (Iter j = first; j != last; ++j)
{
CHECK(!comp(*j, *p.min));
CHECK(!comp(*p.max, *j));
}
}
else
{
CHECK(p.min == last);
CHECK(p.max == last);
}
auto res = ranges::minmax_element(std::move(rng), comp);
CHECK(is_dangling(res.min));
CHECK(is_dangling(res.max));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp(unsigned N)
{
std::unique_ptr<int[]> a{new int[N]};
std::iota(a.get(), a.get()+N, 0);
std::shuffle(a.get(), a.get()+N, gen);
test_iter_comp(Iter(a.get()), Sent(a.get()+N));
}
template<class Iter, class Sent = Iter>
void
test_iter_comp()
{
test_iter_comp<Iter, Sent>(0);
test_iter_comp<Iter, Sent>(1);
test_iter_comp<Iter, Sent>(2);
test_iter_comp<Iter, Sent>(3);
test_iter_comp<Iter, Sent>(10);
test_iter_comp<Iter, Sent>(1000);
{
const unsigned N = 100;
std::unique_ptr<int[]> a{new int[N]};
std::fill_n(a.get(), N, 5);
std::shuffle(a.get(), a.get()+N, gen);
typedef std::greater<int> Compare;
Compare comp;
ranges::minmax_element_result<Iter> p = ranges::minmax_element(Iter(a.get()), Sent(a.get()+N), comp);
CHECK(base(p.min) == a.get());
CHECK(base(p.max) == a.get()+N-1);
}
}
struct S
{
int i;
};
}
int main()
{
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter<ForwardIterator<const int*> >();
test_iter<BidirectionalIterator<const int*> >();
test_iter<RandomAccessIterator<const int*> >();
test_iter<const int*>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<ForwardIterator<const int*> >();
test_iter_comp<BidirectionalIterator<const int*> >();
test_iter_comp<RandomAccessIterator<const int*> >();
test_iter_comp<const int*>();
test_iter_comp<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter_comp<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{40},S{7},S{8},S{9}};
ranges::minmax_element_result<S const *> ps = ranges::minmax_element(s, std::less<int>{}, &S::i);
CHECK(ps.min->i == -4);
CHECK(ps.max->i == 40);
{
constexpr auto a = test::array<int, 10>{{1, 2, 3, 4, -4, 5, 6, 40, 8, 9}};
STATIC_CHECK(ranges::minmax_element(a).min == ranges::begin(a) + 4);
STATIC_CHECK(ranges::minmax_element(a).max == ranges::begin(a) + 7);
}
return test_result();
}

View File

@@ -0,0 +1,149 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/mismatch.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
template<typename Iter, typename Sent = Iter>
void test_iter()
{
int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
constexpr auto sa = ranges::size(ia);
int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};
using Res = ranges::mismatch_result<Iter, Iter>;
CHECK(ranges::mismatch(Iter(ia), Sent(ia + sa), Iter(ib)) ==
Res{Iter(ia+3),Iter(ib+3)});
CHECK(ranges::mismatch(Iter(ia),Sent(ia + sa),Iter(ib),Sent(ib + sa)) ==
Res{Iter(ia+3),Iter(ib+3)});
CHECK(ranges::mismatch(Iter(ia),Sent(ia + sa),Iter(ib),Sent(ib + 2)) ==
Res{Iter(ia+2),Iter(ib+2)});
CHECK(ranges::mismatch(Iter(ia),Sent(ia + sa),Iter(ib),std::equal_to<int>()) ==
Res{Iter(ia+3),Iter(ib+3)});
CHECK(ranges::mismatch(Iter(ia),Sent(ia + sa),Iter(ib),Sent(ib + sa),std::equal_to<int>()) ==
Res{Iter(ia+3),Iter(ib+3)});
CHECK(ranges::mismatch(Iter(ia), Sent(ia + sa), Iter(ib), Sent(ib + 2), std::equal_to<int>()) ==
Res{Iter(ia+2),Iter(ib+2)});
}
template<typename Iter, typename Sent = Iter>
void test_range()
{
int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
constexpr auto sa = ranges::size(ia);
int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};
using Res = ranges::mismatch_result<Iter, Iter>;
auto rng1 = ::MakeTestRange(Iter(ia), Sent(ia + sa));
CHECK(ranges::mismatch(rng1, Iter(ib)) ==
Res{Iter(ia+3),Iter(ib+3)});
auto r1 = ranges::mismatch(std::move(rng1), Iter(ib));
CHECK(::is_dangling(r1.in1));
CHECK(r1.in2 == Iter(ib+3));
auto rng2 = ::MakeTestRange(Iter(ia),Sent(ia + sa));
auto rng3 = ::MakeTestRange(Iter(ib),Sent(ib + sa));
CHECK(ranges::mismatch(rng2,rng3) ==
Res{Iter(ia+3),Iter(ib+3)});
auto r2 = ranges::mismatch(std::move(rng2), std::move(rng3));
CHECK(::is_dangling(r2.in1));
CHECK(::is_dangling(r2.in2));
auto r3 = ranges::mismatch(rng2, std::move(rng3));
CHECK(r3.in1 == Iter(ia+3));
CHECK(::is_dangling(r3.in2));
auto r4 = ranges::mismatch(std::move(rng2), rng3);
CHECK(::is_dangling(r4.in1));
CHECK(r4.in2 == Iter(ib+3));
auto rng4 = ::MakeTestRange(Iter(ia),Sent(ia + sa));
auto rng5 = ::MakeTestRange(Iter(ib),Sent(ib + 2));
CHECK(ranges::mismatch(rng4,rng5) ==
Res{Iter(ia+2),Iter(ib+2)});
auto rng6 = ::MakeTestRange(Iter(ia),Sent(ia + sa));
CHECK(ranges::mismatch(rng6,Iter(ib),std::equal_to<int>()) ==
Res{Iter(ia+3),Iter(ib+3)});
auto rng7 = ::MakeTestRange(Iter(ia),Sent(ia + sa));
auto rng8 = ::MakeTestRange(Iter(ib),Sent(ib + sa));
CHECK(ranges::mismatch(rng7,rng8,std::equal_to<int>()) ==
Res{Iter(ia+3),Iter(ib+3)});
auto rng9 = ::MakeTestRange(Iter(ia), Sent(ia + sa));
auto rng10 = ::MakeTestRange(Iter(ib), Sent(ib + 2));
CHECK(ranges::mismatch(rng9,rng10,std::equal_to<int>()) ==
Res{Iter(ia+2),Iter(ib+2)});
}
struct S
{
int i;
};
int main()
{
test_iter<InputIterator<const int*>>();
test_iter<ForwardIterator<const int*>>();
test_iter<BidirectionalIterator<const int*>>();
test_iter<RandomAccessIterator<const int*>>();
test_iter<const int*>();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_iter<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_iter<RandomAccessIterator<const int*>, Sentinel<const int*>>();
test_range<InputIterator<const int*>>();
test_range<ForwardIterator<const int*>>();
test_range<BidirectionalIterator<const int*>>();
test_range<RandomAccessIterator<const int*>>();
test_range<const int*>();
test_range<InputIterator<const int*>, Sentinel<const int*>>();
test_range<ForwardIterator<const int*>, Sentinel<const int*>>();
test_range<BidirectionalIterator<const int*>, Sentinel<const int*>>();
test_range<RandomAccessIterator<const int*>, Sentinel<const int*>>();
// Works with projections?
S s1[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{40},S{7},S{8},S{9}};
int const i1[] = {1,2,3,4,5,6,7,8,9};
ranges::mismatch_result<S const *, int const *> ps1
= ranges::mismatch(s1, i1, std::equal_to<int>(), &S::i);
CHECK(ps1.in1->i == -4);
CHECK(*ps1.in2 == 5);
S s2[] = {S{1},S{2},S{3},S{4},S{5},S{6},S{40},S{7},S{8},S{9}};
ranges::mismatch_result<S const *, S const *> ps2
= ranges::mismatch(s1, s2, std::equal_to<int>(), &S::i, &S::i);
CHECK(ps2.in1->i == -4);
CHECK(ps2.in2->i == 5);
constexpr auto r1 = test::array<int, 11>{{1, 2, 3, 4, -4, 5, 6, 40, 7, 8, 9}};
constexpr auto r11 = test::array<int, 9>{{1, 2, 3, 4, 5, 6, 7, 8, 9}};
constexpr auto r2 = test::array<int, 10>{{1, 2, 3, 4, 5, 6, 40, 7, 8, 9}};
STATIC_CHECK(*ranges::mismatch(r1, r11, std::equal_to<int>{}).in1 == -4);
STATIC_CHECK(*ranges::mismatch(r1, r11, std::equal_to<int>{}).in2 == 5);
STATIC_CHECK(*ranges::mismatch(r1, r2, std::equal_to<int>{}).in1 == -4);
STATIC_CHECK(*ranges::mismatch(r1, r2, std::equal_to<int>{}).in2 == 5);
return test_result();
}

View File

@@ -0,0 +1,413 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/move.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<typename InIter, typename OutIter, typename Sent = InIter>
void
test()
{
{
const int N = 1000;
int ia[N];
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
ranges::move_result<InIter, OutIter> r = ranges::move(InIter(ia), Sent(ia+N), OutIter(ib));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib+N);
for(int i = 0; i < N; ++i)
CHECK(ia[i] == ib[i]);
}
{
const int N = 1000;
int ia[N];
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
ranges::move_result<InIter, OutIter> r = ranges::move(as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+N))), OutIter(ib));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib+N);
for(int i = 0; i < N; ++i)
CHECK(ia[i] == ib[i]);
}
}
template<typename InIter, typename OutIter, typename Sent = InIter>
constexpr bool test_constexpr()
{
{
constexpr int N = 1000;
int ia[N]{1};
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
const auto r = ranges::move(InIter(ia), Sent(ia + N), OutIter(ib));
if(base(r.in) != ia + N)
{
return false;
}
if(base(r.out) != ib + N)
{
return false;
}
for(int i = 0; i < N; ++i)
if(ia[i] != ib[i])
{
return false;
}
}
{
constexpr int N = 1000;
int ia[N]{1};
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
const auto r = ranges::move(
as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia + N))), OutIter(ib));
if(base(r.in) != ia + N)
{
return false;
}
if(base(r.out) != ib + N)
{
return false;
}
for(int i = 0; i < N; ++i)
if(ia[i] != ib[i])
{
return false;
}
}
return true;
}
struct S
{
std::unique_ptr<int> p;
};
template<typename InIter, typename OutIter, typename Sent = InIter>
void
test1()
{
{
const int N = 100;
std::unique_ptr<int> ia[N];
for(int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::unique_ptr<int> ib[N];
ranges::move_result<InIter, OutIter> r = ranges::move(InIter(ia), Sent(ia+N), OutIter(ib));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib+N);
for(int i = 0; i < N; ++i)
{
CHECK(ia[i].get() == nullptr);
CHECK(*ib[i] == i);
}
}
{
const int N = 100;
std::unique_ptr<int> ia[N];
for(int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::unique_ptr<int> ib[N];
ranges::move_result<InIter, OutIter> r = ranges::move(as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+N))), OutIter(ib));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib+N);
for(int i = 0; i < N; ++i)
{
CHECK(ia[i].get() == nullptr);
CHECK(*ib[i] == i);
}
ranges::move(ib, ib+N, ia);
auto r2 = ranges::move(ranges::make_subrange(InIter(ia), Sent(ia+N)), OutIter(ib));
CHECK(base(r2.in) == ia+N);
CHECK(base(r2.out) == ib+N);
for(int i = 0; i < N; ++i)
{
CHECK(ia[i].get() == nullptr);
CHECK(*ib[i] == i);
}
}
}
int main()
{
test<InputIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, InputIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*> >();
test<const int*, InputIterator<int*> >();
test<const int*, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<int*> >();
test<const int*, int*>();
test<InputIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, InputIterator<int*>, Sentinel<const int*> >();
test<InputIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<InputIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<InputIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, OutputIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, InputIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, OutputIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, InputIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, OutputIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, InputIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test1<InputIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<ForwardIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<BidirectionalIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<RandomAccessIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<std::unique_ptr<int>*, OutputIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, InputIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, ForwardIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, std::unique_ptr<int>*>();
test1<InputIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<InputIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<ForwardIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<ForwardIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<BidirectionalIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<RandomAccessIterator<std::unique_ptr<int>*>, OutputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, InputIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*> >();
{
STATIC_CHECK(test_constexpr<InputIterator<const int *>, OutputIterator<int *>>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>, InputIterator<int *>>());
STATIC_CHECK(
test_constexpr<InputIterator<const int *>, ForwardIterator<int *>>());
STATIC_CHECK(
test_constexpr<InputIterator<const int *>, BidirectionalIterator<int *>>());
STATIC_CHECK(
test_constexpr<InputIterator<const int *>, RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>, int *>());
STATIC_CHECK(
test_constexpr<ForwardIterator<const int *>, OutputIterator<int *>>());
STATIC_CHECK(
test_constexpr<ForwardIterator<const int *>, InputIterator<int *>>());
STATIC_CHECK(
test_constexpr<ForwardIterator<const int *>, ForwardIterator<int *>>());
STATIC_CHECK(
test_constexpr<ForwardIterator<const int *>, BidirectionalIterator<int *>>());
STATIC_CHECK(
test_constexpr<ForwardIterator<const int *>, RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>, int *>());
STATIC_CHECK(
test_constexpr<BidirectionalIterator<const int *>, OutputIterator<int *>>());
STATIC_CHECK(
test_constexpr<BidirectionalIterator<const int *>, InputIterator<int *>>());
STATIC_CHECK(
test_constexpr<BidirectionalIterator<const int *>, ForwardIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>, int *>());
STATIC_CHECK(
test_constexpr<RandomAccessIterator<const int *>, OutputIterator<int *>>());
STATIC_CHECK(
test_constexpr<RandomAccessIterator<const int *>, InputIterator<int *>>());
STATIC_CHECK(
test_constexpr<RandomAccessIterator<const int *>, ForwardIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>, int *>());
STATIC_CHECK(test_constexpr<const int *, OutputIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, InputIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, ForwardIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, int *>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>,
OutputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>,
InputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>,
ForwardIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>,
BidirectionalIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<InputIterator<const int *>,
RandomAccessIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>,
OutputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>,
InputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>,
ForwardIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>,
BidirectionalIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<ForwardIterator<const int *>,
RandomAccessIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
OutputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
InputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
ForwardIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
BidirectionalIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
RandomAccessIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
OutputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
InputIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
ForwardIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
BidirectionalIterator<int *>,
Sentinel<const int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
RandomAccessIterator<int *>,
Sentinel<const int *>>());
}
return test_result();
}

View File

@@ -0,0 +1,217 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/move_backward.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<typename InIter, typename OutIter>
void
test()
{
{
const int N = 1000;
int ia[N];
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
ranges::move_backward_result<InIter, OutIter> r =
ranges::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib);
for(int i = 0; i < N; ++i)
CHECK(ia[i] == ib[i]);
}
{
const int N = 1000;
int ia[N];
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
ranges::move_backward_result<InIter, OutIter> r =
ranges::move_backward(ranges::make_subrange(InIter(ia), InIter(ia+N)), OutIter(ib+N));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib);
for(int i = 0; i < N; ++i)
CHECK(ia[i] == ib[i]);
}
}
template<typename InIter, typename OutIter, typename Sent = InIter>
constexpr bool test_constexpr()
{
{
constexpr int N = 1000;
int ia[N]{1};
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
const auto r = ranges::move_backward(InIter(ia), Sent(ia + N), OutIter(ib + N));
if(base(r.in) != ia + N)
{
return false;
}
if(base(r.out) != ib)
{
return false;
}
for(int i = 0; i < N; ++i)
if(ia[i] != ib[i])
{
return false;
}
}
{
constexpr int N = 1000;
int ia[N]{1};
for(int i = 0; i < N; ++i)
ia[i] = i;
int ib[N] = {0};
const auto r = ranges::move_backward(
as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia + N))), OutIter(ib + N));
if(base(r.in) != ia + N)
{
return false;
}
if(base(r.out) != ib)
{
return false;
}
for(int i = 0; i < N; ++i)
if(ia[i] != ib[i])
{
return false;
}
}
return true;
}
struct S
{
std::unique_ptr<int> p;
};
template<typename InIter, typename OutIter>
void
test1()
{
{
const int N = 100;
std::unique_ptr<int> ia[N];
for(int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::unique_ptr<int> ib[N];
ranges::move_backward_result<InIter, OutIter> r =
ranges::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib);
for(int i = 0; i < N; ++i)
{
CHECK(ia[i].get() == nullptr);
CHECK(*ib[i] == i);
}
}
{
const int N = 100;
std::unique_ptr<int> ia[N];
for(int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::unique_ptr<int> ib[N];
ranges::move_backward_result<InIter, OutIter> r =
ranges::move_backward(ranges::make_subrange(InIter(ia), InIter(ia+N)), OutIter(ib+N));
CHECK(base(r.in) == ia+N);
CHECK(base(r.out) == ib);
for(int i = 0; i < N; ++i)
{
CHECK(ia[i].get() == nullptr);
CHECK(*ib[i] == i);
}
ranges::move_backward(ib, ib+N, ia+N);
auto r2 = ranges::move_backward(ranges::make_subrange(InIter(ia), InIter(ia+N)), OutIter(ib+N));
CHECK(base(r2.in) == ia+N);
CHECK(base(r2.out) == ib);
for(int i = 0; i < N; ++i)
{
CHECK(ia[i].get() == nullptr);
CHECK(*ib[i] == i);
}
}
}
int main()
{
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<int*> >();
test<const int*, int*>();
test1<BidirectionalIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<BidirectionalIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<RandomAccessIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<RandomAccessIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test1<std::unique_ptr<int>*, BidirectionalIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, RandomAccessIterator<std::unique_ptr<int>*> >();
test1<std::unique_ptr<int>*, std::unique_ptr<int>*>();
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>,
RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<BidirectionalIterator<const int *>, int *>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>,
BidirectionalIterator<int *>>());
STATIC_CHECK(
test_constexpr<RandomAccessIterator<const int *>, RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<RandomAccessIterator<const int *>, int *>());
STATIC_CHECK(test_constexpr<const int *, BidirectionalIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, RandomAccessIterator<int *>>());
STATIC_CHECK(test_constexpr<const int *, int *>());
return test_result();
}

View File

@@ -0,0 +1,236 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstring>
#include <utility>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/permutation.hpp>
#include <range/v3/algorithm/equal.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
int factorial(int x)
{
int r = 1;
for (; x; --x)
r *= x;
return r;
}
template<typename Iter, typename Sent = Iter>
void test_iter()
{
int ia[] = {1, 2, 3, 4, 5, 6};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for (int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::next_permutation(Iter(ia), Sent(ia+e));
if(e > 1)
{
if(x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));
}
++count;
} while(x);
CHECK(count == factorial(e));
}
}
template<typename Iter, typename Sent = Iter>
void test_range()
{
int ia[] = {1, 2, 3, 4, 5, 6};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for (int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::next_permutation(ranges::make_subrange(Iter(ia), Sent(ia+e)));
if(e > 1)
{
if(x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));
}
++count;
} while(x);
CHECK(count == factorial(e));
}
}
template<typename Iter, typename Sent = Iter>
void test_iter_comp()
{
typedef std::greater<int> C;
int ia[] = {6, 5, 4, 3, 2, 1};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for(int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::next_permutation(Iter(ia), Sent(ia+e), C());
if(e > 1)
{
if (x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));
}
++count;
} while (x);
CHECK(count == factorial(e));
}
}
template<typename Iter, typename Sent = Iter>
void test_range_comp()
{
typedef std::greater<int> C;
int ia[] = {6, 5, 4, 3, 2, 1};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for(int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::next_permutation(ranges::make_subrange(Iter(ia), Sent(ia+e)), C());
if(e > 1)
{
if (x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));
}
++count;
} while (x);
CHECK(count == factorial(e));
}
}
struct c_str
{
char const * value;
friend bool operator==(c_str a, c_str b)
{
return 0 == std::strcmp(a.value, b.value);
}
friend bool operator!=(c_str a, c_str b)
{
return !(a == b);
}
};
// For debugging the projection test
std::ostream &operator<<(std::ostream& sout, std::pair<int, c_str> p)
{
return sout << "{" << p.first << "," << p.second.value << "}";
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {6, 5, 4, 3, 2, 1};
using IL = std::initializer_list<int>;
next_permutation(ia, greater{});
STATIC_CHECK_RETURN(equal(ia, IL{6, 5, 4, 3, 1, 2}));
next_permutation(ia, greater{});
STATIC_CHECK_RETURN(equal(ia, IL{6, 5, 4, 2, 3, 1}));
next_permutation(ia, greater{});
STATIC_CHECK_RETURN(equal(ia, IL{6, 5, 4, 2, 1, 3}));
return true;
}
int main()
{
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter<RandomAccessIterator<int*>, Sentinel<int*> >();
test_iter_comp<BidirectionalIterator<int*> >();
test_iter_comp<RandomAccessIterator<int*> >();
test_iter_comp<int*>();
test_iter_comp<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter_comp<RandomAccessIterator<int*>, Sentinel<int*> >();
test_range<BidirectionalIterator<int*> >();
test_range<RandomAccessIterator<int*> >();
test_range<int*>();
test_range<BidirectionalIterator<int*>, Sentinel<int*> >();
test_range<RandomAccessIterator<int*>, Sentinel<int*> >();
test_range_comp<BidirectionalIterator<int*> >();
test_range_comp<RandomAccessIterator<int*> >();
test_range_comp<int*>();
test_range_comp<BidirectionalIterator<int*>, Sentinel<int*> >();
test_range_comp<RandomAccessIterator<int*>, Sentinel<int*> >();
// Test projection
using C = std::greater<int>;
using I = std::initializer_list<std::pair<int, c_str>>;
std::pair<int, c_str> ia[] = {{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {3,{"three"}}, {2,{"two"}}, {1,{"one"}}};
CHECK(ranges::next_permutation(ia, C(), &std::pair<int,c_str>::first));
::check_equal(ia, I{{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {3,{"three"}}, {1,{"one"}}, {2,{"two"}}});
CHECK(ranges::next_permutation(ia, C(), &std::pair<int,c_str>::first));
::check_equal(ia, I{{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {2,{"two"}}, {3,{"three"}}, {1,{"one"}}});
CHECK(ranges::next_permutation(ia, C(), &std::pair<int,c_str>::first));
::check_equal(ia, I{{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {2,{"two"}}, {1,{"one"}}, {3,{"three"}}});
// etc..
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,72 @@
// Range v3 library
//
// Copyright Andrew Sutton 2014
// Copyright Gonzalo Brito Gadeschi 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/none_of.hpp>
#include "../simple_test.hpp"
constexpr bool even(int n) { return n % 2 == 0; }
struct S {
S(bool p) : test(p) { }
bool p() const { return test; }
bool test;
};
constexpr bool test_constexpr(std::initializer_list<int> il)
{
return ranges::none_of(il, even);
}
int main()
{
std::vector<int> all_even { 0, 2, 4, 6 };
std::vector<int> one_even { 1, 3, 4, 7 };
std::vector<int> none_even { 1, 3, 5, 7 };
CHECK(!ranges::none_of(all_even.begin(), all_even.end(), even));
CHECK(!ranges::none_of(one_even.begin(), one_even.end(), even));
CHECK(ranges::none_of(none_even.begin(), none_even.end(), even));
CHECK(!ranges::none_of(all_even, even));
CHECK(!ranges::none_of(one_even, even));
CHECK(ranges::none_of(none_even, even));
using ILI = std::initializer_list<int>;
CHECK(!ranges::none_of(ILI{0, 2, 4, 6}, [](int n) { return n % 2 == 0; }));
CHECK(!ranges::none_of(ILI{1, 3, 4, 7}, [](int n) { return n % 2 == 0; }));
CHECK(ranges::none_of(ILI{1, 3, 5, 7}, [](int n) { return n % 2 == 0; }));
std::vector<S> all_true { true, true, true };
std::vector<S> one_true { false, false, true };
std::vector<S> none_true { false, false, false };
CHECK(!ranges::none_of(all_true.begin(), all_true.end(), &S::p));
CHECK(!ranges::none_of(one_true.begin(), one_true.end(), &S::p));
CHECK(ranges::none_of(none_true.begin(), none_true.end(), &S::p));
CHECK(!ranges::none_of(all_true, &S::p));
CHECK(!ranges::none_of(one_true, &S::p));
CHECK(ranges::none_of(none_true, &S::p));
using ILS = std::initializer_list<S>;
CHECK(!ranges::none_of(ILS{S(true), S(true), S(true)}, &S::p));
CHECK(!ranges::none_of(ILS{S(false), S(true), S(false)}, &S::p));
CHECK(ranges::none_of(ILS{S(false), S(false), S(false)}, &S::p));
STATIC_CHECK(!test_constexpr({0, 2, 4, 6}));
STATIC_CHECK(!test_constexpr({1, 3, 4, 7}));
STATIC_CHECK(test_constexpr({1, 3, 5, 7}));
return ::test_result();
}

View File

@@ -0,0 +1,103 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <random>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/nth_element.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
void
test_one(unsigned N, unsigned M)
{
RANGES_ENSURE(N != 0);
RANGES_ENSURE(M < N);
std::unique_ptr<int[]> array{new int[N]};
for (int i = 0; (unsigned)i < N; ++i)
array[i] = i;
std::shuffle(array.get(), array.get()+N, gen);
CHECK(ranges::nth_element(array.get(), array.get()+M, array.get()+N) == array.get()+N);
CHECK((unsigned)array[M] == M);
std::shuffle(array.get(), array.get()+N, gen);
CHECK(ranges::nth_element(::as_lvalue(ranges::make_subrange(array.get(), array.get()+N)), array.get()+M) == array.get()+N);
CHECK((unsigned)array[M] == M);
std::shuffle(array.get(), array.get()+N, gen);
CHECK(ranges::nth_element(ranges::make_subrange(array.get(), array.get()+N), array.get()+M) == array.get()+N);
CHECK((unsigned)array[M] == M);
ranges::nth_element(array.get(), array.get()+N, array.get()+N); // first, last, end
}
void
test(unsigned N)
{
test_one(N, 0);
test_one(N, 1);
test_one(N, 2);
test_one(N, 3);
test_one(N, N/2-1);
test_one(N, N/2);
test_one(N, N/2+1);
test_one(N, N-3);
test_one(N, N-2);
test_one(N, N-1);
}
struct S
{
int i,j;
};
}
int main()
{
int d = 0;
ranges::nth_element(&d, &d, &d);
CHECK(d == 0);
test(256);
test(257);
test(499);
test(500);
test(997);
test(1000);
test(1009);
// Works with projections?
const int N = 257;
const int M = 56;
S ia[N];
for(int i = 0; i < N; ++i)
ia[i].i = ia[i].j = i;
std::shuffle(ia, ia+N, gen);
ranges::nth_element(ia, ia+M, std::less<int>(), &S::i);
CHECK(ia[M].i == M);
CHECK(ia[M].j == M);
return test_result();
}

View File

@@ -0,0 +1,204 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <random>
#include <algorithm>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/partial_sort.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
struct indirect_less
{
template<class P>
bool operator()(const P& x, const P& y)
{return *x < *y;}
};
void
test_larger_sorts(int N, int M)
{
RANGES_ENSURE(N > 0);
RANGES_ENSURE(M >= 0 && M <= N);
int* array = new int[N];
for(int i = 0; i < N; ++i)
array[i] = i;
using I = RandomAccessIterator<int*>;
using S = Sentinel<int*>;
std::shuffle(array, array+N, gen);
int *res = ranges::partial_sort(array, array+M, array+N);
CHECK(res == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == i);
std::shuffle(array, array+N, gen);
I res2 = ranges::partial_sort(I{array}, I{array+M}, S{array+N});
CHECK(res2.base() == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == i);
std::shuffle(array, array+N, gen);
res = ranges::partial_sort(ranges::make_subrange(array, array+N), array+M);
CHECK(res == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == i);
std::shuffle(array, array+N, gen);
res2 = ranges::partial_sort(ranges::make_subrange(I{array}, S{array+N}), I{array+M});
CHECK(res2.base() == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == i);
std::shuffle(array, array+N, gen);
auto res3 = ranges::partial_sort(::MakeTestRange(array, array+N), array+M);
CHECK(::is_dangling(res3));
for(int i = 0; i < M; ++i)
CHECK(array[i] == i);
std::shuffle(array, array+N, gen);
auto res4 = ranges::partial_sort(::MakeTestRange(I{array}, S{array+N}), I{array+M});
CHECK(::is_dangling(res4));
for(int i = 0; i < M; ++i)
CHECK(array[i] == i);
std::shuffle(array, array+N, gen);
res = ranges::partial_sort(array, array+M, array+N, std::greater<int>());
CHECK(res == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == N-i-1);
std::shuffle(array, array+N, gen);
res2 = ranges::partial_sort(I{array}, I{array+M}, S{array+N}, std::greater<int>());
CHECK(res2.base() == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == N-i-1);
std::shuffle(array, array+N, gen);
res = ranges::partial_sort(ranges::make_subrange(array, array+N), array+M, std::greater<int>());
CHECK(res == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == N-i-1);
std::shuffle(array, array+N, gen);
res2 = ranges::partial_sort(ranges::make_subrange(I{array}, S{array+N}), I{array+M}, std::greater<int>());
CHECK(res2.base() == array+N);
for(int i = 0; i < M; ++i)
CHECK(array[i] == N-i-1);
delete [] array;
}
void
test_larger_sorts(int N)
{
test_larger_sorts(N, 0);
test_larger_sorts(N, 1);
test_larger_sorts(N, 2);
test_larger_sorts(N, 3);
test_larger_sorts(N, N/2-1);
test_larger_sorts(N, N/2);
test_larger_sorts(N, N/2+1);
test_larger_sorts(N, N-2);
test_larger_sorts(N, N-1);
test_larger_sorts(N, N);
}
struct S
{
int i, j;
};
}
constexpr bool test_constexpr()
{
test::array<std::size_t, 10> v{{0}};
for(std::size_t i = 0; i < v.size(); ++i)
{
v[i] = v.size() - i - 1;
}
ranges::partial_sort(v, v.begin() + v.size() / 2, ranges::less{});
for(size_t i = 0; i < v.size() / 2; ++i)
{
STATIC_CHECK_RETURN(v[i] == i);
}
return true;
}
int main()
{
int i = 0;
int * res = ranges::partial_sort(&i, &i, &i);
CHECK(i == 0);
CHECK(res == &i);
test_larger_sorts(10);
test_larger_sorts(256);
test_larger_sorts(257);
test_larger_sorts(499);
test_larger_sorts(500);
test_larger_sorts(997);
test_larger_sorts(1000);
test_larger_sorts(1009);
// Check move-only types
{
std::vector<std::unique_ptr<int> > v(1000);
for(int j = 0; j < (int)v.size(); ++j)
v[j].reset(new int((int)v.size() - j - 1));
ranges::partial_sort(v, v.begin() + v.size()/2, indirect_less());
for(int j = 0; j < (int)v.size()/2; ++j)
CHECK(*v[j] == j);
}
// Check projections
{
std::vector<S> v(1000, S{});
for(int j = 0; (std::size_t)j < v.size(); ++j)
{
v[j].i = (int)v.size() - j - 1;
v[j].j = j;
}
ranges::partial_sort(v, v.begin() + v.size()/2, std::less<int>{}, &S::i);
for(int j = 0; (std::size_t)j < v.size()/2; ++j)
{
CHECK(v[j].i == j);
CHECK((std::size_t)v[j].j == v.size() - j - 1);
}
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,198 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <memory>
#include <random>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/partial_sort_copy.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
template<class Iter>
void
test_larger_sorts(int N, int M)
{
auto partial_sort_copy = ::make_testable_2<true, false>(ranges::partial_sort_copy);
int* input = new int[N];
int* output = new int[M];
for (int i = 0; i < N; ++i)
input[i] = i;
std::shuffle(input, input+N, gen);
partial_sort_copy(Iter(input), Iter(input+N), output, output+M).check([&](int* r)
{
int* e = output + std::min(N, M);
CHECK(r == e);
int i = 0;
for (int* x = output; x < e; ++x, ++i)
CHECK(*x == i);
std::shuffle(input, input+N, gen);
});
partial_sort_copy(Iter(input), Iter(input+N), output, output+M, std::greater<int>()).check([&](int* r)
{
int* e = output + std::min(N, M);
CHECK(r == e);
int i = N-1;
for (int* x = output; x < e; ++x, --i)
CHECK(*x == i);
std::shuffle(input, input+N, gen);
});
delete [] output;
delete [] input;
}
template<class Iter>
void
test_larger_sorts(int N)
{
test_larger_sorts<Iter>(N, 0);
test_larger_sorts<Iter>(N, 1);
test_larger_sorts<Iter>(N, 2);
test_larger_sorts<Iter>(N, 3);
test_larger_sorts<Iter>(N, N/2-1);
test_larger_sorts<Iter>(N, N/2);
test_larger_sorts<Iter>(N, N/2+1);
test_larger_sorts<Iter>(N, N-2);
test_larger_sorts<Iter>(N, N-1);
test_larger_sorts<Iter>(N, N);
test_larger_sorts<Iter>(N, N+1000);
}
template<class Iter>
void
test()
{
test_larger_sorts<Iter>(0, 100);
test_larger_sorts<Iter>(10);
test_larger_sorts<Iter>(256);
test_larger_sorts<Iter>(257);
test_larger_sorts<Iter>(499);
test_larger_sorts<Iter>(500);
test_larger_sorts<Iter>(997);
test_larger_sorts<Iter>(1000);
test_larger_sorts<Iter>(1009);
}
struct S
{
int i;
};
struct U
{
int i;
U & operator=(S s)
{
i = s.i;
return *this;
}
};
}
constexpr bool test_constexpr()
{
using namespace ranges;
using IL = std::initializer_list<int>;
int output[9] = {0};
int * r = partial_sort_copy(IL{5, 3, 4, 1, 8, 2, 6, 7, 0, 9}, output, less{});
int * e = output + 9;
STATIC_CHECK_RETURN(r == e);
int i = 0;
for(int * x = output; x < e; ++x, ++i)
{
STATIC_CHECK_RETURN(*x == i);
}
return true;
}
int main()
{
int i = 0;
int * r = ranges::partial_sort_copy(&i, &i, &i, &i+5);
CHECK(r == &i);
CHECK(i == 0);
test<InputIterator<const int*> >();
test<ForwardIterator<const int*> >();
test<BidirectionalIterator<const int*> >();
test<RandomAccessIterator<const int*> >();
test<const int*>();
// Check projections
{
constexpr int N = 256;
constexpr int M = N/2-1;
S input[N];
U output[M];
for (int j = 0; j < N; ++j)
input[j].i = j;
std::shuffle(input, input+N, gen);
U * r2 = ranges::partial_sort_copy(input, output, std::less<int>(), &S::i, &U::i);
U* e = output + std::min(N, M);
CHECK(r2 == e);
int i2 = 0;
for (U* x = output; x < e; ++x, ++i2)
CHECK(x->i == i2);
}
// Check rvalue ranges
{
constexpr int N = 256;
constexpr int M = N/2-1;
S input[N];
U output[M];
for (int j = 0; j < N; ++j)
input[j].i = j;
std::shuffle(input, input+N, gen);
auto r0 = ranges::partial_sort_copy(input, std::move(output), std::less<int>(), &S::i, &U::i);
U* e = output + std::min(N, M);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(r0));
#endif // RANGES_WORKAROUND_MSVC_573728
int i2 = 0;
for (U* x = output; x < e; ++x, ++i2)
CHECK(x->i == i2);
std::vector<U> vec(M);
auto r1 = ranges::partial_sort_copy(input, std::move(vec), std::less<int>(), &S::i, &U::i);
e = vec.data() + std::min(N, M);
CHECK(::is_dangling(r1));
i2 = 0;
for (U* x = vec.data(); x < e; ++x, ++i2)
CHECK(x->i == i2);
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,261 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/partition.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
struct is_odd
{
constexpr bool operator()(const int & i) const
{
return i & 1;
}
};
template<class Iter, class Sent = Iter>
void
test_iter()
{
// check mixed
int ia[] = {1, 2, 3, 4, 5, 6, 7, 8 ,9};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Iter r = ranges::partition(Iter(ia), Sent(ia + sa), is_odd());
CHECK(base(r) == ia + 5);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check empty
r = ranges::partition(Iter(ia), Sent(ia), is_odd());
CHECK(base(r) == ia);
// check all false
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i;
r = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());
CHECK(base(r) == ia);
// check all true
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i+1;
r = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());
CHECK(base(r) == ia+sa);
// check all true but last
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i+1;
ia[sa-1] = 10;
r = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());
CHECK(base(r) == ia+sa-1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check all true but first
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i+1;
ia[0] = 10;
r = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());
CHECK(base(r) == ia+sa-1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check all false but last
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i;
ia[sa-1] = 11;
r = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());
CHECK(base(r) == ia+1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check all false but first
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i;
ia[0] = 11;
r = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());
CHECK(base(r) == ia+1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
}
template<class Iter, class Sent = Iter>
void
test_range()
{
// check mixed
int ia[] = {1, 2, 3, 4, 5, 6, 7, 8 ,9};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Iter r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia + sa))), is_odd());
CHECK(base(r) == ia + 5);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check empty
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia))), is_odd());
CHECK(base(r) == ia);
// check all false
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i;
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), is_odd());
CHECK(base(r) == ia);
// check all true
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i+1;
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), is_odd());
CHECK(base(r) == ia+sa);
// check all true but last
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i+1;
ia[sa-1] = 10;
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), is_odd());
CHECK(base(r) == ia+sa-1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check all true but first
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i+1;
ia[0] = 10;
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), is_odd());
CHECK(base(r) == ia+sa-1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check all false but last
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i;
ia[sa-1] = 11;
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), is_odd());
CHECK(base(r) == ia+1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
// check all false but first
for (unsigned i = 0; i < sa; ++i)
ia[i] = 2*i;
ia[0] = 11;
r = ranges::partition(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), is_odd());
CHECK(base(r) == ia+1);
for (int* i = ia; i < base(r); ++i)
CHECK(is_odd()(*i));
for (int* i = base(r); i < ia+sa; ++i)
CHECK(!is_odd()(*i));
}
struct S
{
int i;
};
}
constexpr bool test_constexpr()
{
using namespace ranges;
test::array<int, 9> ia{{1, 2, 3, 4, 5, 6, 7, 8, 9}};
int * r = partition(ia, is_odd());
STATIC_CHECK_RETURN(r == begin(ia) + 5);
for(int * i = begin(ia); i < r; ++i)
{
STATIC_CHECK_RETURN(is_odd()(*i));
}
for(int * i = r; i < end(ia); ++i)
{
STATIC_CHECK_RETURN(!is_odd()(*i));
}
// Test rvalue range
auto r2 = partition(make_subrange(begin(ia), end(ia)), is_odd());
STATIC_CHECK_RETURN(r2 == begin(ia) + 5);
for(int * i = begin(ia); i < r2; ++i)
{
STATIC_CHECK_RETURN(is_odd()(*i));
}
for(int * i = r2; i < end(ia); ++i)
{
STATIC_CHECK_RETURN(!is_odd()(*i));
}
return true;
}
int main()
{
test_iter<ForwardIterator<int*> >();
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<ForwardIterator<int*>, Sentinel<int*> >();
test_iter<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter<RandomAccessIterator<int*>, Sentinel<int*> >();
test_range<ForwardIterator<int*> >();
test_range<BidirectionalIterator<int*> >();
test_range<RandomAccessIterator<int*> >();
test_range<int*>();
test_range<ForwardIterator<int*>, Sentinel<int*> >();
test_range<BidirectionalIterator<int*>, Sentinel<int*> >();
test_range<RandomAccessIterator<int*>, Sentinel<int*> >();
// Test projections
S ia[] = {S{1}, S{2}, S{3}, S{4}, S{5}, S{6}, S{7}, S{8} ,S{9}};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
S* r = ranges::partition(ia, is_odd(), &S::i);
CHECK(r == ia + 5);
for (S* i = ia; i < r; ++i)
CHECK(is_odd()(i->i));
for (S* i = r; i < ia+sa; ++i)
CHECK(!is_odd()(i->i));
// Test rvalue range
auto r2 = ranges::partition(std::move(ia), is_odd(), &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(r2));
#endif // RANGES_WORKAROUND_MSVC_573728
std::vector<S> vec(ranges::begin(ia), ranges::end(ia));
auto r3 = ranges::partition(std::move(vec), is_odd(), &S::i);
CHECK(::is_dangling(r3));
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,193 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <tuple>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/partition_copy.hpp>
#include <range/v3/view/counted.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
struct is_odd
{
constexpr bool operator()(const int & i) const
{
return i & 1;
}
};
template<class Iter, class Sent = Iter>
void
test_iter()
{
const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
int r1[10] = {0};
int r2[10] = {0};
typedef ranges::partition_copy_result<Iter, OutputIterator<int*>, int*> P;
P p = ranges::partition_copy(Iter(std::begin(ia)),
Sent(std::end(ia)),
OutputIterator<int*>(r1), r2, is_odd());
CHECK(p.in == Iter(std::end(ia)));
CHECK(p.out1.base() == r1 + 4);
CHECK(r1[0] == 1);
CHECK(r1[1] == 3);
CHECK(r1[2] == 5);
CHECK(r1[3] == 7);
CHECK(p.out2 == r2 + 4);
CHECK(r2[0] == 2);
CHECK(r2[1] == 4);
CHECK(r2[2] == 6);
CHECK(r2[3] == 8);
}
template<class Iter, class Sent = Iter>
void
test_range()
{
const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
int r1[10] = {0};
int r2[10] = {0};
typedef ranges::partition_copy_result<Iter, OutputIterator<int*>, int*> P;
P p = ranges::partition_copy(::as_lvalue(ranges::make_subrange(Iter(std::begin(ia)),
Sent(std::end(ia)))),
OutputIterator<int*>(r1), r2, is_odd());
CHECK(p.in == Iter(std::end(ia)));
CHECK(p.out1.base() == r1 + 4);
CHECK(r1[0] == 1);
CHECK(r1[1] == 3);
CHECK(r1[2] == 5);
CHECK(r1[3] == 7);
CHECK(p.out2 == r2 + 4);
CHECK(r2[0] == 2);
CHECK(r2[1] == 4);
CHECK(r2[2] == 6);
CHECK(r2[3] == 8);
}
struct S
{
int i;
};
void test_proj()
{
// Test projections
const S ia[] = {S{1}, S{2}, S{3}, S{4}, S{6}, S{8}, S{5}, S{7}};
S r1[10] = {S{0}};
S r2[10] = {S{0}};
typedef ranges::partition_copy_result<S const *, S*, S*> P;
P p = ranges::partition_copy(ia, r1, r2, is_odd(), &S::i);
CHECK(p.in == std::end(ia));
CHECK(p.out1 == r1 + 4);
CHECK(r1[0].i == 1);
CHECK(r1[1].i == 3);
CHECK(r1[2].i == 5);
CHECK(r1[3].i == 7);
CHECK(p.out2 == r2 + 4);
CHECK(r2[0].i == 2);
CHECK(r2[1].i == 4);
CHECK(r2[2].i == 6);
CHECK(r2[3].i == 8);
}
void test_rvalue()
{
// Test rvalue ranges
const S ia[] = {S{1}, S{2}, S{3}, S{4}, S{6}, S{8}, S{5}, S{7}};
S r1[10] = {};
S r2[10] = {};
auto p = ranges::partition_copy(std::move(ia), r1, r2, is_odd(), &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(p.in));
#endif
CHECK(p.out1 == r1 + 4);
CHECK(r1[0].i == 1);
CHECK(r1[1].i == 3);
CHECK(r1[2].i == 5);
CHECK(r1[3].i == 7);
CHECK(p.out2 == r2 + 4);
CHECK(r2[0].i == 2);
CHECK(r2[1].i == 4);
CHECK(r2[2].i == 6);
CHECK(r2[3].i == 8);
std::fill(r1 + 0, r1 + 10, S{});
std::fill(r2 + 0, r2 + 10, S{});
std::vector<S> vec(ranges::begin(ia), ranges::end(ia));
auto q = ranges::partition_copy(std::move(vec), r1, r2, is_odd(), &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(q.in));
#endif
CHECK(q.out1 == r1 + 4);
CHECK(r1[0].i == 1);
CHECK(r1[1].i == 3);
CHECK(r1[2].i == 5);
CHECK(r1[3].i == 7);
CHECK(q.out2 == r2 + 4);
CHECK(r2[0].i == 2);
CHECK(r2[1].i == 4);
CHECK(r2[2].i == 6);
CHECK(r2[3].i == 8);
}
constexpr bool test_constexpr()
{
using namespace ranges;
const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
int r1[10] = {0};
int r2[10] = {0};
const auto p = partition_copy(ia, r1, r2, is_odd());
STATIC_CHECK_RETURN(p.in == std::end(ia));
STATIC_CHECK_RETURN(p.out1 == r1 + 4);
STATIC_CHECK_RETURN(r1[0] == 1);
STATIC_CHECK_RETURN(r1[1] == 3);
STATIC_CHECK_RETURN(r1[2] == 5);
STATIC_CHECK_RETURN(r1[3] == 7);
STATIC_CHECK_RETURN(p.out2 == r2 + 4);
STATIC_CHECK_RETURN(r2[0] == 2);
STATIC_CHECK_RETURN(r2[1] == 4);
STATIC_CHECK_RETURN(r2[2] == 6);
STATIC_CHECK_RETURN(r2[3] == 8);
return true;
}
int main()
{
test_iter<InputIterator<const int*> >();
test_iter<InputIterator<const int*>, Sentinel<const int*>>();
test_range<InputIterator<const int*> >();
test_range<InputIterator<const int*>, Sentinel<const int*>>();
test_proj();
test_rvalue();
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,70 @@
// Range v3 library
//
// Copyright Eric Niebler 2014
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <tuple>
#include <range/v3/algorithm/partition_move.hpp>
#include <range/v3/core.hpp>
#include "../simple_test.hpp"
struct is_odd
{
constexpr bool operator()(const int & i) const
{
return i & 1;
}
};
constexpr bool test_constexpr()
{
using namespace ranges;
const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
int r1[10] = {0};
int r2[10] = {0};
typedef std::tuple<int const *, int *, int *> P;
P p = partition_move(ia, r1, r2, is_odd());
STATIC_CHECK_RETURN(std::get<0>(p) == std::end(ia));
STATIC_CHECK_RETURN(std::get<1>(p) == r1 + 4);
STATIC_CHECK_RETURN(r1[0] == 1);
STATIC_CHECK_RETURN(r1[1] == 3);
STATIC_CHECK_RETURN(r1[2] == 5);
STATIC_CHECK_RETURN(r1[3] == 7);
STATIC_CHECK_RETURN(std::get<2>(p) == r2 + 4);
STATIC_CHECK_RETURN(r2[0] == 2);
STATIC_CHECK_RETURN(r2[1] == 4);
STATIC_CHECK_RETURN(r2[2] == 6);
STATIC_CHECK_RETURN(r2[3] == 8);
return true;
}
int main()
{
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,238 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/partition_point.hpp>
#include <range/v3/view/counted.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
#include "../array.hpp"
struct is_odd
{
constexpr bool operator()(const int & i) const
{
return i & 1;
}
};
template<class Iter, class Sent = Iter>
void
test_iter()
{
{
const int ia[] = {2, 4, 6, 8, 10};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia));
}
{
const int ia[] = {1, 2, 4, 6, 8};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia + 1));
}
{
const int ia[] = {1, 3, 2, 4, 6};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia + 2));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia + 3));
}
{
const int ia[] = {1, 3, 5, 7, 2, 4};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia + 4));
}
{
const int ia[] = {1, 3, 5, 7, 9, 2};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia + 5));
}
{
const int ia[] = {1, 3, 5, 7, 9, 11};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)),
is_odd()) == Iter(ia + 6));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
Sent(ranges::begin(ia)),
is_odd()) == Iter(ia));
}
}
template<class Iter, class Sent = Iter>
void
test_range()
{
{
const int ia[] = {2, 4, 6, 8, 10};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia));
}
{
const int ia[] = {1, 2, 4, 6, 8};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia + 1));
}
{
const int ia[] = {1, 3, 2, 4, 6};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia + 2));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia + 3));
}
{
const int ia[] = {1, 3, 5, 7, 2, 4};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia + 4));
}
{
const int ia[] = {1, 3, 5, 7, 9, 2};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia + 5));
}
{
const int ia[] = {1, 3, 5, 7, 9, 11};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia)))),
is_odd()) == Iter(ia + 6));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::begin(ia)))),
is_odd()) == Iter(ia));
}
// An rvalue range
{
const int ia[] = {1, 3, 5, 7, 9, 2};
CHECK(ranges::partition_point(ranges::make_subrange(Iter(ranges::begin(ia)),
Sent(ranges::end(ia))),
is_odd()) == Iter(ia + 5));
}
}
template<class Iter>
void
test_counted()
{
{
const int ia[] = {2, 4, 6, 8, 10};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia), ranges::size(ia)));
}
{
const int ia[] = {1, 2, 4, 6, 8};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 1), ranges::size(ia) - 1));
}
{
const int ia[] = {1, 3, 2, 4, 6};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 2), ranges::size(ia) - 2));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 3), ranges::size(ia) - 3));
}
{
const int ia[] = {1, 3, 5, 7, 2, 4};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 4), ranges::size(ia) - 4));
}
{
const int ia[] = {1, 3, 5, 7, 9, 2};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 5), ranges::size(ia) - 5));
}
{
const int ia[] = {1, 3, 5, 7, 9, 11};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
ranges::size(ia))),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 6), ranges::size(ia) - 6));
}
{
const int ia[] = {1, 3, 5, 2, 4, 6, 7};
CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
0)),
is_odd()) == ranges::counted_iterator<Iter>(Iter(ia), 0));
}
}
struct S
{
int i;
};
int main()
{
test_iter<ForwardIterator<const int*> >();
test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
test_range<ForwardIterator<const int*> >();
test_range<ForwardIterator<const int*>, Sentinel<const int*>>();
test_counted<ForwardIterator<const int*> >();
// Test projections
const S ia[] = {S{1}, S{3}, S{5}, S{2}, S{4}, S{6}};
CHECK(ranges::partition_point(ia, is_odd(), &S::i) == ia + 3);
{
constexpr test::array<int, 6> a{{1, 3, 5, 2, 4, 6}};
STATIC_CHECK(ranges::partition_point(a, is_odd()) == ranges::begin(a) + 3);
}
return ::test_result();
}

View File

@@ -0,0 +1,293 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <random>
#include <algorithm>
#include <functional>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/heap_algorithm.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
void test_1(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ia, ia+i) == ia+i);
CHECK(std::is_heap(ia, ia+i-1));
}
CHECK(ranges::pop_heap(ia, ia) == ia);
delete[] ia;
}
void test_2(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia+i)) == ia+i);
CHECK(std::is_heap(ia, ia+i-1));
}
CHECK(ranges::pop_heap(ia, ia) == ia);
delete[] ia;
}
void test_3(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, ia+i))) == ia+i);
CHECK(std::is_heap(ia, ia+i-1));
}
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ranges::make_subrange(ia, ia+i)) == ia+i);
CHECK(std::is_heap(ia, ia+i-1));
}
CHECK(ranges::pop_heap(ia, ia) == ia);
delete[] ia;
}
void test_4(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, Sentinel<int*>(ia+i)))) == ia+i);
CHECK(std::is_heap(ia, ia+i-1));
}
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ranges::make_subrange(ia, Sentinel<int*>(ia+i))) == ia+i);
CHECK(std::is_heap(ia, ia+i-1));
}
CHECK(ranges::pop_heap(ia, ia) == ia);
delete[] ia;
}
void test_5(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, std::greater<int>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ia, ia+i, std::greater<int>()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
}
CHECK(ranges::pop_heap(ia, ia, std::greater<int>()) == ia);
delete[] ia;
}
void test_6(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, std::greater<int>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia+i), std::greater<int>()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
}
CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia), std::greater<int>()) == ia);
delete[] ia;
}
void test_7(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, std::greater<int>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, ia+i)), std::greater<int>()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
}
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, std::greater<int>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ranges::make_subrange(ia, ia+i), std::greater<int>()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
}
CHECK(ranges::pop_heap(ia, ia, std::greater<int>()) == ia);
delete[] ia;
}
void test_8(int N)
{
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, std::greater<int>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(::as_lvalue(ranges::make_subrange(ia, Sentinel<int*>(ia+i))), std::greater<int>()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
}
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, std::greater<int>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ranges::make_subrange(ia, Sentinel<int*>(ia+i)), std::greater<int>()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));
}
CHECK(ranges::pop_heap(ia, Sentinel<int*>(ia), std::greater<int>()) == ia);
delete[] ia;
}
struct indirect_less
{
template<class P>
bool operator()(const P& x, const P& y)
{return *x < *y;}
};
void test_9(int N)
{
std::unique_ptr<int>* ia = new std::unique_ptr<int>[N];
for (int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N, indirect_less());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ia, ia+i, indirect_less()) == ia+i);
CHECK(std::is_heap(ia, ia+i-1, indirect_less()));
}
delete[] ia;
}
template<typename T>
struct construct
{
template<typename ...Us>
T operator()(Us &&... us) const
{
return T{((Us &&)us)...};
}
};
struct S
{
int i;
};
void test_10(int N)
{
int* ia = new int[N];
S* ib = new S[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
std::make_heap(ia, ia+N);
std::transform(ia, ia+N, ib, construct<S>());
for (int i = N; i > 0; --i)
{
CHECK(ranges::pop_heap(ib, ib+i, std::less<int>(), &S::i) == ib+i);
std::transform(ib, ib+i, ia, std::mem_fn(&S::i));
CHECK(std::is_heap(ia, ia+i-1));
}
CHECK(ranges::pop_heap(ib, ib, std::less<int>(), &S::i) == ib);
delete[] ia;
delete[] ib;
}
}
constexpr bool test_constexpr()
{
using namespace ranges;
constexpr int N = 100;
test::array<int, N> ia{{0}};
for(int i = 0; i < N; ++i)
ia[i] = i;
make_heap(ia);
for(int i = N; i > 0; --i)
{
STATIC_CHECK_RETURN(pop_heap(make_subrange(begin(ia), begin(ia) + i), less{}) == begin(ia) + i);
STATIC_CHECK_RETURN(is_heap(begin(ia), begin(ia) + i - 1));
}
STATIC_CHECK_RETURN(pop_heap(make_subrange(begin(ia), begin(ia)), less{}) == begin(ia));
return true;
}
int main()
{
test_1(1000);
test_2(1000);
test_3(1000);
test_4(1000);
test_5(1000);
test_6(1000);
test_7(1000);
test_8(1000);
test_9(1000);
test_10(1000);
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,236 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstring>
#include <utility>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/permutation.hpp>
#include <range/v3/algorithm/equal.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
int factorial(int x)
{
int r = 1;
for (; x; --x)
r *= x;
return r;
}
template<typename Iter, typename Sent = Iter>
void test_iter()
{
int ia[] = {6, 5, 4, 3, 2, 1};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for (int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::prev_permutation(Iter(ia), Sent(ia+e));
if(e > 1)
{
if(!x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));
}
++count;
} while(x);
CHECK(count == factorial(e));
}
}
template<typename Iter, typename Sent = Iter>
void test_range()
{
int ia[] = {6, 5, 4, 3, 2, 1};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for (int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::prev_permutation(ranges::make_subrange(Iter(ia), Sent(ia+e)));
if(e > 1)
{
if(!x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));
}
++count;
} while(x);
CHECK(count == factorial(e));
}
}
template<typename Iter, typename Sent = Iter>
void test_iter_comp()
{
typedef std::greater<int> C;
int ia[] = {1, 2, 3, 4, 5, 6};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for(int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::prev_permutation(Iter(ia), Sent(ia+e), C());
if(e > 1)
{
if(!x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));
}
++count;
} while (x);
CHECK(count == factorial(e));
}
}
template<typename Iter, typename Sent = Iter>
void test_range_comp()
{
typedef std::greater<int> C;
int ia[] = {1, 2, 3, 4, 5, 6};
const int sa = sizeof(ia)/sizeof(ia[0]);
int prev[sa];
for(int e = 0; e <= sa; ++e)
{
int count = 0;
bool x;
do
{
std::copy(ia, ia+e, prev);
x = ranges::prev_permutation(ranges::make_subrange(Iter(ia), Sent(ia+e)), C());
if(e > 1)
{
if(!x)
CHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));
else
CHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));
}
++count;
} while (x);
CHECK(count == factorial(e));
}
}
struct c_str
{
char const * value;
friend bool operator==(c_str a, c_str b)
{
return 0 == std::strcmp(a.value, b.value);
}
friend bool operator!=(c_str a, c_str b)
{
return !(a == b);
}
};
// For debugging the projection test
std::ostream &operator<<(std::ostream& sout, std::pair<int, c_str> p)
{
return sout << "{" << p.first << "," << p.second.value << "}";
}
constexpr bool test_constexpr()
{
using namespace ranges;
using IL = std::initializer_list<int>;
int ia[] = {6, 5, 4, 3, 2, 1};
prev_permutation(ia);
STATIC_CHECK_RETURN(equal(ia, IL{6, 5, 4, 3, 1, 2}));
prev_permutation(ia);
STATIC_CHECK_RETURN(equal(ia, IL{6, 5, 4, 2, 3, 1}));
prev_permutation(ia);
STATIC_CHECK_RETURN(equal(ia, IL{6, 5, 4, 2, 1, 3}));
return true;
}
int main()
{
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter<RandomAccessIterator<int*>, Sentinel<int*> >();
test_iter_comp<BidirectionalIterator<int*> >();
test_iter_comp<RandomAccessIterator<int*> >();
test_iter_comp<int*>();
test_iter_comp<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter_comp<RandomAccessIterator<int*>, Sentinel<int*> >();
test_range<BidirectionalIterator<int*> >();
test_range<RandomAccessIterator<int*> >();
test_range<int*>();
test_range<BidirectionalIterator<int*>, Sentinel<int*> >();
test_range<RandomAccessIterator<int*>, Sentinel<int*> >();
test_range_comp<BidirectionalIterator<int*> >();
test_range_comp<RandomAccessIterator<int*> >();
test_range_comp<int*>();
test_range_comp<BidirectionalIterator<int*>, Sentinel<int*> >();
test_range_comp<RandomAccessIterator<int*>, Sentinel<int*> >();
// Test projection
using C = std::less<int>;
using I = std::initializer_list<std::pair<int, c_str>>;
std::pair<int, c_str> ia[] = {{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {3,{"three"}}, {2,{"two"}}, {1,{"one"}}};
CHECK(ranges::prev_permutation(ia, C(), &std::pair<int,c_str>::first));
::check_equal(ia, I{{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {3,{"three"}}, {1,{"one"}}, {2,{"two"}}});
CHECK(ranges::prev_permutation(ia, C(), &std::pair<int,c_str>::first));
::check_equal(ia, I{{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {2,{"two"}}, {3,{"three"}}, {1,{"one"}}});
CHECK(ranges::prev_permutation(ia, C(), &std::pair<int,c_str>::first));
::check_equal(ia, I{{6, {"six"}}, {5,{"five"}}, {4,{"four"}}, {2,{"two"}}, {1,{"one"}}, {3,{"three"}}});
// etc..
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,176 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <algorithm>
// template<random_access_iterator Iter>
// requires ShuffleIterator<Iter>
// && LessThanComparable<Iter::value_type>
// void
// push_heap(Iter first, Iter last);
#include <memory>
#include <random>
#include <algorithm>
#include <functional>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/heap_algorithm.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
namespace
{
std::mt19937 gen;
void test_basic(int N)
{
auto push_heap = make_testable_1(ranges::push_heap);
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
for (int i = 0; i <= N; ++i)
{
push_heap(ia, ia+i).check([&](int *r){CHECK(r == ia + i);});
CHECK(std::is_heap(ia, ia+i));
}
delete[] ia;
}
void test_comp(int N)
{
auto push_heap = make_testable_1(ranges::push_heap);
int* ia = new int[N];
for (int i = 0; i < N; ++i)
ia[i] = i;
std::shuffle(ia, ia+N, gen);
for (int i = 0; i <= N; ++i)
{
push_heap(ia, ia+i, std::greater<int>()).check([&](int *r){CHECK(r == ia+i);});
CHECK(std::is_heap(ia, ia+i, std::greater<int>()));
}
delete[] ia;
}
struct S
{
int i;
};
void test_proj(int N)
{
auto push_heap = make_testable_1(ranges::push_heap);
S* ia = new S[N];
int* ib = new int[N];
for (int i = 0; i < N; ++i)
ia[i].i = i;
std::shuffle(ia, ia+N, gen);
for (int i = 0; i <= N; ++i)
{
push_heap(ia, ia+i, std::greater<int>(), &S::i).check([&](S *r){CHECK(r == ia+i);});
std::transform(ia, ia+i, ib, std::mem_fn(&S::i));
CHECK(std::is_heap(ib, ib+i, std::greater<int>()));
}
delete[] ia;
delete[] ib;
}
struct indirect_less
{
template<class P>
bool operator()(const P& x, const P& y)
{return *x < *y;}
};
void test_move_only(int N)
{
auto const push_heap = make_testable_1(ranges::push_heap);
std::unique_ptr<int>* ia = new std::unique_ptr<int>[N];
for (int i = 0; i < N; ++i)
ia[i].reset(new int(i));
std::shuffle(ia, ia+N, gen);
for (int i = 0; i <= N; ++i)
{
push_heap(ia, ia+i, indirect_less()).check([&](std::unique_ptr<int> *r){CHECK(r == ia+i);});
CHECK(std::is_heap(ia, ia+i, indirect_less()));
}
delete[] ia;
}
}
constexpr bool test_constexpr()
{
using namespace ranges;
constexpr int N = 100;
test::array<int, N> ia{{0}};
for(int i = 0; i < N; ++i)
ia[i] = i;
for(int i = 0; i <= N; ++i)
{
STATIC_CHECK_RETURN(push_heap(make_subrange(begin(ia), begin(ia) + i),
std::greater<int>()) == begin(ia) + i);
STATIC_CHECK_RETURN(is_heap(begin(ia), begin(ia) + i, std::greater<int>()));
}
return true;
}
int main()
{
test_basic(1000);
test_comp(1000);
test_proj(1000);
test_move_only(1000);
{
int const N = 1000;
S* ia = new S[N];
int* ib = new int[N];
for (int i = 0; i < N; ++i)
ia[i].i = i;
std::shuffle(ia, ia+N, gen);
for (int i = 0; i <= N; ++i)
{
CHECK(ranges::push_heap(ranges::make_subrange(ia, ia+i), std::greater<int>(), &S::i) == ia+i);
std::transform(ia, ia+i, ib, std::mem_fn(&S::i));
CHECK(std::is_heap(ib, ib+i, std::greater<int>()));
}
delete[] ia;
delete[] ib;
}
{
STATIC_CHECK(test_constexpr());
}
return test_result();
}

View File

@@ -0,0 +1,205 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/remove.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, class Sent = Iter>
void
test_iter()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
Iter r = ranges::remove(Iter(ia), Sent(ia+sa), 2);
CHECK(base(r) == ia + sa-3);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 3);
CHECK(ia[3] == 4);
CHECK(ia[4] == 3);
CHECK(ia[5] == 4);
}
template<class Iter, class Sent = Iter>
void
test_range()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
Iter r = ranges::remove(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 2);
CHECK(base(r) == ia + sa-3);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 3);
CHECK(ia[3] == 4);
CHECK(ia[4] == 3);
CHECK(ia[5] == 4);
}
template<class Iter, class Sent = Iter>
void
test_iter_rvalue()
{
constexpr unsigned sa = 9;
std::unique_ptr<int> ia[sa];
ia[0].reset(new int(0));
ia[1].reset(new int(1));
ia[3].reset(new int(3));
ia[4].reset(new int(4));
ia[6].reset(new int(3));
ia[7].reset(new int(4));
Iter r = ranges::remove(Iter(ia), Sent(ia+sa), std::unique_ptr<int>());
CHECK(base(r) == ia + sa-3);
CHECK(*ia[0] == 0);
CHECK(*ia[1] == 1);
CHECK(*ia[2] == 3);
CHECK(*ia[3] == 4);
CHECK(*ia[4] == 3);
CHECK(*ia[5] == 4);
}
template<class Iter, class Sent = Iter>
void
test_range_rvalue()
{
constexpr unsigned sa = 9;
std::unique_ptr<int> ia[sa];
ia[0].reset(new int(0));
ia[1].reset(new int(1));
ia[3].reset(new int(3));
ia[4].reset(new int(4));
ia[6].reset(new int(3));
ia[7].reset(new int(4));
Iter r = ranges::remove(ranges::make_subrange(Iter(ia), Sent(ia+sa)), std::unique_ptr<int>());
CHECK(base(r) == ia + sa-3);
CHECK(*ia[0] == 0);
CHECK(*ia[1] == 1);
CHECK(*ia[2] == 3);
CHECK(*ia[3] == 4);
CHECK(*ia[4] == 3);
CHECK(*ia[5] == 4);
}
struct S
{
int i;
};
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
auto r = ranges::remove(ia, 2);
STATIC_CHECK_RETURN(r == ia + sa - 3);
STATIC_CHECK_RETURN(ia[0] == 0);
STATIC_CHECK_RETURN(ia[1] == 1);
STATIC_CHECK_RETURN(ia[2] == 3);
STATIC_CHECK_RETURN(ia[3] == 4);
STATIC_CHECK_RETURN(ia[4] == 3);
STATIC_CHECK_RETURN(ia[5] == 4);
return true;
}
int main()
{
test_iter<ForwardIterator<int*> >();
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<ForwardIterator<int*>, Sentinel<int*>>();
test_iter<BidirectionalIterator<int*>, Sentinel<int*>>();
test_iter<RandomAccessIterator<int*>, Sentinel<int*>>();
test_range<ForwardIterator<int*> >();
test_range<BidirectionalIterator<int*> >();
test_range<RandomAccessIterator<int*> >();
test_range<int*>();
test_range<ForwardIterator<int*>, Sentinel<int*>>();
test_range<BidirectionalIterator<int*>, Sentinel<int*>>();
test_range<RandomAccessIterator<int*>, Sentinel<int*>>();
test_iter_rvalue<ForwardIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<BidirectionalIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<RandomAccessIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<std::unique_ptr<int>*>();
test_iter_rvalue<ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_iter_rvalue<BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_iter_rvalue<RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<ForwardIterator<std::unique_ptr<int>*> >();
test_range_rvalue<BidirectionalIterator<std::unique_ptr<int>*> >();
test_range_rvalue<RandomAccessIterator<std::unique_ptr<int>*> >();
test_range_rvalue<std::unique_ptr<int>*>();
test_range_rvalue<ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
// Check projection
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
S* r = ranges::remove(ia, 2, &S::i);
CHECK(r == ia + sa-3);
CHECK(ia[0].i == 0);
CHECK(ia[1].i == 1);
CHECK(ia[2].i == 3);
CHECK(ia[3].i == 4);
CHECK(ia[4].i == 3);
CHECK(ia[5].i == 4);
// Check rvalue ranges
S ia2[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
auto r2 = ranges::remove(std::move(ia2), 2, &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(r2));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(ia2[0].i == 0);
CHECK(ia2[1].i == 1);
CHECK(ia2[2].i == 3);
CHECK(ia2[3].i == 4);
CHECK(ia2[4].i == 3);
CHECK(ia2[5].i == 4);
std::vector<S> vec{S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
auto r3 = ranges::remove(std::move(vec), 2, &S::i);
CHECK(::is_dangling(r3));
CHECK(vec[0].i == 0);
CHECK(vec[1].i == 1);
CHECK(vec[2].i == 3);
CHECK(vec[3].i == 4);
CHECK(vec[4].i == 3);
CHECK(vec[5].i == 4);
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,210 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <memory>
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/remove_copy.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class InIter, class OutIter, class Sent = InIter>
void
test_iter()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
int ib[sa];
ranges::remove_copy_result<InIter, OutIter> r = ranges::remove_copy(InIter(ia), Sent(ia+sa), OutIter(ib), 2);
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa-3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 3);
CHECK(ib[3] == 4);
CHECK(ib[4] == 3);
CHECK(ib[5] == 4);
}
template<class InIter, class OutIter, class Sent = InIter>
void
test_range()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
int ib[sa];
ranges::remove_copy_result<InIter, OutIter> r = ranges::remove_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+sa))), OutIter(ib), 2);
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa-3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 3);
CHECK(ib[3] == 4);
CHECK(ib[4] == 3);
CHECK(ib[5] == 4);
}
template<class InIter, class OutIter, class Sent = InIter>
void
test()
{
test_iter<InIter, OutIter, Sent>();
test_range<InIter, OutIter, Sent>();
}
struct S
{
int i;
};
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
int ib[6] = {0};
constexpr auto sa = ranges::size(ia);
auto r = ranges::remove_copy(ia, ib, 2);
STATIC_CHECK_RETURN(r.in == ia + sa);
STATIC_CHECK_RETURN(r.out == ib + (sa - 3));
STATIC_CHECK_RETURN(ib[0] == 0);
STATIC_CHECK_RETURN(ib[1] == 1);
STATIC_CHECK_RETURN(ib[2] == 3);
STATIC_CHECK_RETURN(ib[3] == 4);
STATIC_CHECK_RETURN(ib[4] == 3);
STATIC_CHECK_RETURN(ib[5] == 4);
return true;
}
int main()
{
test<InputIterator<const int*>, OutputIterator<int*>>();
test<InputIterator<const int*>, ForwardIterator<int*>>();
test<InputIterator<const int*>, BidirectionalIterator<int*>>();
test<InputIterator<const int*>, RandomAccessIterator<int*>>();
test<InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, OutputIterator<int*>>();
test<ForwardIterator<const int*>, ForwardIterator<int*>>();
test<ForwardIterator<const int*>, BidirectionalIterator<int*>>();
test<ForwardIterator<const int*>, RandomAccessIterator<int*>>();
test<ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*>>();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>>();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*>>();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>>();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*>>();
test<const int*, ForwardIterator<int*>>();
test<const int*, BidirectionalIterator<int*>>();
test<const int*, RandomAccessIterator<int*>>();
test<const int*, int*>();
test<InputIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, int*, Sentinel<const int*>>();
test<ForwardIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, int*, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, int*, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, int*, Sentinel<const int*>>();
// Check projection
{
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
S ib[sa];
ranges::remove_copy_result<S*, S*> r = ranges::remove_copy(ia, ib, 2, &S::i);
CHECK(r.in == ia + sa);
CHECK(r.out == ib + sa-3);
CHECK(ib[0].i == 0);
CHECK(ib[1].i == 1);
CHECK(ib[2].i == 3);
CHECK(ib[3].i == 4);
CHECK(ib[4].i == 3);
CHECK(ib[5].i == 4);
}
// Check rvalue range
{
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
S ib[sa] = {};
auto r0 = ranges::remove_copy(std::move(ia), ib, 2, &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
static_assert(std::is_same<decltype(r0),
ranges::remove_copy_result<ranges::dangling, S *>>::value, "");
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(r0.out == ib + sa-3);
CHECK(ib[0].i == 0);
CHECK(ib[1].i == 1);
CHECK(ib[2].i == 3);
CHECK(ib[3].i == 4);
CHECK(ib[4].i == 3);
CHECK(ib[5].i == 4);
std::fill(ranges::begin(ib), ranges::end(ib), S{});
std::vector<S> vec(ranges::begin(ia), ranges::end(ia));
auto r1 = ranges::remove_copy(std::move(vec), ib, 2, &S::i);
static_assert(std::is_same<decltype(r1),
ranges::remove_copy_result<ranges::dangling, S *>>::value, "");
CHECK(r1.out == ib + sa-3);
CHECK(ib[0].i == 0);
CHECK(ib[1].i == 1);
CHECK(ib[2].i == 3);
CHECK(ib[3].i == 4);
CHECK(ib[4].i == 3);
CHECK(ib[5].i == 4);
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,214 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <functional>
#include <memory>
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/remove_copy_if.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class InIter, class OutIter, class Sent = InIter>
void
test_iter()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
int ib[sa];
ranges::remove_copy_if_result<InIter, OutIter> r = ranges::remove_copy_if(InIter(ia), Sent(ia+sa), OutIter(ib), [](int i){return i == 2;});
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa-3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 3);
CHECK(ib[3] == 4);
CHECK(ib[4] == 3);
CHECK(ib[5] == 4);
}
template<class InIter, class OutIter, class Sent = InIter>
void
test_range()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
int ib[sa];
ranges::remove_copy_if_result<InIter, OutIter> r = ranges::remove_copy_if(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+sa))), OutIter(ib), [](int i){return i == 2;});
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa-3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 3);
CHECK(ib[3] == 4);
CHECK(ib[4] == 3);
CHECK(ib[5] == 4);
}
template<class InIter, class OutIter, class Sent = InIter>
void
test()
{
test_iter<InIter, OutIter, Sent>();
test_range<InIter, OutIter, Sent>();
}
struct S
{
int i;
};
constexpr bool equals_two(int i)
{
return i == 2;
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
int ib[6] = {0};
constexpr auto sa = ranges::size(ia);
auto r = ranges::remove_copy_if(ia, ib, equals_two);
STATIC_CHECK_RETURN(r.in == ia + sa);
STATIC_CHECK_RETURN(r.out == ib + (sa - 3));
STATIC_CHECK_RETURN(ib[0] == 0);
STATIC_CHECK_RETURN(ib[1] == 1);
STATIC_CHECK_RETURN(ib[2] == 3);
STATIC_CHECK_RETURN(ib[3] == 4);
STATIC_CHECK_RETURN(ib[4] == 3);
STATIC_CHECK_RETURN(ib[5] == 4);
return true;
}
int main()
{
test<InputIterator<const int*>, OutputIterator<int*>>();
test<InputIterator<const int*>, ForwardIterator<int*>>();
test<InputIterator<const int*>, BidirectionalIterator<int*>>();
test<InputIterator<const int*>, RandomAccessIterator<int*>>();
test<InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, OutputIterator<int*>>();
test<ForwardIterator<const int*>, ForwardIterator<int*>>();
test<ForwardIterator<const int*>, BidirectionalIterator<int*>>();
test<ForwardIterator<const int*>, RandomAccessIterator<int*>>();
test<ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*>>();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>>();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*>>();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>>();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*>>();
test<const int*, ForwardIterator<int*>>();
test<const int*, BidirectionalIterator<int*>>();
test<const int*, RandomAccessIterator<int*>>();
test<const int*, int*>();
test<InputIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<InputIterator<const int*>, int*, Sentinel<const int*>>();
test<ForwardIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<ForwardIterator<const int*>, int*, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<BidirectionalIterator<const int*>, int*, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, OutputIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*>>();
test<RandomAccessIterator<const int*>, int*, Sentinel<const int*>>();
// Check projection
{
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
S ib[sa];
ranges::remove_copy_if_result<S*, S*> r = ranges::remove_copy_if(ia, ib, [](int i){return i == 2;}, &S::i);
CHECK(r.in == ia + sa);
CHECK(r.out == ib + sa-3);
CHECK(ib[0].i == 0);
CHECK(ib[1].i == 1);
CHECK(ib[2].i == 3);
CHECK(ib[3].i == 4);
CHECK(ib[4].i == 3);
CHECK(ib[5].i == 4);
}
// Check rvalue range
{
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
S ib[sa] = {};
auto r0 = ranges::remove_copy_if(std::move(ia), ib, [](int i){return i == 2;}, &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(r0.in));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(r0.out == ib + sa-3);
CHECK(ib[0].i == 0);
CHECK(ib[1].i == 1);
CHECK(ib[2].i == 3);
CHECK(ib[3].i == 4);
CHECK(ib[4].i == 3);
CHECK(ib[5].i == 4);
std::fill(ranges::begin(ib), ranges::end(ib), S{});
std::vector<S> vec(ranges::begin(ia), ranges::end(ia));
auto r1 = ranges::remove_copy_if(std::move(vec), ib, [](int i){return i == 2;}, &S::i);
CHECK(::is_dangling(r1.in));
CHECK(r1.out == ib + sa-3);
CHECK(ib[0].i == 0);
CHECK(ib[1].i == 1);
CHECK(ib[2].i == 3);
CHECK(ib[3].i == 4);
CHECK(ib[4].i == 3);
CHECK(ib[5].i == 4);
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,231 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <functional>
#include <iostream>
#include <memory>
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/remove_if.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, class Sent = Iter>
void
test_iter()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
using namespace std::placeholders;
Iter r = ranges::remove_if(Iter(ia), Sent(ia+sa), std::bind(std::equal_to<int>(), _1, 2));
CHECK(base(r) == ia + sa-3);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 3);
CHECK(ia[3] == 4);
CHECK(ia[4] == 3);
CHECK(ia[5] == 4);
}
template<class Iter, class Sent = Iter>
void
test_range()
{
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
using namespace std::placeholders;
Iter r = ranges::remove_if(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), std::bind(std::equal_to<int>(), _1, 2));
CHECK(base(r) == ia + sa-3);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 3);
CHECK(ia[3] == 4);
CHECK(ia[4] == 3);
CHECK(ia[5] == 4);
}
struct pred
{
bool operator()(const std::unique_ptr<int>& i) {return *i == 2;}
};
template<class Iter, class Sent = Iter>
void
test_iter_rvalue()
{
constexpr unsigned sa = 9;
std::unique_ptr<int> ia[sa];
ia[0].reset(new int(0));
ia[1].reset(new int(1));
ia[2].reset(new int(2));
ia[3].reset(new int(3));
ia[4].reset(new int(4));
ia[5].reset(new int(2));
ia[6].reset(new int(3));
ia[7].reset(new int(4));
ia[8].reset(new int(2));
Iter r = ranges::remove_if(Iter(ia), Sent(ia+sa), pred());
CHECK(base(r) == ia + sa-3);
CHECK(*ia[0] == 0);
CHECK(*ia[1] == 1);
CHECK(*ia[2] == 3);
CHECK(*ia[3] == 4);
CHECK(*ia[4] == 3);
CHECK(*ia[5] == 4);
}
template<class Iter, class Sent = Iter>
void
test_range_rvalue()
{
constexpr unsigned sa = 9;
std::unique_ptr<int> ia[sa];
ia[0].reset(new int(0));
ia[1].reset(new int(1));
ia[2].reset(new int(2));
ia[3].reset(new int(3));
ia[4].reset(new int(4));
ia[5].reset(new int(2));
ia[6].reset(new int(3));
ia[7].reset(new int(4));
ia[8].reset(new int(2));
Iter r = ranges::remove_if(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))), pred());
CHECK(base(r) == ia + sa-3);
CHECK(*ia[0] == 0);
CHECK(*ia[1] == 1);
CHECK(*ia[2] == 3);
CHECK(*ia[3] == 4);
CHECK(*ia[4] == 3);
CHECK(*ia[5] == 4);
}
struct S
{
int i;
};
constexpr bool equals_two(int i)
{
return i == 2;
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};
constexpr auto sa = ranges::size(ia);
auto r = ranges::remove_if(ia, equals_two);
STATIC_CHECK_RETURN(r == ia + sa - 3);
STATIC_CHECK_RETURN(ia[0] == 0);
STATIC_CHECK_RETURN(ia[1] == 1);
STATIC_CHECK_RETURN(ia[2] == 3);
STATIC_CHECK_RETURN(ia[3] == 4);
STATIC_CHECK_RETURN(ia[4] == 3);
STATIC_CHECK_RETURN(ia[5] == 4);
return true;
}
int main()
{
test_iter<ForwardIterator<int*> >();
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<ForwardIterator<int*>, Sentinel<int*>>();
test_iter<BidirectionalIterator<int*>, Sentinel<int*>>();
test_iter<RandomAccessIterator<int*>, Sentinel<int*>>();
test_range<ForwardIterator<int*> >();
test_range<BidirectionalIterator<int*> >();
test_range<RandomAccessIterator<int*> >();
test_range<int*>();
test_range<ForwardIterator<int*>, Sentinel<int*>>();
test_range<BidirectionalIterator<int*>, Sentinel<int*>>();
test_range<RandomAccessIterator<int*>, Sentinel<int*>>();
test_iter_rvalue<ForwardIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<BidirectionalIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<RandomAccessIterator<std::unique_ptr<int>*> >();
test_iter_rvalue<std::unique_ptr<int>*>();
test_iter_rvalue<ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_iter_rvalue<BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_iter_rvalue<RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<ForwardIterator<std::unique_ptr<int>*> >();
test_range_rvalue<BidirectionalIterator<std::unique_ptr<int>*> >();
test_range_rvalue<RandomAccessIterator<std::unique_ptr<int>*> >();
test_range_rvalue<std::unique_ptr<int>*>();
test_range_rvalue<ForwardIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<BidirectionalIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
test_range_rvalue<RandomAccessIterator<std::unique_ptr<int>*>, Sentinel<std::unique_ptr<int>*>>();
{
// Check projection
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
constexpr auto sa = ranges::size(ia);
using namespace std::placeholders;
S* r = ranges::remove_if(ia, std::bind(std::equal_to<int>(), _1, 2), &S::i);
CHECK(r == ia + sa-3);
CHECK(ia[0].i == 0);
CHECK(ia[1].i == 1);
CHECK(ia[2].i == 3);
CHECK(ia[3].i == 4);
CHECK(ia[4].i == 3);
CHECK(ia[5].i == 4);
}
{
// Check rvalue ranges
S ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
using namespace std::placeholders;
auto r0 = ranges::remove_if(std::move(ia), std::bind(std::equal_to<int>(), _1, 2), &S::i);
#ifndef RANGES_WORKAROUND_MSVC_573728
static_assert(std::is_same<decltype(r0), ranges::dangling>::value, "");
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(ia[0].i == 0);
CHECK(ia[1].i == 1);
CHECK(ia[2].i == 3);
CHECK(ia[3].i == 4);
CHECK(ia[4].i == 3);
CHECK(ia[5].i == 4);
std::vector<S> vec{S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};
auto r1 = ranges::remove_if(std::move(vec), std::bind(std::equal_to<int>(), _1, 2), &S::i);
static_assert(std::is_same<decltype(r1), ranges::dangling>::value, "");
CHECK(vec[0].i == 0);
CHECK(vec[1].i == 1);
CHECK(vec[2].i == 3);
CHECK(vec[3].i == 4);
CHECK(vec[4].i == 3);
CHECK(vec[5].i == 4);
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,142 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/replace.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<typename Iter, typename Sent = Iter>
void test_iter()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Iter i = ranges::replace(Iter(ia), Sent(ia+sa), 2, 5);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 5);
CHECK(ia[3] == 3);
CHECK(ia[4] == 4);
CHECK(base(i) == ia + sa);
}
template<typename Iter, typename Sent = Iter>
void test_rng()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
auto rng = ranges::make_subrange(Iter(ia), Sent(ia+sa));
Iter i = ranges::replace(rng, 2, 5);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 5);
CHECK(ia[3] == 3);
CHECK(ia[4] == 4);
CHECK(base(i) == ia + sa);
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
constexpr auto sa = ranges::size(ia);
auto r = ranges::replace(ia, 2, 42);
STATIC_CHECK_RETURN(r == ia + sa);
STATIC_CHECK_RETURN(ia[0] == 0);
STATIC_CHECK_RETURN(ia[1] == 1);
STATIC_CHECK_RETURN(ia[2] == 42);
STATIC_CHECK_RETURN(ia[3] == 3);
STATIC_CHECK_RETURN(ia[4] == 4);
return true;
}
int main()
{
test_iter<ForwardIterator<int*> >();
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<ForwardIterator<int*>, Sentinel<int*> >();
test_iter<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter<RandomAccessIterator<int*>, Sentinel<int*> >();
test_rng<ForwardIterator<int*> >();
test_rng<BidirectionalIterator<int*> >();
test_rng<RandomAccessIterator<int*> >();
test_rng<int*>();
test_rng<ForwardIterator<int*>, Sentinel<int*> >();
test_rng<BidirectionalIterator<int*>, Sentinel<int*> >();
test_rng<RandomAccessIterator<int*>, Sentinel<int*> >();
// test projection
{
using P = std::pair<int,std::string>;
P ia[] = {{0,"0"}, {1,"1"}, {2,"2"}, {3,"3"}, {4,"4"}};
P *i = ranges::replace(ia, 2, std::make_pair(42,"42"), &std::pair<int,std::string>::first);
CHECK(ia[0] == P{0,"0"});
CHECK(ia[1] == P{1,"1"});
CHECK(ia[2] == P{42,"42"});
CHECK(ia[3] == P{3,"3"});
CHECK(ia[4] == P{4,"4"});
CHECK(i == ranges::end(ia));
}
// test rvalue ranges
{
using P = std::pair<int,std::string>;
P ia[] = {{0,"0"}, {1,"1"}, {2,"2"}, {3,"3"}, {4,"4"}};
auto i = ranges::replace(std::move(ia), 2, std::make_pair(42,"42"), &std::pair<int,std::string>::first);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(i));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(ia[0] == P{0,"0"});
CHECK(ia[1] == P{1,"1"});
CHECK(ia[2] == P{42,"42"});
CHECK(ia[3] == P{3,"3"});
CHECK(ia[4] == P{4,"4"});
}
{
using P = std::pair<int,std::string>;
std::vector<P> ia{{0,"0"}, {1,"1"}, {2,"2"}, {3,"3"}, {4,"4"}};
auto i = ranges::replace(std::move(ia), 2, std::make_pair(42,"42"), &std::pair<int,std::string>::first);
CHECK(::is_dangling(i));
CHECK(ia[0] == P{0,"0"});
CHECK(ia[1] == P{1,"1"});
CHECK(ia[2] == P{42,"42"});
CHECK(ia[3] == P{3,"3"});
CHECK(ia[4] == P{4,"4"});
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,144 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/replace_copy.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class InIter, class OutIter, class Sent = InIter>
void test_iter()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[sa] = {0};
ranges::replace_copy_result<InIter, OutIter> r = ranges::replace_copy(InIter(ia), Sent(ia+sa), OutIter(ib), 2, 5);
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 5);
CHECK(ib[3] == 3);
CHECK(ib[4] == 4);
}
template<class InIter, class OutIter, class Sent = InIter>
void test_rng()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[sa] = {0};
auto rng = ranges::make_subrange(InIter(ia), Sent(ia+sa));
ranges::replace_copy_result<InIter, OutIter> r = ranges::replace_copy(rng, OutIter(ib), 2, 5);
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 5);
CHECK(ib[3] == 3);
CHECK(ib[4] == 4);
}
template<class InIter, class OutIter>
void test()
{
using Sent = typename sentinel_type<InIter>::type;
test_iter<InIter, OutIter>();
test_iter<InIter, OutIter>();
test_rng<InIter, OutIter, Sent>();
test_rng<InIter, OutIter, Sent>();
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
int ib[5] = {0};
constexpr auto sa = ranges::size(ia);
const auto r = ranges::replace_copy(ia, ib, 2, 42);
STATIC_CHECK_RETURN(r.in == ia + sa);
STATIC_CHECK_RETURN(r.out == ib + sa);
STATIC_CHECK_RETURN(ib[0] == 0);
STATIC_CHECK_RETURN(ib[1] == 1);
STATIC_CHECK_RETURN(ib[2] == 42);
STATIC_CHECK_RETURN(ib[3] == 3);
STATIC_CHECK_RETURN(ib[4] == 4);
return true;
}
int main()
{
test<InputIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*> >();
test<const int*, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<int*> >();
test<const int*, int*>();
// Test projection
{
using P = std::pair<int, std::string>;
P in[] = {{0, "0"}, {1, "1"}, {2, "2"}, {3, "3"}, {4, "4"}};
P out[ranges::size(in)] = {};
ranges::replace_copy_result<P *, P *> r = ranges::replace_copy(in, out, 2, P{5, "5"}, &std::pair<int, std::string>::first);
CHECK(r.in == ranges::end(in));
CHECK(r.out == ranges::end(out));
CHECK(out[0] == P{0, "0"});
CHECK(out[1] == P{1, "1"});
CHECK(out[2] == P{5, "5"});
CHECK(out[3] == P{3, "3"});
CHECK(out[4] == P{4, "4"});
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,152 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/replace_copy_if.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class InIter, class OutIter, class Sent = InIter>
void test_iter()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[sa] = {0};
ranges::replace_copy_if_result<InIter, OutIter> r = ranges::replace_copy_if(InIter(ia), Sent(ia+sa), OutIter(ib),
[](int i){return 2==i;}, 5);
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 5);
CHECK(ib[3] == 3);
CHECK(ib[4] == 4);
}
template<class InIter, class OutIter, class Sent = InIter>
void test_rng()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[sa] = {0};
auto rng = ranges::make_subrange(InIter(ia), Sent(ia+sa));
ranges::replace_copy_if_result<InIter, OutIter> r = ranges::replace_copy_if(rng, OutIter(ib),
[](int i){return 2==i;}, 5);
CHECK(base(r.in) == ia + sa);
CHECK(base(r.out) == ib + sa);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 5);
CHECK(ib[3] == 3);
CHECK(ib[4] == 4);
}
template<class InIter, class OutIter>
void test()
{
using Sent = typename sentinel_type<InIter>::type;
test_iter<InIter, OutIter>();
test_iter<InIter, OutIter>();
test_rng<InIter, OutIter, Sent>();
test_rng<InIter, OutIter, Sent>();
}
constexpr bool equals_two(int i)
{
return i == 2;
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
int ib[5] = {0};
constexpr auto sa = ranges::size(ia);
const auto r = ranges::replace_copy_if(ia, ib, equals_two, 42);
STATIC_CHECK_RETURN(r.in == ia + sa);
STATIC_CHECK_RETURN(r.out == ib + sa);
STATIC_CHECK_RETURN(ib[0] == 0);
STATIC_CHECK_RETURN(ib[1] == 1);
STATIC_CHECK_RETURN(ib[2] == 42);
STATIC_CHECK_RETURN(ib[3] == 3);
STATIC_CHECK_RETURN(ib[4] == 4);
return true;
}
int main()
{
test<InputIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*> >();
test<const int*, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<int*> >();
test<const int*, int*>();
// Test projection
{
using P = std::pair<int, std::string>;
P in[] = {{0, "0"}, {1, "1"}, {2, "2"}, {3, "3"}, {4, "4"}};
P out[ranges::size(in)] = {};
ranges::replace_copy_if_result<P *, P *> r = ranges::replace_copy_if(in, out,
[](int i){return 2==i;}, P{5, "5"}, &std::pair<int, std::string>::first);
CHECK(r.in == ranges::end(in));
CHECK(r.out == ranges::end(out));
CHECK(out[0] == P{0, "0"});
CHECK(out[1] == P{1, "1"});
CHECK(out[2] == P{5, "5"});
CHECK(out[3] == P{3, "3"});
CHECK(out[4] == P{4, "4"});
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,150 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/replace_if.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<typename Iter, typename Sent = Iter>
void test_iter()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Iter i = ranges::replace_if(Iter(ia), Sent(ia+sa), [](int j){return j==2;}, 5);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 5);
CHECK(ia[3] == 3);
CHECK(ia[4] == 4);
CHECK(base(i) == ia + sa);
}
template<typename Iter, typename Sent = Iter>
void test_rng()
{
int ia[] = {0, 1, 2, 3, 4};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
auto rng = ranges::make_subrange(Iter(ia), Sent(ia+sa));
Iter i = ranges::replace_if(rng, [](int j){return j==2;}, 5);
CHECK(ia[0] == 0);
CHECK(ia[1] == 1);
CHECK(ia[2] == 5);
CHECK(ia[3] == 3);
CHECK(ia[4] == 4);
CHECK(base(i) == ia + sa);
}
constexpr bool equals_two(int i)
{
return i == 2;
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
constexpr auto sa = ranges::size(ia);
auto r = ranges::replace_if(ia, equals_two, 42);
STATIC_CHECK_RETURN(r == ia + sa);
STATIC_CHECK_RETURN(ia[0] == 0);
STATIC_CHECK_RETURN(ia[1] == 1);
STATIC_CHECK_RETURN(ia[2] == 42);
STATIC_CHECK_RETURN(ia[3] == 3);
STATIC_CHECK_RETURN(ia[4] == 4);
return true;
}
int main()
{
test_iter<ForwardIterator<int*> >();
test_iter<BidirectionalIterator<int*> >();
test_iter<RandomAccessIterator<int*> >();
test_iter<int*>();
test_iter<ForwardIterator<int*>, Sentinel<int*> >();
test_iter<BidirectionalIterator<int*>, Sentinel<int*> >();
test_iter<RandomAccessIterator<int*>, Sentinel<int*> >();
test_rng<ForwardIterator<int*> >();
test_rng<BidirectionalIterator<int*> >();
test_rng<RandomAccessIterator<int*> >();
test_rng<int*>();
test_rng<ForwardIterator<int*>, Sentinel<int*> >();
test_rng<BidirectionalIterator<int*>, Sentinel<int*> >();
test_rng<RandomAccessIterator<int*>, Sentinel<int*> >();
// test projection
{
using P = std::pair<int,std::string>;
P ia[] = {{0,"0"}, {1,"1"}, {2,"2"}, {3,"3"}, {4,"4"}};
P *i = ranges::replace_if(ia, [](int j){return j==2;}, std::make_pair(42,"42"),
&std::pair<int,std::string>::first);
CHECK(ia[0] == P{0,"0"});
CHECK(ia[1] == P{1,"1"});
CHECK(ia[2] == P{42,"42"});
CHECK(ia[3] == P{3,"3"});
CHECK(ia[4] == P{4,"4"});
CHECK(i == ranges::end(ia));
}
// test rvalue ranges
{
using P = std::pair<int,std::string>;
P ia[] = {{0,"0"}, {1,"1"}, {2,"2"}, {3,"3"}, {4,"4"}};
auto i = ranges::replace_if(std::move(ia), [](int j){return j==2;}, std::make_pair(42,"42"),
&std::pair<int,std::string>::first);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(i));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(ia[0] == P{0,"0"});
CHECK(ia[1] == P{1,"1"});
CHECK(ia[2] == P{42,"42"});
CHECK(ia[3] == P{3,"3"});
CHECK(ia[4] == P{4,"4"});
}
{
using P = std::pair<int,std::string>;
std::vector<P> ia{{0,"0"}, {1,"1"}, {2,"2"}, {3,"3"}, {4,"4"}};
auto i = ranges::replace_if(std::move(ia), [](int j){return j==2;}, std::make_pair(42,"42"),
&std::pair<int,std::string>::first);
CHECK(::is_dangling(i));
CHECK(ia[0] == P{0,"0"});
CHECK(ia[1] == P{1,"1"});
CHECK(ia[2] == P{42,"42"});
CHECK(ia[3] == P{3,"3"});
CHECK(ia[4] == P{4,"4"});
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,130 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/reverse.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, class Sent = Iter>
void test()
{
// iterators
{
int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Iter i0 = ranges::reverse(Iter(ia), Sent(ia));
::check_equal(ia, {0});
CHECK(i0 == Iter(ia));
Iter i1 = ranges::reverse(Iter(ia), Sent(ia+sa));
::check_equal(ia, {0});
CHECK(i1 == Iter(ia+sa));
int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
Iter i2 = ranges::reverse(Iter(ib), Sent(ib+sb));
::check_equal(ib, {1, 0});
CHECK(i2 == Iter(ib+sb));
int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
Iter i3 = ranges::reverse(Iter(ic), Sent(ic+sc));
::check_equal(ic, {2, 1, 0});
CHECK(i3 == Iter(ic+sc));
int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
Iter i4 = ranges::reverse(Iter(id), Sent(id+sd));
::check_equal(id, {3, 2, 1, 0});
CHECK(i4 == Iter(id+sd));
}
// ranges
{
int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Iter i0 = ranges::reverse(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia))));
::check_equal(ia, {0});
CHECK(i0 == Iter(ia));
Iter i1 = ranges::reverse(::as_lvalue(ranges::make_subrange(Iter(ia), Sent(ia+sa))));
::check_equal(ia, {0});
CHECK(i1 == Iter(ia+sa));
int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
Iter i2 = ranges::reverse(::as_lvalue(ranges::make_subrange(Iter(ib), Sent(ib+sb))));
::check_equal(ib, {1, 0});
CHECK(i2 == Iter(ib+sb));
int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
Iter i3 = ranges::reverse(::as_lvalue(ranges::make_subrange(Iter(ic), Sent(ic+sc))));
::check_equal(ic, {2, 1, 0});
CHECK(i3 == Iter(ic+sc));
int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
Iter i4 = ranges::reverse(::as_lvalue(ranges::make_subrange(Iter(id), Sent(id+sd))));
::check_equal(id, {3, 2, 1, 0});
CHECK(i4 == Iter(id+sd));
// rvalue range
auto i5 = ranges::reverse(ranges::make_subrange(Iter(id), Sent(id+sd)));
::check_equal(id, {0, 1, 2, 3});
CHECK(i5 == Iter(id+sd));
}
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
constexpr auto sa = ranges::size(ia);
auto r = ranges::reverse(ia);
STATIC_CHECK_RETURN(r == ia + sa);
STATIC_CHECK_RETURN(ia[0] == 4);
STATIC_CHECK_RETURN(ia[1] == 3);
STATIC_CHECK_RETURN(ia[2] == 2);
STATIC_CHECK_RETURN(ia[3] == 1);
STATIC_CHECK_RETURN(ia[4] == 0);
return true;
}
int main()
{
test<BidirectionalIterator<int *>>();
test<RandomAccessIterator<int *>>();
test<int*>();
test<BidirectionalIterator<int *>, Sentinel<int*>>();
test<RandomAccessIterator<int *>, Sentinel<int*>>();
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,189 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstring>
#include <utility>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/reverse_copy.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, class OutIter, class Sent = Iter>
void test()
{
using P = ranges::reverse_copy_result<Iter, OutIter>;
// iterators
{
const int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ja[sa] = {-1};
P p0 = ranges::reverse_copy(Iter(ia), Sent(ia), OutIter(ja));
::check_equal(ja, {-1});
CHECK(p0.in == Iter(ia));
CHECK(base(p0.out) == ja);
P p1 = ranges::reverse_copy(Iter(ia), Sent(ia+sa), OutIter(ja));
::check_equal(ja, {0});
CHECK(p1.in == Iter(ia+sa));
CHECK(base(p1.out) == ja+sa);
const int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int jb[sb] = {-1};
P p2 = ranges::reverse_copy(Iter(ib), Sent(ib+sb), OutIter(jb));
::check_equal(jb, {1, 0});
CHECK(p2.in == Iter(ib+sb));
CHECK(base(p2.out) == jb+sb);
const int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
int jc[sc] = {-1};
P p3 = ranges::reverse_copy(Iter(ic), Sent(ic+sc), OutIter(jc));
::check_equal(jc, {2, 1, 0});
CHECK(p3.in == Iter(ic+sc));
CHECK(base(p3.out) == jc+sc);
const int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
int jd[sd] = {-1};
P p4 = ranges::reverse_copy(Iter(id), Sent(id+sd), OutIter(jd));
::check_equal(jd, {3, 2, 1, 0});
CHECK(p4.in == Iter(id+sd));
CHECK(base(p4.out) == jd+sd);
}
// ranges
{
const int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ja[sa] = {-1};
P p0 = ranges::reverse_copy(ranges::make_subrange(Iter(ia), Sent(ia)), OutIter(ja));
::check_equal(ja, {-1});
CHECK(p0.in == Iter(ia));
CHECK(base(p0.out) == ja);
P p1 = ranges::reverse_copy(ranges::make_subrange(Iter(ia), Sent(ia+sa)), OutIter(ja));
::check_equal(ja, {0});
CHECK(p1.in == Iter(ia+sa));
CHECK(base(p1.out) == ja+sa);
const int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int jb[sb] = {-1};
P p2 = ranges::reverse_copy(ranges::make_subrange(Iter(ib), Sent(ib+sb)), OutIter(jb));
::check_equal(jb, {1, 0});
CHECK(p2.in == Iter(ib+sb));
CHECK(base(p2.out) == jb+sb);
const int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
int jc[sc] = {-1};
P p3 = ranges::reverse_copy(ranges::make_subrange(Iter(ic), Sent(ic+sc)), OutIter(jc));
::check_equal(jc, {2, 1, 0});
CHECK(p3.in == Iter(ic+sc));
CHECK(base(p3.out) == jc+sc);
const int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
int jd[sd] = {-1};
P p4 = ranges::reverse_copy(ranges::make_subrange(Iter(id), Sent(id+sd)), OutIter(jd));
::check_equal(jd, {3, 2, 1, 0});
CHECK(p4.in == Iter(id+sd));
CHECK(base(p4.out) == jd+sd);
// test rvalue ranges
std::memset(jd, 0, sizeof(jd));
auto p5 = ranges::reverse_copy(::MakeTestRange(Iter(id), Sent(id+sd)), OutIter(jd));
::check_equal(jd, {3, 2, 1, 0});
CHECK(::is_dangling(p5.in));
CHECK(base(p4.out) == jd+sd);
}
}
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
int ib[5] = {0};
constexpr auto sa = ranges::size(ia);
const auto r = ranges::reverse_copy(ia, ib);
STATIC_CHECK_RETURN(r.in == ia + sa);
STATIC_CHECK_RETURN(r.out == ib + sa);
STATIC_CHECK_RETURN(ia[0] == 0);
STATIC_CHECK_RETURN(ia[1] == 1);
STATIC_CHECK_RETURN(ia[2] == 2);
STATIC_CHECK_RETURN(ia[3] == 3);
STATIC_CHECK_RETURN(ia[4] == 4);
STATIC_CHECK_RETURN(ib[0] == 4);
STATIC_CHECK_RETURN(ib[1] == 3);
STATIC_CHECK_RETURN(ib[2] == 2);
STATIC_CHECK_RETURN(ib[3] == 1);
STATIC_CHECK_RETURN(ib[4] == 0);
return true;
}
int main()
{
test<BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*> >();
test<const int*, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<int*> >();
test<const int*, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*>, Sentinel<const int *> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>, Sentinel<const int *> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int *> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int *> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*>, Sentinel<const int *> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>, Sentinel<const int *> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int *> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int *> >();
test<RandomAccessIterator<const int*>, int*>();
test<const int*, OutputIterator<int*>, Sentinel<const int *> >();
test<const int*, ForwardIterator<int*>, Sentinel<const int *> >();
test<const int*, BidirectionalIterator<int*>, Sentinel<const int *> >();
test<const int*, RandomAccessIterator<int*>, Sentinel<const int *> >();
test<const int*, int*>();
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,322 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/rotate.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
template<class Iter, class Sent = Iter>
void test()
{
using namespace ranges;
using Res = subrange<Iter>;
int ia[] = {0};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
Res r = rotate(Iter(ia), Iter(ia), Sent(ia));
CHECK(base(r.begin()) == ia);
CHECK(base(r.end()) == ia);
CHECK(ia[0] == 0);
r = rotate(Iter(ia), Iter(ia), Sent(ia+sa));
CHECK(base(r.begin()) == ia+sa);
CHECK(base(r.end()) == ia+sa);
CHECK(ia[0] == 0);
r = rotate(Iter(ia), Iter(ia+sa), Sent(ia+sa));
CHECK(base(r.begin()) == ia);
CHECK(base(r.end()) == ia+sa);
CHECK(ia[0] == 0);
int ib[] = {0, 1};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
r = rotate(Iter(ib), Iter(ib), Sent(ib+sb));
CHECK(base(r.begin()) == ib+sb);
CHECK(base(r.end()) == ib+sb);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
r = rotate(Iter(ib), Iter(ib+1), Sent(ib+sb));
CHECK(base(r.end()) == ib+sb);
CHECK(base(r.begin()) == ib+1);
CHECK(ib[0] == 1);
CHECK(ib[1] == 0);
r = rotate(Iter(ib), Iter(ib+sb), Sent(ib+sb));
CHECK(base(r.end()) == ib+sb);
CHECK(base(r.begin()) == ib);
CHECK(ib[0] == 1);
CHECK(ib[1] == 0);
int ic[] = {0, 1, 2};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
r = rotate(Iter(ic), Iter(ic), Sent(ic+sc));
CHECK(base(r.begin()) == ic+sc);
CHECK(base(r.end()) == ic+sc);
CHECK(ic[0] == 0);
CHECK(ic[1] == 1);
CHECK(ic[2] == 2);
r = rotate(Iter(ic), Iter(ic+1), Sent(ic+sc));
CHECK(base(r.begin()) == ic+2);
CHECK(base(r.end()) == ic+sc);
CHECK(ic[0] == 1);
CHECK(ic[1] == 2);
CHECK(ic[2] == 0);
r = rotate(Iter(ic), Iter(ic+2), Sent(ic+sc));
CHECK(base(r.begin()) == ic+1);
CHECK(base(r.end()) == ic+sc);
CHECK(ic[0] == 0);
CHECK(ic[1] == 1);
CHECK(ic[2] == 2);
r = rotate(Iter(ic), Iter(ic+sc), Sent(ic+sc));
CHECK(base(r.begin()) == ic);
CHECK(base(r.end()) == ic+sc);
CHECK(ic[0] == 0);
CHECK(ic[1] == 1);
CHECK(ic[2] == 2);
int id[] = {0, 1, 2, 3};
const unsigned sd = sizeof(id)/sizeof(id[0]);
r = rotate(Iter(id), Iter(id), Sent(id+sd));
CHECK(base(r.begin()) == id+sd);
CHECK(base(r.end()) == id+sd);
CHECK(id[0] == 0);
CHECK(id[1] == 1);
CHECK(id[2] == 2);
CHECK(id[3] == 3);
r = rotate(Iter(id), Iter(id+1), Sent(id+sd));
CHECK(base(r.begin()) == id+3);
CHECK(base(r.end()) == id+sd);
CHECK(id[0] == 1);
CHECK(id[1] == 2);
CHECK(id[2] == 3);
CHECK(id[3] == 0);
r = rotate(Iter(id), Iter(id+2), Sent(id+sd));
CHECK(base(r.begin()) == id+2);
CHECK(base(r.end()) == id+sd);
CHECK(id[0] == 3);
CHECK(id[1] == 0);
CHECK(id[2] == 1);
CHECK(id[3] == 2);
r = rotate(Iter(id), Iter(id+3), Sent(id+sd));
CHECK(base(r.begin()) == id+1);
CHECK(base(r.end()) == id+sd);
CHECK(id[0] == 2);
CHECK(id[1] == 3);
CHECK(id[2] == 0);
CHECK(id[3] == 1);
r = rotate(Iter(id), Iter(id+sd), Sent(id+sd));
CHECK(base(r.begin()) == id);
CHECK(base(r.end()) == id+sd);
CHECK(id[0] == 2);
CHECK(id[1] == 3);
CHECK(id[2] == 0);
CHECK(id[3] == 1);
int ie[] = {0, 1, 2, 3, 4};
const unsigned se = sizeof(ie)/sizeof(ie[0]);
r = rotate(Iter(ie), Iter(ie), Sent(ie+se));
CHECK(base(r.begin()) == ie+se);
CHECK(base(r.end()) == ie+se);
CHECK(ie[0] == 0);
CHECK(ie[1] == 1);
CHECK(ie[2] == 2);
CHECK(ie[3] == 3);
CHECK(ie[4] == 4);
r = rotate(Iter(ie), Iter(ie+1), Sent(ie+se));
CHECK(base(r.begin()) == ie+4);
CHECK(base(r.end()) == ie+se);
CHECK(ie[0] == 1);
CHECK(ie[1] == 2);
CHECK(ie[2] == 3);
CHECK(ie[3] == 4);
CHECK(ie[4] == 0);
r = rotate(Iter(ie), Iter(ie+2), Sent(ie+se));
CHECK(base(r.begin()) == ie+3);
CHECK(base(r.end()) == ie+se);
CHECK(ie[0] == 3);
CHECK(ie[1] == 4);
CHECK(ie[2] == 0);
CHECK(ie[3] == 1);
CHECK(ie[4] == 2);
r = rotate(Iter(ie), Iter(ie+3), Sent(ie+se));
CHECK(base(r.begin()) == ie+2);
CHECK(base(r.end()) == ie+se);
CHECK(ie[0] == 1);
CHECK(ie[1] == 2);
CHECK(ie[2] == 3);
CHECK(ie[3] == 4);
CHECK(ie[4] == 0);
r = rotate(Iter(ie), Iter(ie+4), Sent(ie+se));
CHECK(base(r.begin()) == ie+1);
CHECK(base(r.end()) == ie+se);
CHECK(ie[0] == 0);
CHECK(ie[1] == 1);
CHECK(ie[2] == 2);
CHECK(ie[3] == 3);
CHECK(ie[4] == 4);
r = rotate(Iter(ie), Iter(ie+se), Sent(ie+se));
CHECK(base(r.begin()) == ie);
CHECK(base(r.end()) == ie+se);
CHECK(ie[0] == 0);
CHECK(ie[1] == 1);
CHECK(ie[2] == 2);
CHECK(ie[3] == 3);
CHECK(ie[4] == 4);
int ig[] = {0, 1, 2, 3, 4, 5};
const unsigned sg = sizeof(ig)/sizeof(ig[0]);
r = rotate(Iter(ig), Iter(ig), Sent(ig+sg));
CHECK(base(r.begin()) == ig+sg);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 0);
CHECK(ig[1] == 1);
CHECK(ig[2] == 2);
CHECK(ig[3] == 3);
CHECK(ig[4] == 4);
CHECK(ig[5] == 5);
r = rotate(Iter(ig), Iter(ig+1), Sent(ig+sg));
CHECK(base(r.begin()) == ig+5);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 1);
CHECK(ig[1] == 2);
CHECK(ig[2] == 3);
CHECK(ig[3] == 4);
CHECK(ig[4] == 5);
CHECK(ig[5] == 0);
r = rotate(Iter(ig), Iter(ig+2), Sent(ig+sg));
CHECK(base(r.begin()) == ig+4);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 3);
CHECK(ig[1] == 4);
CHECK(ig[2] == 5);
CHECK(ig[3] == 0);
CHECK(ig[4] == 1);
CHECK(ig[5] == 2);
r = rotate(Iter(ig), Iter(ig+3), Sent(ig+sg));
CHECK(base(r.begin()) == ig+3);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 0);
CHECK(ig[1] == 1);
CHECK(ig[2] == 2);
CHECK(ig[3] == 3);
CHECK(ig[4] == 4);
CHECK(ig[5] == 5);
r = rotate(Iter(ig), Iter(ig+4), Sent(ig+sg));
CHECK(base(r.begin()) == ig+2);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 4);
CHECK(ig[1] == 5);
CHECK(ig[2] == 0);
CHECK(ig[3] == 1);
CHECK(ig[4] == 2);
CHECK(ig[5] == 3);
r = rotate(Iter(ig), Iter(ig+5), Sent(ig+sg));
CHECK(base(r.begin()) == ig+1);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 3);
CHECK(ig[1] == 4);
CHECK(ig[2] == 5);
CHECK(ig[3] == 0);
CHECK(ig[4] == 1);
CHECK(ig[5] == 2);
r = rotate(Iter(ig), Iter(ig+sg), Sent(ig+sg));
CHECK(base(r.begin()) == ig);
CHECK(base(r.end()) == ig+sg);
CHECK(ig[0] == 3);
CHECK(ig[1] == 4);
CHECK(ig[2] == 5);
CHECK(ig[3] == 0);
CHECK(ig[4] == 1);
CHECK(ig[5] == 2);
}
constexpr bool test_constexpr()
{
int rgi[] = {0, 1, 2, 3, 4, 5};
auto r = ranges::rotate(rgi, rgi + 2);
STATIC_CHECK_RETURN(r.begin() == rgi + 4);
STATIC_CHECK_RETURN(r.end() == ranges::end(rgi));
STATIC_CHECK_RETURN(rgi[0] == 2);
STATIC_CHECK_RETURN(rgi[1] == 3);
STATIC_CHECK_RETURN(rgi[2] == 4);
STATIC_CHECK_RETURN(rgi[3] == 5);
STATIC_CHECK_RETURN(rgi[4] == 0);
STATIC_CHECK_RETURN(rgi[5] == 1);
return true;
}
int main()
{
test<ForwardIterator<int *>>();
test<BidirectionalIterator<int *>>();
test<RandomAccessIterator<int *>>();
test<ForwardIterator<int *>, Sentinel<int*>>();
test<BidirectionalIterator<int *>, Sentinel<int*>>();
test<RandomAccessIterator<int *>, Sentinel<int*>>();
// test rvalue ranges
{
int rgi[] = {0,1,2,3,4,5};
auto r = ranges::rotate(ranges::views::all(rgi), rgi+2);
CHECK(r.begin() == rgi+4);
CHECK(r.end() == ranges::end(rgi));
CHECK(rgi[0] == 2);
CHECK(rgi[1] == 3);
CHECK(rgi[2] == 4);
CHECK(rgi[3] == 5);
CHECK(rgi[4] == 0);
CHECK(rgi[5] == 1);
}
{
int rgi[] = {0,1,2,3,4,5};
auto r = ranges::rotate(std::move(rgi), rgi+2);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(r));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(rgi[0] == 2);
CHECK(rgi[1] == 3);
CHECK(rgi[2] == 4);
CHECK(rgi[3] == 5);
CHECK(rgi[4] == 0);
CHECK(rgi[5] == 1);
}
{
std::vector<int> rgi{0,1,2,3,4,5};
auto r = ranges::rotate(std::move(rgi), rgi.begin()+2);
CHECK(::is_dangling(r));
CHECK(rgi[0] == 2);
CHECK(rgi[1] == 3);
CHECK(rgi[2] == 4);
CHECK(rgi[3] == 5);
CHECK(rgi[4] == 0);
CHECK(rgi[5] == 1);
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,359 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/rotate_copy.hpp>
#include "../simple_test.hpp"
#include "../test_iterators.hpp"
#include "../test_utils.hpp"
template<class InIter, class OutIter, typename Sent = InIter>
void test_iter()
{
int ia[] = {0, 1, 2, 3};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[sa] = {0};
ranges::rotate_copy_result<InIter, OutIter> r = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia), OutIter(ib));
CHECK(base(r.in) == ia);
CHECK(base(r.out) == ib);
r = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+1), OutIter(ib));
CHECK(base(r.in) == ia+1);
CHECK(base(r.out) == ib+1);
CHECK(ib[0] == 0);
r = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+1), OutIter(ib));
CHECK(base(r.in) == ia+1);
CHECK(base(r.out) == ib+1);
CHECK(ib[0] == 0);
r = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+2), OutIter(ib));
CHECK(base(r.in) == ia+2);
CHECK(base(r.out) == ib+2);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
r = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+2), OutIter(ib));
CHECK(base(r.in) == ia+2);
CHECK(base(r.out) == ib+2);
CHECK(ib[0] == 1);
CHECK(ib[1] == 0);
r = ranges::rotate_copy(InIter(ia), InIter(ia+2), Sent(ia+2), OutIter(ib));
CHECK(base(r.in) == ia+2);
CHECK(base(r.out) == ib+2);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
r = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+3), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
r = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+3), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 1);
CHECK(ib[1] == 2);
CHECK(ib[2] == 0);
r = ranges::rotate_copy(InIter(ia), InIter(ia+2), Sent(ia+3), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 2);
CHECK(ib[1] == 0);
CHECK(ib[2] == 1);
r = ranges::rotate_copy(InIter(ia), InIter(ia+3), Sent(ia+3), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
r = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+4), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
CHECK(ib[3] == 3);
r = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+4), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 1);
CHECK(ib[1] == 2);
CHECK(ib[2] == 3);
CHECK(ib[3] == 0);
r = ranges::rotate_copy(InIter(ia), InIter(ia+2), Sent(ia+4), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 2);
CHECK(ib[1] == 3);
CHECK(ib[2] == 0);
CHECK(ib[3] == 1);
r = ranges::rotate_copy(InIter(ia), InIter(ia+3), Sent(ia+4), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 3);
CHECK(ib[1] == 0);
CHECK(ib[2] == 1);
CHECK(ib[3] == 2);
r = ranges::rotate_copy(InIter(ia), InIter(ia+4), Sent(ia+4), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
CHECK(ib[3] == 3);
}
template<class InIter, class OutIter, typename Sent = InIter>
void test_rng()
{
int ia[] = {0, 1, 2, 3};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[sa] = {0};
ranges::rotate_copy_result<InIter, OutIter> r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia))), InIter(ia), OutIter(ib));
CHECK(base(r.in) == ia);
CHECK(base(r.out) == ib);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+1))), InIter(ia), OutIter(ib));
CHECK(base(r.in) == ia+1);
CHECK(base(r.out) == ib+1);
CHECK(ib[0] == 0);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+1))), InIter(ia+1), OutIter(ib));
CHECK(base(r.in) == ia+1);
CHECK(base(r.out) == ib+1);
CHECK(ib[0] == 0);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+2))), InIter(ia), OutIter(ib));
CHECK(base(r.in) == ia+2);
CHECK(base(r.out) == ib+2);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+2))), InIter(ia+1), OutIter(ib));
CHECK(base(r.in) == ia+2);
CHECK(base(r.out) == ib+2);
CHECK(ib[0] == 1);
CHECK(ib[1] == 0);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+2))), InIter(ia+2), OutIter(ib));
CHECK(base(r.in) == ia+2);
CHECK(base(r.out) == ib+2);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+3))), InIter(ia), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+3))), InIter(ia+1), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 1);
CHECK(ib[1] == 2);
CHECK(ib[2] == 0);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+3))), InIter(ia+2), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 2);
CHECK(ib[1] == 0);
CHECK(ib[2] == 1);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+3))), InIter(ia+3), OutIter(ib));
CHECK(base(r.in) == ia+3);
CHECK(base(r.out) == ib+3);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+4))), InIter(ia), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
CHECK(ib[3] == 3);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+4))), InIter(ia+1), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 1);
CHECK(ib[1] == 2);
CHECK(ib[2] == 3);
CHECK(ib[3] == 0);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+4))), InIter(ia+2), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 2);
CHECK(ib[1] == 3);
CHECK(ib[2] == 0);
CHECK(ib[3] == 1);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+4))), InIter(ia+3), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 3);
CHECK(ib[1] == 0);
CHECK(ib[2] == 1);
CHECK(ib[3] == 2);
r = ranges::rotate_copy(::as_lvalue(ranges::make_subrange(InIter(ia), Sent(ia+4))), InIter(ia+4), OutIter(ib));
CHECK(base(r.in) == ia+4);
CHECK(base(r.out) == ib+4);
CHECK(ib[0] == 0);
CHECK(ib[1] == 1);
CHECK(ib[2] == 2);
CHECK(ib[3] == 3);
}
template<class InIter, class OutIter, typename Sent = InIter>
void test()
{
test_iter<InIter, OutIter, Sent>();
test_rng<InIter, OutIter, Sent>();
}
struct S
{
int i;
};
constexpr bool test_constexpr()
{
using namespace ranges;
int rgi[] = {0, 1, 2, 3, 4, 5};
int rgo[6] = {0};
const auto r = ranges::rotate_copy(rgi, rgi + 2, rgo);
STATIC_CHECK_RETURN(r.in == ranges::end(rgi));
STATIC_CHECK_RETURN(r.out == ranges::end(rgo));
STATIC_CHECK_RETURN(rgo[0] == 2);
STATIC_CHECK_RETURN(rgo[1] == 3);
STATIC_CHECK_RETURN(rgo[2] == 4);
STATIC_CHECK_RETURN(rgo[3] == 5);
STATIC_CHECK_RETURN(rgo[4] == 0);
STATIC_CHECK_RETURN(rgo[5] == 1);
return true;
}
int main()
{
test<ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, int*>();
test<ForwardIterator<const int*>, OutputIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test<ForwardIterator<const int*>, int*, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, OutputIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test<BidirectionalIterator<const int*>, int*, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, OutputIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<int*>, Sentinel<const int*> >();
test<RandomAccessIterator<const int*>, int*, Sentinel<const int*> >();
test<const int*, OutputIterator<int*> >();
test<const int*, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<int*> >();
test<const int*, int*>();
// test rvalue ranges
{
int rgi[] = {0,1,2,3,4,5};
int rgo[6] = {0};
auto r = ranges::rotate_copy(std::move(rgi), rgi+2, rgo);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(r.in));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK(r.out == ranges::end(rgo));
CHECK(rgo[0] == 2);
CHECK(rgo[1] == 3);
CHECK(rgo[2] == 4);
CHECK(rgo[3] == 5);
CHECK(rgo[4] == 0);
CHECK(rgo[5] == 1);
}
{
std::vector<int> rgi{0,1,2,3,4,5};
int rgo[6] = {0};
auto r = ranges::rotate_copy(std::move(rgi), rgi.begin()+2, rgo);
CHECK(::is_dangling(r.in));
CHECK(r.out == ranges::end(rgo));
CHECK(rgo[0] == 2);
CHECK(rgo[1] == 3);
CHECK(rgo[2] == 4);
CHECK(rgo[3] == 5);
CHECK(rgo[4] == 0);
CHECK(rgo[5] == 1);
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,281 @@
// Range v3 lbrary
//
// Copyright Eric Niebler 2014-present
// Copyright Casey Carter 2016
//
// Use, modification and distrbution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distrbuted under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <array>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/algorithm/sample.hpp>
#include <range/v3/numeric/iota.hpp>
#include <range/v3/iterator/move_iterators.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
namespace
{
template<typename I, typename S>
auto in_sequence(I first, I mid, S last) ->
CPP_ret(bool)(
requires ranges::sentinel_for<S, I>)
{
for (; first != mid; ++first)
RANGES_ENSURE(first != last);
for (; first != last; ++first)
;
return true;
}
}
int main()
{
constexpr unsigned N = 100;
constexpr unsigned K = 10;
{
std::array<int, N> i;
ranges::iota(i, 0);
std::array<int, K> a{}, b{}, c{};
std::minstd_rand g1, g2 = g1;
{
auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
Sentinel<int*>(i.data()+N), a.begin(), K, g1);
CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, c));
}
{
auto result = ranges::sample(i.begin(), i.end(), b.begin(), K, g1);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(!ranges::equal(a, b));
CHECK(!ranges::equal(b, c));
}
{
auto result = ranges::sample(i.begin(), i.end(), c.begin(), K, g2);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == c.end());
CHECK(ranges::equal(a, c));
}
}
{
std::array<int, N> i;
ranges::iota(i, 0);
std::array<int, K> a{}, b{}, c{};
std::minstd_rand g1, g2 = g1;
auto rng = ranges::make_subrange(RandomAccessIterator<int*>(i.data()), Sentinel<int*>(i.data() + N));
{
auto result = ranges::sample(rng, a.begin(), K, g1);
CHECK(in_sequence(ranges::begin(rng), result.in, ranges::end(rng)));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, b));
}
{
auto result = ranges::sample(i, b.begin(), K, g2);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(ranges::equal(a, b));
}
{
auto result = ranges::sample(i, b.begin(), K, g1);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(!ranges::equal(a, b));
CHECK(!ranges::equal(b, c));
}
{
a.fill(0);
auto result = ranges::sample(std::move(rng), a.begin(), K, g1);
CHECK(in_sequence(ranges::begin(rng), result.in, ranges::end(rng)));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, c));
}
}
{
std::array<int, N> i;
ranges::iota(i, 0);
std::array<int, K> a{}, b{}, c{};
{
auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
Sentinel<int*>(i.data() + N), a.begin(), K);
CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, b));
}
{
auto result = ranges::sample(i, b.begin(), K);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(!ranges::equal(b, c));
CHECK(!ranges::equal(a, b));
}
}
{
std::array<MoveOnlyString, 10> source;
std::array<MoveOnlyString, 4> dest;
auto result = ranges::sample(ranges::make_move_iterator(source.begin()),
ranges::make_move_sentinel(source.end()),
ForwardIterator<MoveOnlyString*>(dest.data()), dest.size());
CHECK(in_sequence(ranges::make_move_iterator(source.begin()),
result.in,
ranges::make_move_sentinel(source.end())));
CHECK(result.out == ForwardIterator<MoveOnlyString*>(dest.data() + dest.size()));
}
{
std::array<int, N> i;
ranges::iota(i, 0);
std::array<int, K> a{}, b{}, c{};
std::minstd_rand g1, g2 = g1;
{
auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
Sentinel<int*>(i.data()+N), a, g1);
CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, c));
}
{
auto result = ranges::sample(i.begin(), i.end(), b, g1);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(!ranges::equal(a, b));
CHECK(!ranges::equal(b, c));
}
{
auto result = ranges::sample(i.begin(), i.end(), c, g2);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == c.end());
CHECK(ranges::equal(a, c));
}
}
{
std::array<int, N> i;
ranges::iota(i, 0);
std::array<int, K> a{}, b{}, c{};
std::minstd_rand g1, g2 = g1;
auto rng = ranges::make_subrange(RandomAccessIterator<int*>(i.data()), Sentinel<int*>(i.data() + N));
{
auto result = ranges::sample(rng, a, g1);
CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, b));
}
{
auto result = ranges::sample(i, b, g2);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(ranges::equal(a, b));
}
{
auto result = ranges::sample(i, b, g1);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(!ranges::equal(a, b));
CHECK(!ranges::equal(b, c));
}
{
a.fill(0);
auto result = ranges::sample(std::move(rng), a, g1);
CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, c));
}
}
{
std::array<int, N> i;
ranges::iota(i, 0);
std::array<int, K> a{}, b{}, c{};
{
auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
Sentinel<int*>(i.data() + N), a);
CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
CHECK(result.out == a.end());
CHECK(!ranges::equal(a, b));
}
{
auto result = ranges::sample(i, b);
CHECK(in_sequence(i.begin(), result.in, i.end()));
CHECK(result.out == b.end());
CHECK(!ranges::equal(b, c));
CHECK(!ranges::equal(a, b));
}
}
{
std::array<MoveOnlyString, 10> source;
std::array<MoveOnlyString, 4> dest;
auto out = ranges::make_subrange(
ForwardIterator<MoveOnlyString*>(dest.data()),
Sentinel<MoveOnlyString*, true>(dest.data() + dest.size()));
auto result = ranges::sample(ranges::make_move_iterator(source.begin()),
ranges::make_move_sentinel(source.end()), out);
CHECK(in_sequence(source.begin(), result.in.base(), source.end()));
CHECK(result.out == ranges::end(out));
}
{
int data[] = {0,1,2,3};
int sample[2];
std::minstd_rand g;
{
auto result = ranges::sample(data, sample, g);
CHECK(in_sequence(ranges::begin(data), result.in, ranges::end(data)));
CHECK(result.out == ranges::end(sample));
}
{
auto result = ranges::sample(data, sample);
CHECK(in_sequence(ranges::begin(data), result.in, ranges::end(data)));
CHECK(result.out == ranges::end(sample));
}
{
auto result = ranges::sample(data + 0, data + 2, sample + 0, 9999);
CHECK(result.in == data + 2);
CHECK(result.out == sample + 2);
}
}
return ::test_result();
}

View File

@@ -0,0 +1,256 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/search.hpp>
#include <range/v3/view/counted.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>
void
test_iter_impl()
{
int ia[] = {0, 1, 2, 3, 4, 5};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia)).begin() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia)).end() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia+1)).begin() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia+1)).end() == Iter1(ia+1));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+1), Sent2(ia+2)).begin() == Iter1(ia+1));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+1), Sent2(ia+2)).end() == Iter1(ia+2));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+2)).begin() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+2)).end() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+3)).begin() == Iter1(ia+2));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+3)).end() == Iter1(ia+3));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+3)).begin() == Iter1(ia+2));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+3)).end() == Iter1(ia+3));
CHECK(ranges::search(Iter1(ia), Sent1(ia), Iter2(ia+2), Sent2(ia+3)).begin() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia), Iter2(ia+2), Sent2(ia+3)).end() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+sa-1), Sent2(ia+sa)).begin() == Iter1(ia+sa-1));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+sa-1), Sent2(ia+sa)).end() == Iter1(ia+sa));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+sa-3), Sent2(ia+sa)).begin() == Iter1(ia+sa-3));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+sa-3), Sent2(ia+sa)).end() == Iter1(ia+sa));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia+sa)).begin() == Iter1(ia));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia+sa)).end() == Iter1(ia+sa));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa-1), Iter2(ia), Sent2(ia+sa)).begin() == Iter1(ia+sa-1));
CHECK(ranges::search(Iter1(ia), Sent1(ia+sa-1), Iter2(ia), Sent2(ia+sa)).end() == Iter1(ia+sa-1));
CHECK(ranges::search(Iter1(ia), Sent1(ia+1), Iter2(ia), Sent2(ia+sa)).begin() == Iter1(ia+1));
CHECK(ranges::search(Iter1(ia), Sent1(ia+1), Iter2(ia), Sent2(ia+sa)).end() == Iter1(ia+1));
int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int ic[] = {1};
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ic), Sent2(ic+1)).begin() == Iter1(ib+1));
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ic), Sent2(ic+1)).end() == Iter1(ib+2));
int id[] = {1, 2};
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(id), Sent2(id+2)).begin() == Iter1(ib+1));
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(id), Sent2(id+2)).end() == Iter1(ib+3));
int ie[] = {1, 2, 3};
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ie), Sent2(ie+3)).begin() == Iter1(ib+4));
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ie), Sent2(ie+3)).end() == Iter1(ib+7));
int ig[] = {1, 2, 3, 4};
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ig), Sent2(ig+4)).begin() == Iter1(ib+8));
CHECK(ranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ig), Sent2(ig+4)).end() == Iter1(ib+12));
int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
const unsigned sh = sizeof(ih)/sizeof(ih[0]);
int ii[] = {1, 1, 2};
CHECK(ranges::search(Iter1(ih), Sent1(ih+sh), Iter2(ii), Sent2(ii+3)).begin() == Iter1(ih+3));
CHECK(ranges::search(Iter1(ih), Sent1(ih+sh), Iter2(ii), Sent2(ii+3)).end() == Iter1(ih+6));
int ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
const unsigned sj = sizeof(ij)/sizeof(ij[0]);
int ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
const unsigned sk = sizeof(ik)/sizeof(ik[0]);
CHECK(ranges::search(Iter1(ij), Sent1(ij+sj), Iter2(ik), Sent2(ik+sk)).begin() == Iter1(ij+6));
CHECK(ranges::search(Iter1(ij), Sent1(ij+sj), Iter2(ik), Sent2(ik+sk)).end() == Iter1(ij+6+sk));
}
template<class Iter1, class Iter2>
void
test_iter()
{
using Sent1 = typename sentinel_type<Iter1>::type;
using Sent2 = typename sentinel_type<Iter2>::type;
test_iter_impl<Iter1, Iter2>();
test_iter_impl<Iter1, Iter2, Sent1>();
test_iter_impl<Iter1, Iter2, Iter1, Sent2>();
test_iter_impl<Iter1, Iter2, Sent1, Sent2>();
using SizedSent1 = typename sentinel_type<Iter1, true>::type;
using SizedSent2 = typename sentinel_type<Iter2, true>::type;
test_iter_impl<Iter1, Iter2, SizedSent1, SizedSent2>();
}
template<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>
void
test_range_impl()
{
int ia[] = {0, 1, 2, 3, 4, 5};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia), Sent2(ia))).begin() == Iter1(ia));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia), Sent2(ia+1))).begin() == Iter1(ia));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia+1), Sent2(ia+2))).begin() == Iter1(ia+1));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia+2), Sent2(ia+2))).begin() == Iter1(ia));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia+2), Sent2(ia+3))).begin() == Iter1(ia+2));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia+2), Sent2(ia+3))).begin() == Iter1(ia+2));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia)), ranges::make_subrange(Iter2(ia+2), Sent2(ia+3))).begin() == Iter1(ia));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia+sa-1), Sent2(ia+sa))).begin() == Iter1(ia+sa-1));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia+sa-3), Sent2(ia+sa))).begin() == Iter1(ia+sa-3));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa)), ranges::make_subrange(Iter2(ia), Sent2(ia+sa))).begin() == Iter1(ia));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+sa-1)), ranges::make_subrange(Iter2(ia), Sent2(ia+sa))).begin() == Iter1(ia+sa-1));
CHECK(ranges::search(ranges::make_subrange(Iter1(ia), Sent1(ia+1)), ranges::make_subrange(Iter2(ia), Sent2(ia+sa))).begin() == Iter1(ia+1));
int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int ic[] = {1};
CHECK(ranges::search(ranges::make_subrange(Iter1(ib), Sent1(ib+sb)), ranges::make_subrange(Iter2(ic), Sent2(ic+1))).begin() == Iter1(ib+1));
int id[] = {1, 2};
CHECK(ranges::search(ranges::make_subrange(Iter1(ib), Sent1(ib+sb)), ranges::make_subrange(Iter2(id), Sent2(id+2))).begin() == Iter1(ib+1));
int ie[] = {1, 2, 3};
CHECK(ranges::search(ranges::make_subrange(Iter1(ib), Sent1(ib+sb)), ranges::make_subrange(Iter2(ie), Sent2(ie+3))).begin() == Iter1(ib+4));
int ig[] = {1, 2, 3, 4};
CHECK(ranges::search(ranges::make_subrange(Iter1(ib), Sent1(ib+sb)), ranges::make_subrange(Iter2(ig), Sent2(ig+4))).begin() == Iter1(ib+8));
int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
const unsigned sh = sizeof(ih)/sizeof(ih[0]);
int ii[] = {1, 1, 2};
CHECK(ranges::search(ranges::make_subrange(Iter1(ih), Sent1(ih+sh)), ranges::make_subrange(Iter2(ii), Sent2(ii+3))).begin() == Iter1(ih+3));
int ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
const unsigned sj = sizeof(ij)/sizeof(ij[0]);
int ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
const unsigned sk = sizeof(ik)/sizeof(ik[0]);
CHECK(ranges::search(ranges::make_subrange(Iter1(ij), Sent1(ij+sj)), ranges::make_subrange(Iter2(ik), Sent2(ik+sk))).begin() == Iter1(ij+6));
}
template<class Iter1, class Iter2>
void
test_range()
{
using Sent1 = typename sentinel_type<Iter1>::type;
using Sent2 = typename sentinel_type<Iter2>::type;
test_range_impl<Iter1, Iter2>();
test_range_impl<Iter1, Iter2, Sent1>();
test_range_impl<Iter1, Iter2, Iter1, Sent2>();
test_range_impl<Iter1, Iter2, Sent1, Sent2>();
using SizedSent1 = typename sentinel_type<Iter1, true>::type;
using SizedSent2 = typename sentinel_type<Iter2, true>::type;
test_range_impl<Iter1, Iter2, SizedSent1, SizedSent2>();
}
template<class Iter1, class Iter2>
void
test()
{
test_iter<Iter1, Iter2>();
test_range<Iter1, Iter2>();
}
struct S
{
int i;
};
struct T
{
int i;
};
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 3, 4};
int ib[] = {2, 3};
int ic[] = {2, 4};
constexpr auto sa = size(ia);
auto r = search(ia, ib, equal_to{});
STATIC_CHECK_RETURN(r.begin() == ia + 2);
auto r2 = search(ia, ic, equal_to{});
STATIC_CHECK_RETURN(r2.begin() == ia + sa);
return true;
}
int main()
{
test<ForwardIterator<const int*>, ForwardIterator<const int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
// Test projections:
{
S const in[] = {{0}, {1}, {2}, {3}, {4}, {5}};
T const pat[] = {{2}, {3}};
S const *p = ranges::search(in, pat, std::equal_to<int>{}, &S::i, &T::i).begin();
CHECK(p == in+2);
}
// Test counted ranges
{
int in[] = {0,1,2,3,4,5};
auto rng = ranges::views::counted(BidirectionalIterator<int*>(in), 6);
auto sub = ranges::search(rng, std::initializer_list<int>{2,3});
CHECK(base(sub.begin().base()) == in+2);
CHECK(base(sub.end().base()) == in+4);
CHECK(sub.begin().count() == 4);
CHECK(sub.end().count() == 2);
sub = ranges::search(rng, std::initializer_list<int>{5,6});
CHECK(base(sub.begin().base()) == in+6);
CHECK(base(sub.end().base()) == in+6);
CHECK(sub.begin().count() == 0);
CHECK(sub.end().count() == 0);
}
// Test rvalue ranges
{
int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
int ie[] = {1, 2, 3};
CHECK(ranges::search(ranges::views::all(ib), ie).begin() == ib+4);
}
#ifndef RANGES_WORKAROUND_MSVC_573728
{
int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
int ie[] = {1, 2, 3};
CHECK(::is_dangling(ranges::search(std::move(ib), ie)));
}
#endif
{
std::vector<int> ib{0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
int ie[] = {1, 2, 3};
CHECK(::is_dangling(ranges::search(std::move(ib), ie)));
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,263 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
// Copyright 2005 - 2007 Adobe Systems Incorporated
// Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
// or a copy at http://stlab.adobe.com/licenses.html)
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/search_n.hpp>
#include <range/v3/view/counted.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter, typename Sent = Iter>
void
test_iter_impl()
{
int ia[] = {0, 1, 2, 3, 4, 5};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 0).begin() == Iter(ia));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 0).end() == Iter(ia));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 0).begin() == Iter(ia+0));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 0).end() == Iter(ia+1));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 0).begin() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 0).end() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 0).begin() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 0).end() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 3).begin() == Iter(ia));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 3).end() == Iter(ia));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 3).begin() == Iter(ia+3));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 3).end() == Iter(ia+4));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 3).begin() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 3).end() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 3).begin() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 3).end() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 5).begin() == Iter(ia));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 5).end() == Iter(ia));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 5).begin() == Iter(ia+5));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 5).end() == Iter(ia+6));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 5).begin() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 5).end() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 5).begin() == Iter(ia+sa));
CHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 5).end() == Iter(ia+sa));
int ib[] = {0, 0, 1, 1, 2, 2};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 0).begin() == Iter(ib));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 0).end() == Iter(ib));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 0).begin() == Iter(ib+0));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 0).end() == Iter(ib+1));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 0).begin() == Iter(ib+0));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 0).end() == Iter(ib+2));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 0).begin() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 0).end() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 0).begin() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 0).end() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 1).begin() == Iter(ib));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 1).end() == Iter(ib));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 1).begin() == Iter(ib+2));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 1).end() == Iter(ib+3));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 1).begin() == Iter(ib+2));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 1).end() == Iter(ib+4));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 1).begin() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 1).end() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 1).begin() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 1).end() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 2).begin() == Iter(ib));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 2).end() == Iter(ib));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 2).begin() == Iter(ib+4));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 2).end() == Iter(ib+5));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 2).begin() == Iter(ib+4));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 2).end() == Iter(ib+6));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 2).begin() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 2).end() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 2).begin() == Iter(ib+sb));
CHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 2).end() == Iter(ib+sb));
int ic[] = {0, 0, 0};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 0, 0).begin() == Iter(ic));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 0, 0).end() == Iter(ic));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 1, 0).begin() == Iter(ic));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 1, 0).end() == Iter(ic+1));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 2, 0).begin() == Iter(ic));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 2, 0).end() == Iter(ic+2));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 3, 0).begin() == Iter(ic));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 3, 0).end() == Iter(ic+3));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 4, 0).begin() == Iter(ic+sc));
CHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 4, 0).end() == Iter(ic+sc));
}
template<class Iter, class Iter2>
void
test_iter()
{
using Sent = typename sentinel_type<Iter>::type;
test_iter_impl<Iter>();
test_iter_impl<Iter, Sent>();
using SizedSent1 = typename sentinel_type<Iter, true>::type;
test_iter_impl<Iter, SizedSent1>();
}
template<class Iter, typename Sent = Iter>
void
test_range_impl()
{
int ia[] = {0, 1, 2, 3, 4, 5};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 0, 0).begin() == Iter(ia));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 1, 0).begin() == Iter(ia+0));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 2, 0).begin() == Iter(ia+sa));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), sa, 0).begin() == Iter(ia+sa));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 0, 3).begin() == Iter(ia));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 1, 3).begin() == Iter(ia+3));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 2, 3).begin() == Iter(ia+sa));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), sa, 3).begin() == Iter(ia+sa));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 0, 5).begin() == Iter(ia));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 1, 5).begin() == Iter(ia+5));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), 2, 5).begin() == Iter(ia+sa));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ia), Sent(ia+sa)), sa, 5).begin() == Iter(ia+sa));
int ib[] = {0, 0, 1, 1, 2, 2};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 0, 0).begin() == Iter(ib));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 1, 0).begin() == Iter(ib+0));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 2, 0).begin() == Iter(ib+0));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 3, 0).begin() == Iter(ib+sb));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), sb, 0).begin() == Iter(ib+sb));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 0, 1).begin() == Iter(ib));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 1, 1).begin() == Iter(ib+2));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 2, 1).begin() == Iter(ib+2));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 3, 1).begin() == Iter(ib+sb));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), sb, 1).begin() == Iter(ib+sb));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 0, 2).begin() == Iter(ib));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 1, 2).begin() == Iter(ib+4));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 2, 2).begin() == Iter(ib+4));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), 3, 2).begin() == Iter(ib+sb));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ib), Sent(ib+sb)), sb, 2).begin() == Iter(ib+sb));
int ic[] = {0, 0, 0};
const unsigned sc = sizeof(ic)/sizeof(ic[0]);
CHECK(ranges::search_n(ranges::make_subrange(Iter(ic), Sent(ic+sc)), 0, 0).begin() == Iter(ic));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ic), Sent(ic+sc)), 1, 0).begin() == Iter(ic));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ic), Sent(ic+sc)), 2, 0).begin() == Iter(ic));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ic), Sent(ic+sc)), 3, 0).begin() == Iter(ic));
CHECK(ranges::search_n(ranges::make_subrange(Iter(ic), Sent(ic+sc)), 4, 0).begin() == Iter(ic+sc));
}
template<class Iter, class Iter2>
void
test_range()
{
using Sent = typename sentinel_type<Iter>::type;
test_range_impl<Iter>();
test_range_impl<Iter, Sent>();
using SizedSent1 = typename sentinel_type<Iter, true>::type;
test_range_impl<Iter, SizedSent1>();
}
template<class Iter, class Iter2>
void
test()
{
test_iter<Iter, Iter2>();
test_range<Iter, Iter2>();
}
struct S
{
int i;
};
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {0, 1, 2, 2, 4, 5};
auto r = search_n(ia, 2, 2, equal_to{});
STATIC_CHECK_RETURN(r.begin() == ia + 2);
return true;
}
int main()
{
test<ForwardIterator<const int*>, ForwardIterator<const int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
// Test projections:
{
S const in[] = {{0}, {1}, {2}, {2}, {4}, {5}};
auto sub = ranges::search_n(in, 2, 2, std::equal_to<int>{}, &S::i);
CHECK(sub.begin() == in+2);
CHECK(sub.end() == in+4);
}
// Test counted ranges
{
int in[] = {0,1,2,2,4,5};
auto rng = ranges::views::counted(BidirectionalIterator<int*>(in), 6);
auto sub = ranges::search_n(rng, 2, 2);
CHECK(base(sub.begin().base()) == in+2);
CHECK(base(sub.end().base()) == in+4);
CHECK(sub.begin().count() == 4);
CHECK(sub.end().count() == 2);
auto sub2 = ranges::search_n(rng, 3, 2);
CHECK(base(sub2.begin().base()) == in+6);
CHECK(base(sub2.end().base()) == in+6);
CHECK(sub2.begin().count() == 0);
CHECK(sub2.end().count() == 0);
}
// Test rvalue ranges
{
int ib[] = {0, 0, 1, 1, 2, 2};
CHECK(ranges::search_n(ranges::views::all(ib), 2, 1).begin() == ib+2);
}
#ifndef RANGES_WORKAROUND_MSVC_573728
{
int ib[] = {0, 0, 1, 1, 2, 2};
CHECK(::is_dangling(ranges::search_n(std::move(ib), 2, 1)));
}
#endif // RANGES_WORKAROUND_MSVC_573728
{
std::vector<int> ib{0, 0, 1, 1, 2, 2};
CHECK(::is_dangling(ranges::search_n(std::move(ib), 2, 1)));
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}

View File

@@ -0,0 +1,375 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <functional>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/fill.hpp>
#include <range/v3/algorithm/set_algorithm.hpp>
#include <range/v3/algorithm/lexicographical_compare.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter1, class Iter2, class OutIter>
void
test_iter()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
static const int sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4, 4, 6};
static const int sb = sizeof(ib)/sizeof(ib[0]);
int ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto set_difference = ::make_testable_2<false, true>(ranges::set_difference);
set_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic)).
check([&](ranges::set_difference_result<Iter1, OutIter> res)
{
CHECK((base(res.in1) - ia) == sa);
CHECK((base(res.out) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(res.out), ir, ir+sr) == false);
ranges::fill(ic, 0);
}
);
int irr[] = {6};
static const int srr = sizeof(irr)/sizeof(irr[0]);
set_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic)).
check([&](ranges::set_difference_result<Iter1, OutIter> res)
{
CHECK((base(res.in1) - ib) == sb);
CHECK((base(res.out) - ic) == srr);
CHECK(std::lexicographical_compare(ic, base(res.out), irr, irr+srr) == false);
ranges::fill(ic, 0);
}
);
}
template<class Iter1, class Iter2, class OutIter>
void
test_comp()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
static const int sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4, 4, 6};
static const int sb = sizeof(ib)/sizeof(ib[0]);
int ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto set_difference = ::make_testable_2<false, true>(ranges::set_difference);
set_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic), std::less<int>()).
check([&](ranges::set_difference_result<Iter1, OutIter> res)
{
CHECK((base(res.in1) - ia) == sa);
CHECK((base(res.out) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(res.out), ir, ir+sr) == false);
ranges::fill(ic, 0);
}
);
int irr[] = {6};
static const int srr = sizeof(irr)/sizeof(irr[0]);
set_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic), std::less<int>()).
check([&](ranges::set_difference_result<Iter1, OutIter> res)
{
CHECK((base(res.in1) - ib) == sb);
CHECK((base(res.out) - ic) == srr);
CHECK(std::lexicographical_compare(ic, base(res.out), irr, irr+srr) == false);
ranges::fill(ic, 0);
}
);
}
template<class Iter1, class Iter2, class OutIter>
void test()
{
test_iter<Iter1, Iter2, OutIter>();
test_comp<Iter1, Iter2, OutIter>();
}
struct S
{
int i;
};
struct T
{
int j;
};
struct U
{
int k;
U& operator=(S s) { k = s.i; return *this;}
U& operator=(T t) { k = t.j; return *this;}
};
constexpr bool test_constexpr()
{
using namespace ranges;
using IL = std::initializer_list<int>;
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
const int sa = sizeof(ia) / sizeof(ia[0]);
int ib[] = {2, 4, 4, 6};
const int sb = sizeof(ib) / sizeof(ib[0]);
int ic[20] = {0};
int ir[] = {1, 2, 3, 3, 3, 4, 4};
const int sr = sizeof(ir) / sizeof(ir[0]);
const auto res = set_difference(ia, IL{2, 4, 4, 6}, ic, less{});
STATIC_CHECK_RETURN((res.in1 - ia) == sa);
STATIC_CHECK_RETURN((res.out - ic) == sr);
STATIC_CHECK_RETURN(lexicographical_compare(ic, res.out, ir, ir + sr, less{}) == 0);
fill(ic, 0);
int irr[] = {6};
const int srr = sizeof(irr) / sizeof(irr[0]);
const auto res2 = set_difference(ib, IL{1, 2, 2, 3, 3, 3, 4, 4, 4, 4}, ic, less{});
STATIC_CHECK_RETURN((res2.in1 - ib) == sb);
STATIC_CHECK_RETURN((res2.out - ic) == srr);
STATIC_CHECK_RETURN(lexicographical_compare(ic, res2.out, irr, irr + srr, less{}) == 0);
return true;
}
int main()
{
#ifdef SET_DIFFERENCE_1
test<InputIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, int*>();
test<InputIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, int*>();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<InputIterator<const int*>, const int*, OutputIterator<int*> >();
test<InputIterator<const int*>, const int*, ForwardIterator<int*> >();
test<InputIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_DIFFERENCE_2
test<ForwardIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, int*>();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<ForwardIterator<const int*>, const int*, OutputIterator<int*> >();
test<ForwardIterator<const int*>, const int*, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_DIFFERENCE_3
test<BidirectionalIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, const int*, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_DIFFERENCE_4
test<RandomAccessIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, const int*, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_DIFFERENCE_5
test<const int*, InputIterator<const int*>, OutputIterator<int*> >();
test<const int*, InputIterator<const int*>, BidirectionalIterator<int*> >(); test<const int*, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, InputIterator<const int*>, int*>();
test<const int*, ForwardIterator<const int*>, OutputIterator<int*> >();
test<const int*, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<const int*, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, ForwardIterator<const int*>, int*>();
test<const int*, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, int*>();
test<const int*, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, int*>();
test<const int*, const int*, OutputIterator<int*> >();
test<const int*, const int*, ForwardIterator<int*> >();
test<const int*, const int*, BidirectionalIterator<int*> >();
test<const int*, const int*, RandomAccessIterator<int*> >();
test<const int*, const int*, int*>();
#endif
#ifdef SET_DIFFERENCE_6
// Test projections
{
S ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
static const int sa = sizeof(ia)/sizeof(ia[0]);
T ib[] = {T{2}, T{4}, T{4}, T{6}};
static const int sb = sizeof(ib)/sizeof(ib[0]);
U ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4};
static const int sr = sizeof(ir)/sizeof(ir[0]);
ranges::set_difference_result<S *, U *> res = ranges::set_difference(ia, ib, ic, std::less<int>(), &S::i, &T::j);
CHECK((res.in1 - ia) == sa);
CHECK((res.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res.out, ir, ir+sr, std::less<int>(), &U::k) == false);
ranges::fill(ic, U{0});
int irr[] = {6};
static const int srr = sizeof(irr)/sizeof(irr[0]);
ranges::set_difference_result<T *, U *> res2 = ranges::set_difference(ib, ia, ic, std::less<int>(), &T::j, &S::i);
CHECK((res2.in1 - ib) == sb);
CHECK((res2.out - ic) == srr);
CHECK(ranges::lexicographical_compare(ic, res2.out, ir, irr+srr, std::less<int>(), &U::k) == false);
}
// Test rvalue ranges
{
S ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
T ib[] = {T{2}, T{4}, T{4}, T{6}};
static const int sb = sizeof(ib)/sizeof(ib[0]);
U ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto res = ranges::set_difference(std::move(ia), ranges::views::all(ib), ic, std::less<int>(), &S::i, &T::j);
#ifndef RANGES_WORKAROUND_MSVC_573728
CHECK(::is_dangling(res.in1));
#endif // RANGES_WORKAROUND_MSVC_573728
CHECK((res.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res.out, ir, ir+sr, std::less<int>(), &U::k) == false);
ranges::fill(ic, U{0});
int irr[] = {6};
static const int srr = sizeof(irr)/sizeof(irr[0]);
auto res2 = ranges::set_difference(ranges::views::all(ib), ranges::views::all(ia), ic, std::less<int>(), &T::j, &S::i);
CHECK((res2.in1 - ib) == sb);
CHECK((res2.out - ic) == srr);
CHECK(ranges::lexicographical_compare(ic, res2.out, ir, irr+srr, std::less<int>(), &U::k) == false);
ranges::fill(ic, U{0});
std::vector<S> vec{S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
auto res3 = ranges::set_difference(std::move(vec), ranges::views::all(ib), ic, std::less<int>(), &S::i, &T::j);
CHECK(::is_dangling(res3.in1));
CHECK((res3.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res3.out, ir, ir+sr, std::less<int>(), &U::k) == false);
}
{
STATIC_CHECK(test_constexpr());
}
#endif
return ::test_result();
}

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_DIFFERENCE_1
#include "./set_difference.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_DIFFERENCE_2
#include "./set_difference.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_DIFFERENCE_3
#include "./set_difference.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_DIFFERENCE_4
#include "./set_difference.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_DIFFERENCE_5
#include "./set_difference.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_DIFFERENCE_6
#include "./set_difference.hpp"

View File

@@ -0,0 +1,286 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <functional>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/fill.hpp>
#include <range/v3/algorithm/set_algorithm.hpp>
#include <range/v3/algorithm/lexicographical_compare.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter1, class Iter2, class OutIter>
void
test()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
static const int sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4, 4, 6};
static const int sb = sizeof(ib)/sizeof(ib[0]);
int ic[20];
int ir[] = {2, 4, 4};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto set_intersection = ::make_testable_2<true, true>(ranges::set_intersection);
set_intersection(Iter1(ia), Iter1(ia+sa),
Iter2(ib), Iter2(ib+sb), OutIter(ic)).check([&](OutIter ce)
{
CHECK((base(ce) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(ce), ir, ir+sr) == false);
ranges::fill(ic, 0);
});
set_intersection(Iter1(ib), Iter1(ib+sb),
Iter2(ia), Iter2(ia+sa), OutIter(ic)).check([&](OutIter ce)
{
CHECK((base(ce) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(ce), ir, ir+sr) == false);
ranges::fill(ic, 0);
});
set_intersection(Iter1(ia), Iter1(ia+sa),
Iter2(ib), Iter2(ib+sb), OutIter(ic), std::less<int>()).check([&](OutIter ce)
{
CHECK((base(ce) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(ce), ir, ir+sr) == false);
ranges::fill(ic, 0);
});
set_intersection(Iter1(ib), Iter1(ib+sb),
Iter2(ia), Iter2(ia+sa), OutIter(ic), std::less<int>()).check([&](OutIter ce)
{
CHECK((base(ce) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(ce), ir, ir+sr) == false);
ranges::fill(ic, 0);
});
}
struct S
{
int i;
};
struct T
{
int j;
};
struct U
{
int k;
U& operator=(S s) { k = s.i; return *this;}
U& operator=(T t) { k = t.j; return *this;}
};
constexpr bool test_constexpr()
{
using namespace ranges;
int ic[20] = {0};
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
int ib[4] = {2, 4, 4, 6};
int ir[3] = {2, 4, 4};
constexpr auto sr = size(ir);
int * res = set_intersection(ia, ib, ic, less{});
STATIC_CHECK_RETURN((res - ic) == sr);
STATIC_CHECK_RETURN(lexicographical_compare(ic, res, ir, ir + sr, less{}) == 0);
return true;
}
int main()
{
#ifdef SET_INTERSECTION_1
test<InputIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, int*>();
test<InputIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, int*>();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<InputIterator<const int*>, const int*, OutputIterator<int*> >();
test<InputIterator<const int*>, const int*, ForwardIterator<int*> >();
test<InputIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_INTERSECTION_2
test<ForwardIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, int*>();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<ForwardIterator<const int*>, const int*, OutputIterator<int*> >();
test<ForwardIterator<const int*>, const int*, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_INTERSECTION_3
test<BidirectionalIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, const int*, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_INTERSECTION_4
test<RandomAccessIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, const int*, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_INTERSECTION_5
test<const int*, InputIterator<const int*>, OutputIterator<int*> >();
test<const int*, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, InputIterator<const int*>, int*>();
test<const int*, ForwardIterator<const int*>, OutputIterator<int*> >();
test<const int*, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<const int*, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, ForwardIterator<const int*>, int*>();
test<const int*, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, int*>();
test<const int*, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, int*>();
test<const int*, const int*, OutputIterator<int*> >();
test<const int*, const int*, ForwardIterator<int*> >();
test<const int*, const int*, BidirectionalIterator<int*> >();
test<const int*, const int*, RandomAccessIterator<int*> >();
test<const int*, const int*, int*>();
#endif
#ifdef SET_INTERSECTION_6
// Test projections
{
S ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
T ib[] = {T{2}, T{4}, T{4}, T{6}};
U ic[20];
int ir[] = {2, 4, 4};
static const int sr = sizeof(ir)/sizeof(ir[0]);
U * res = ranges::set_intersection(ranges::views::all(ia), ranges::views::all(ib), ic, std::less<int>(), &S::i, &T::j);
CHECK((res - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res, ir, ir+sr, std::less<int>(), &U::k) == false);
}
{
STATIC_CHECK(test_constexpr());
}
#endif
return ::test_result();
}

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_INTERSECTION_1
#include "./set_intersection.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_INTERSECTION_2
#include "./set_intersection.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_INTERSECTION_3
#include "./set_intersection.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_INTERSECTION_4
#include "./set_intersection.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_INTERSECTION_5
#include "./set_intersection.hpp"

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_INTERSECTION_6
#include "./set_intersection.hpp"

View File

@@ -0,0 +1,379 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <functional>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/fill.hpp>
#include <range/v3/algorithm/set_algorithm.hpp>
#include <range/v3/algorithm/lexicographical_compare.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter1, class Iter2, class OutIter>
void
test_iter()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
static const int sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4, 4, 6};
static const int sb = sizeof(ib)/sizeof(ib[0]);
int ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4, 6};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto set_symmetric_difference = ::make_testable_2(ranges::set_symmetric_difference);
set_symmetric_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic)).
check([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)
{
CHECK((base(res.out) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(res.out), ir, ir+sr) == false);
ranges::fill(ic, 0);
}
);
set_symmetric_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic)).
check([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)
{
CHECK((base(res.out) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(res.out), ir, ir+sr) == false);
ranges::fill(ic, 0);
}
);
}
template<class Iter1, class Iter2, class OutIter>
void
test_comp()
{
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
static const int sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {2, 4, 4, 6};
static const int sb = sizeof(ib)/sizeof(ib[0]);
int ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4, 6};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto set_symmetric_difference = ::make_testable_2(ranges::set_symmetric_difference);
set_symmetric_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic), std::less<int>()).
check([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)
{
CHECK((base(res.out) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(res.out), ir, ir+sr) == false);
ranges::fill(ic, 0);
}
);
set_symmetric_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic), std::less<int>()).
check([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)
{
CHECK((base(res.out) - ic) == sr);
CHECK(std::lexicographical_compare(ic, base(res.out), ir, ir+sr) == false);
ranges::fill(ic, 0);
}
);
}
template<class Iter1, class Iter2, class OutIter>
void test()
{
test_iter<Iter1, Iter2, OutIter>();
test_comp<Iter1, Iter2, OutIter>();
}
struct S
{
int i;
};
struct T
{
int j;
};
struct U
{
int k;
U& operator=(S s) { k = s.i; return *this;}
U& operator=(T t) { k = t.j; return *this;}
};
constexpr bool test_constexpr()
{
using namespace ranges;
int ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
int ib[] = {2, 4, 4, 6};
int ic[20] = {0};
int ir[] = {1, 2, 3, 3, 3, 4, 4, 6};
const int sr = sizeof(ir) / sizeof(ir[0]);
const auto res1 = set_symmetric_difference(ia, ib, ic, less{});
STATIC_CHECK_RETURN(res1.in1 == end(ia));
STATIC_CHECK_RETURN(res1.in2 == end(ib));
STATIC_CHECK_RETURN((res1.out - begin(ic)) == sr);
STATIC_CHECK_RETURN(lexicographical_compare(ic, res1.out, ir, ir + sr, less{}) == 0);
fill(ic, 0);
const auto res2 = set_symmetric_difference(ib, ia, ic, less{});
STATIC_CHECK_RETURN(res2.in1 == end(ib));
STATIC_CHECK_RETURN(res2.in2 == end(ia));
STATIC_CHECK_RETURN(res2.out - begin(ic) == sr);
STATIC_CHECK_RETURN(lexicographical_compare(ic, res2.out, ir, ir + sr, less{}) == 0);
return true;
}
int main()
{
#ifdef SET_SYMMETRIC_DIFFERENCE_1
test<InputIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, InputIterator<const int*>, int*>();
test<InputIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, ForwardIterator<const int*>, int*>();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<InputIterator<const int*>, const int*, OutputIterator<int*> >();
test<InputIterator<const int*>, const int*, ForwardIterator<int*> >();
test<InputIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<InputIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<InputIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_SYMMETRIC_DIFFERENCE_2
test<ForwardIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, InputIterator<const int*>, int*>();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, ForwardIterator<const int*>, int*>();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<ForwardIterator<const int*>, const int*, OutputIterator<int*> >();
test<ForwardIterator<const int*>, const int*, ForwardIterator<int*> >();
test<ForwardIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<ForwardIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<ForwardIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_SYMMETRIC_DIFFERENCE_3
test<BidirectionalIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, InputIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, ForwardIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<BidirectionalIterator<const int*>, const int*, OutputIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, ForwardIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<BidirectionalIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_SYMMETRIC_DIFFERENCE_4
test<RandomAccessIterator<const int*>, InputIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, InputIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, ForwardIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*>, int*>();
test<RandomAccessIterator<const int*>, const int*, OutputIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, ForwardIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, BidirectionalIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, RandomAccessIterator<int*> >();
test<RandomAccessIterator<const int*>, const int*, int*>();
#endif
#ifdef SET_SYMMETRIC_DIFFERENCE_5
test<const int*, InputIterator<const int*>, OutputIterator<int*> >();
test<const int*, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, InputIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, InputIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, InputIterator<const int*>, int*>();
test<const int*, ForwardIterator<const int*>, OutputIterator<int*> >();
test<const int*, ForwardIterator<const int*>, ForwardIterator<int*> >();
test<const int*, ForwardIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, ForwardIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, ForwardIterator<const int*>, int*>();
test<const int*, BidirectionalIterator<const int*>, OutputIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, ForwardIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, BidirectionalIterator<const int*>, int*>();
test<const int*, RandomAccessIterator<const int*>, OutputIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, ForwardIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, BidirectionalIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, RandomAccessIterator<int*> >();
test<const int*, RandomAccessIterator<const int*>, int*>();
test<const int*, const int*, OutputIterator<int*> >();
test<const int*, const int*, ForwardIterator<int*> >();
test<const int*, const int*, BidirectionalIterator<int*> >();
test<const int*, const int*, RandomAccessIterator<int*> >();
test<const int*, const int*, int*>();
#endif
#ifdef SET_SYMMETRIC_DIFFERENCE_6
// Test projections
{
S ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
T ib[] = {T{2}, T{4}, T{4}, T{6}};
U ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4, 6};
static const int sr = sizeof(ir)/sizeof(ir[0]);
ranges::set_symmetric_difference_result<S *, T *, U *> res1 =
ranges::set_symmetric_difference(ia, ib, ic, std::less<int>(), &S::i, &T::j);
CHECK((res1.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res1.out, ir, ir+sr, std::less<int>(), &U::k) == false);
ranges::fill(ic, U{0});
ranges::set_symmetric_difference_result<T *, S *, U *> res2 =
ranges::set_symmetric_difference(ib, ia, ic, std::less<int>(), &T::j, &S::i);
CHECK((res2.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k) == false);
}
// Test rvalue ranges
#ifndef RANGES_WORKAROUND_MSVC_573728
{
S ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
T ib[] = {T{2}, T{4}, T{4}, T{6}};
U ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4, 6};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto res1 =
ranges::set_symmetric_difference(std::move(ia), ranges::views::all(ib), ic, std::less<int>(), &S::i, &T::j);
CHECK(::is_dangling(res1.in1));
CHECK(res1.in2 == ranges::end(ib));
CHECK((res1.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res1.out, ir, ir+sr, std::less<int>(), &U::k) == false);
ranges::fill(ic, U{0});
auto res2 =
ranges::set_symmetric_difference(ranges::views::all(ib), std::move(ia), ic, std::less<int>(), &T::j, &S::i);
CHECK(res2.in1 == ranges::end(ib));
CHECK(::is_dangling(res2.in2));
CHECK((res2.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k) == false);
}
#endif // RANGES_WORKAROUND_MSVC_573728
{
std::vector<S> ia{S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};
std::vector<T> ib{T{2}, T{4}, T{4}, T{6}};
U ic[20];
int ir[] = {1, 2, 3, 3, 3, 4, 4, 6};
static const int sr = sizeof(ir)/sizeof(ir[0]);
auto res1 =
ranges::set_symmetric_difference(std::move(ia), ranges::views::all(ib), ic, std::less<int>(), &S::i, &T::j);
CHECK(::is_dangling(res1.in1));
CHECK(res1.in2 == ranges::end(ib));
CHECK((res1.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res1.out, ir, ir+sr, std::less<int>(), &U::k) == false);
ranges::fill(ic, U{0});
auto res2 =
ranges::set_symmetric_difference(ranges::views::all(ib), std::move(ia), ic, std::less<int>(), &T::j, &S::i);
CHECK(res2.in1 == ranges::end(ib));
CHECK(::is_dangling(res2.in2));
CHECK((res2.out - ic) == sr);
CHECK(ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k) == false);
}
{
STATIC_CHECK(test_constexpr());
}
#endif
return ::test_result();
}

View File

@@ -0,0 +1,14 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//
#define SET_SYMMETRIC_DIFFERENCE_1
#include "./set_symmetric_difference.hpp"

Some files were not shown because too many files have changed in this diff Show More