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
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled

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,22 @@
include(../cmake/ranges_diagnostics.cmake)
set(CMAKE_FOLDER "test")
add_subdirectory(action)
add_subdirectory(algorithm)
add_subdirectory(iterator)
add_subdirectory(functional)
add_subdirectory(numeric)
add_subdirectory(range)
add_subdirectory(utility)
add_subdirectory(view)
add_subdirectory(experimental)
rv3_add_test(test.config config config.cpp)
rv3_add_test(test.constexpr_core constexpr_core constexpr_core.cpp)
rv3_add_test(test.multiple multiple multiple1.cpp multiple2.cpp)
rv3_add_test(test.bug474 bug474 bug474.cpp)
rv3_add_test(test.bug566 bug566 bug566.cpp)
rv3_add_test(test.bug1322 bug1322 bug1322.cpp)
rv3_add_test(test.bug1335 bug1335 bug1335.cpp)
rv3_add_test(test.bug1633 bug1633 bug1633.cpp)

View File

@@ -0,0 +1,24 @@
set(CMAKE_FOLDER "${CMAKE_FOLDER}/action")
rv3_add_test(test.act.concepts act.concepts cont_concepts.cpp)
rv3_add_test(test.act.adjacent_remove_if act.adjacent_remove_if adjacent_remove_if.cpp)
rv3_add_test(test.act.drop act.drop drop.cpp)
rv3_add_test(test.act.drop_while act.drop_while drop_while.cpp)
rv3_add_test(test.act.insert act.insert insert.cpp)
rv3_add_test(test.act.join act.join join.cpp)
rv3_add_test(test.act.push_front act.push_front push_front.cpp)
rv3_add_test(test.act.push_back act.push_back push_back.cpp)
rv3_add_test(test.act.remove_if act.remove_if remove_if.cpp)
rv3_add_test(test.act.remove act.remove remove.cpp)
rv3_add_test(test.act.unstable_remove_if act.unstable_remove_if unstable_remove_if.cpp)
rv3_add_test(test.act.reverse act.reverse reverse.cpp)
rv3_add_test(test.act.shuffle act.shuffle shuffle.cpp)
rv3_add_test(test.act.slice act.slice slice.cpp)
rv3_add_test(test.act.sort act.sort sort.cpp)
rv3_add_test(test.act.split act.split split.cpp)
rv3_add_test(test.act.stable_sort act.stable_sort stable_sort.cpp)
rv3_add_test(test.act.stride act.stride stride.cpp)
rv3_add_test(test.act.take act.take take.cpp)
rv3_add_test(test.act.take_while act.take_while take_while.cpp)
rv3_add_test(test.act.transform act.transform transform.cpp)
rv3_add_test(test.act.unique act.unique unique.cpp)

View File

@@ -0,0 +1,34 @@
/// \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
//
#include <range/v3/action/adjacent_remove_if.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <vector>
int main()
{
using namespace ranges;
auto v = views::ints(1,21) | to<std::vector>();
auto & v2 = actions::adjacent_remove_if(v, [](int x, int y){ return (x + y) % 3 == 0; });
CHECK(std::addressof(v) == std::addressof(v2));
check_equal(v, {2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 17, 18, 20});
v |= actions::adjacent_remove_if([](int x, int y){ return (y - x) == 2; });
check_equal(v, {2, 5, 8, 11, 14, 17, 20});
return ::test_result();
}

View File

@@ -0,0 +1,43 @@
// 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)
#include <array>
#include <vector>
#include <memory>
#include <range/v3/core.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/view/ref.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
int rgi[6];
CPP_assert(range<decltype(rgi)>);
CPP_assert(!semi_container<decltype(rgi)>);
std::array<int, 6> a;
CPP_assert(semi_container<decltype(a)>);
CPP_assert(!container<decltype(a)>);
std::vector<int> v;
CPP_assert(container<decltype(v)>);
std::vector<std::unique_ptr<int>> v2;
CPP_assert(container<decltype(v2)>);
CPP_assert(lvalue_container_like<decltype((v2))>);
CPP_assert(!lvalue_container_like<decltype(std::move(v2))>);
CPP_assert(lvalue_container_like<decltype(views::ref(v2))>);
return ::test_result();
}

View File

@@ -0,0 +1,39 @@
// 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)
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/action/drop.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
auto v = views::ints(1,21) | to<std::vector>();
auto & v2 = actions::drop(v, 3);
CHECK(&v2 == &v);
CHECK(v.size() == 17u);
CHECK(v[0] == 4);
v = std::move(v) | actions::drop(3);
CHECK(v.size() == 14u);
CHECK(v[0] == 7);
v |= actions::drop(3);
CHECK(v.size() == 11u);
CHECK(v[0] == 10);
v |= actions::drop(100);
CHECK(v.size() == 0u);
return ::test_result();
}

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)
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/action/drop_while.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
using namespace std::placeholders;
auto v = views::ints(1,21) | to<std::vector>();
auto & v2 = actions::drop_while(v, std::bind(std::less<int>(), _1, 4));
CHECK(&v2 == &v);
CHECK(v.size() == 17u);
CHECK(v[0] == 4);
v = std::move(v) | actions::drop_while([](int i){return i < 7;});
CHECK(v.size() == 14u);
CHECK(v[0] == 7);
v |= actions::drop_while([](int i){return i < 10;});
CHECK(v.size() == 11u);
CHECK(v[0] == 10);
v |= actions::drop_while([](int){return true;});
CHECK(v.size() == 0u);
return ::test_result();
}

View File

@@ -0,0 +1,90 @@
// 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)
#include <set>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/view/for_each.hpp>
#include <range/v3/view/ref.hpp>
#include <range/v3/action/insert.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
template<typename T>
struct vector_like : std::vector<T> {
using std::vector<T>::vector;
using typename std::vector<T>::size_type;
size_type last_reservation{};
size_type reservation_count{};
void reserve(size_type n) {
std::vector<T>::reserve(n);
last_reservation = n;
++reservation_count;
}
};
int main()
{
using namespace ranges;
{
std::vector<int> v;
auto i = insert(v, v.begin(), 42);
CHECK(i == v.begin());
::check_equal(v, {42});
insert(v, v.end(), {1,2,3});
::check_equal(v, {42,1,2,3});
insert(v, v.begin(), views::ints | views::take(3));
::check_equal(v, {0,1,2,42,1,2,3});
int rg[] = {9,8,7};
insert(v, v.begin()+3, rg);
::check_equal(v, {0,1,2,9,8,7,42,1,2,3});
insert(v, v.begin()+1, rg);
::check_equal(v, {0,9,8,7,1,2,9,8,7,42,1,2,3});
}
{
std::set<int> s;
insert(s,
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
auto j = insert(s, 10);
CHECK(j.first == prev(s.end()));
CHECK(j.second == true);
::check_equal(s, {0,2,4,6,8,10});
insert(views::ref(s), 12);
::check_equal(s, {0,2,4,6,8,10,12});
}
{
const std::size_t N = 1024;
vector_like<int> vl;
insert(vl, vl.end(), views::iota(0, int{N}));
CHECK(vl.reservation_count == 1u);
CHECK(vl.last_reservation == N);
auto r = views::iota(0, int{2 * N});
insert(vl, vl.begin() + 42, begin(r), end(r));
CHECK(vl.reservation_count == 2u);
CHECK(vl.last_reservation == 3 * N);
int i = 42;
insert(vl, vl.end(), &i, &i + 1);
CHECK(vl.reservation_count == 3u);
CHECK(vl.last_reservation > 3 * N + 1);
}
return ::test_result();
}

View File

@@ -0,0 +1,34 @@
// 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)
#include <vector>
#include <string>
#include <range/v3/core.hpp>
#include <range/v3/action/join.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/view/transform.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
std::vector<std::string> v {"hello"," ","world"};
auto s = v | move | actions::join;
static_assert(std::is_same<decltype(s), std::string>::value, "");
CHECK(s == "hello world");
auto s2 = v | views::transform(views::all) | actions::join;
static_assert(std::is_same<decltype(s2), std::vector<char>>::value, "");
CHECK(std::string(s2.begin(), s2.end()) == "hello world");
return ::test_result();
}

View File

@@ -0,0 +1,100 @@
// 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)
#include <list>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/view/for_each.hpp>
#include <range/v3/action/push_back.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
{
std::vector<int> v;
push_back(v, {1,2,3});
::check_equal(v, {1,2,3});
push_back(v, views::iota(10) | views::take(3));
::check_equal(v, {1,2,3,10,11,12});
push_back(v, views::iota(10) | views::take(3));
::check_equal(v, {1,2,3,10,11,12,10,11,12});
int rg[] = {9,8,7};
push_back(v, rg);
::check_equal(v, {1,2,3,10,11,12,10,11,12,9,8,7});
push_back(v, rg);
::check_equal(v, {1,2,3,10,11,12,10,11,12,9,8,7,9,8,7});
std::list<int> s;
push_back(s,
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
push_back(s, 10);
::check_equal(s, {0,2,4,6,8,10});
}
{
std::vector<int> v;
v = std::move(v) | push_back({1,2,3});
::check_equal(v, {1,2,3});
v = std::move(v) | push_back(views::iota(10) | views::take(3));
::check_equal(v, {1,2,3,10,11,12});
v = std::move(v) | push_back(views::iota(10) | views::take(3));
::check_equal(v, {1,2,3,10,11,12,10,11,12});
int rg[] = {9,8,7};
v = std::move(v) | push_back(rg);
::check_equal(v, {1,2,3,10,11,12,10,11,12,9,8,7});
v = std::move(v) | push_back(rg);
::check_equal(v, {1,2,3,10,11,12,10,11,12,9,8,7,9,8,7});
std::list<int> s;
s = std::move(s) | push_back(
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
s = std::move(s) | push_back(10);
::check_equal(s, {0,2,4,6,8,10});
}
{
std::vector<int> v;
v |= push_back({1,2,3});
::check_equal(v, {1,2,3});
v |= push_back(views::iota(10) | views::take(3));
::check_equal(v, {1,2,3,10,11,12});
v |= push_back(views::iota(10) | views::take(3));
::check_equal(v, {1,2,3,10,11,12,10,11,12});
int rg[] = {9,8,7};
v |= push_back(rg);
::check_equal(v, {1,2,3,10,11,12,10,11,12,9,8,7});
v |= push_back(rg);
::check_equal(v, {1,2,3,10,11,12,10,11,12,9,8,7,9,8,7});
std::list<int> s;
s |= push_back(
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
s |= push_back(10);
::check_equal(s, {0,2,4,6,8,10});
}
return ::test_result();
}

View File

@@ -0,0 +1,100 @@
// 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)
#include <list>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/view/for_each.hpp>
#include <range/v3/action/push_front.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
{
std::vector<int> v;
push_front(v, {1,2,3});
::check_equal(v, {1,2,3});
push_front(v, views::iota(10) | views::take(3));
::check_equal(v, {10,11,12,1,2,3});
push_front(v, views::iota(10) | views::take(3));
::check_equal(v, {10,11,12,10,11,12,1,2,3});
int rg[] = {9,8,7};
push_front(v, rg);
::check_equal(v, {9,8,7,10,11,12,10,11,12,1,2,3});
push_front(v, rg);
::check_equal(v, {9,8,7,9,8,7,10,11,12,10,11,12,1,2,3});
std::list<int> s;
push_front(s,
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
push_front(s, -2);
::check_equal(s, {-2,0,2,4,6,8});
}
{
std::vector<int> v;
v = std::move(v) | push_front({1,2,3});
::check_equal(v, {1,2,3});
v = std::move(v) | push_front(views::iota(10) | views::take(3));
::check_equal(v, {10,11,12,1,2,3});
v = std::move(v) | push_front(views::iota(10) | views::take(3));
::check_equal(v, {10,11,12,10,11,12,1,2,3});
int rg[] = {9,8,7};
v = std::move(v) | push_front(rg);
::check_equal(v, {9,8,7,10,11,12,10,11,12,1,2,3});
v = std::move(v) | push_front(rg);
::check_equal(v, {9,8,7,9,8,7,10,11,12,10,11,12,1,2,3});
std::list<int> s;
s = std::move(s) | push_front(
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
s = std::move(s) | push_front(-2);
::check_equal(s, {-2,0,2,4,6,8});
}
{
std::vector<int> v;
v |= push_front({1,2,3});
::check_equal(v, {1,2,3});
v |= push_front(views::iota(10) | views::take(3));
::check_equal(v, {10,11,12,1,2,3});
v |= push_front(views::iota(10) | views::take(3));
::check_equal(v, {10,11,12,10,11,12,1,2,3});
int rg[] = {9,8,7};
v |= push_front(rg);
::check_equal(v, {9,8,7,10,11,12,10,11,12,1,2,3});
v |= push_front(rg);
::check_equal(v, {9,8,7,9,8,7,10,11,12,10,11,12,1,2,3});
std::list<int> s;
s |= push_front(
views::ints|views::take(10)|views::for_each([](int i){return yield_if(i%2==0,i);}));
::check_equal(s, {0,2,4,6,8});
s |= push_front(-2);
::check_equal(s, {-2,0,2,4,6,8});
}
return ::test_result();
}

View File

@@ -0,0 +1,68 @@
// Range v3 library
//
// Copyright Andrey Diduh 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 <vector>
#include <string>
#include <range/v3/action/remove.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
using namespace ranges;
struct Data
{
int i;
Data() = default;
explicit Data(int j) : i(j) {}
bool operator==(const Data& other) const {
return other.i == i;
}
bool operator!=(const Data& other) const {
return other.i != i;
}
};
void simple_test()
{
std::vector<Data> list;
list.emplace_back(Data{1});
list.emplace_back(Data{2});
list.emplace_back(Data{3});
list.emplace_back(Data{4});
Data d2{2};
const auto remove_data = actions::remove(d2);
list |= remove_data;
check_equal(list, {Data{1}, Data{3}, Data{4}});
list |= actions::remove(3, &Data::i);
check_equal(list, {Data{1}, Data{4}});
}
void string_test()
{
std::vector<std::string> list = {"aaa", "bbb", "ccc"};
list |= actions::remove("bbb");
check_equal(list, {"aaa", "ccc"});
}
int main()
{
simple_test();
string_test();
return ::test_result();
}

View File

@@ -0,0 +1,32 @@
// 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)
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/action/sort.hpp>
#include <range/v3/action/remove_if.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
auto v = views::ints(1,21) | to<std::vector>();
auto & v2 = actions::remove_if(v, [](int i){return i % 2 == 0;});
CHECK(&v2 == &v);
check_equal(v, {1,3,5,7,9,11,13,15,17,19});
auto && v3 = v | move | actions::remove_if(std::bind(std::less<int>{}, std::placeholders::_1, 10));
check_equal(v3, {11,13,15,17,19});
return ::test_result();
}

View File

@@ -0,0 +1,35 @@
// 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)
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/repeat_n.hpp>
#include <range/v3/view/for_each.hpp>
#include <range/v3/action/reverse.hpp>
#include <range/v3/action/unique.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
using namespace ranges;
int main()
{
// [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,...]
auto v =
views::for_each(views::ints(1,6), [](int i){
return yield_from(views::repeat_n(i,i));
}) | to<std::vector>();
check_equal(v, {1,2,2,3,3,3,4,4,4,4,5,5,5,5,5});
v |= actions::unique | actions::reverse;
check_equal(v, {5,4,3,2,1});
return ::test_result();
}

View File

@@ -0,0 +1,70 @@
// Range v3 library
//
// Copyright Filip Matzner 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)
#include <vector>
#include <random>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/stride.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/is_sorted.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/algorithm/sort.hpp>
#include <range/v3/action/shuffle.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
std::mt19937 gen;
// "Ints" view vs. shuffled
auto v = views::ints(0,100) | to<std::vector>();
auto v2 = v | copy | actions::shuffle(gen);
CHECK(is_sorted(v));
CHECK(!is_sorted(v2));
CHECK(size(v2) == size(v));
CPP_assert(same_as<decltype(v), decltype(v2)>);
CHECK(!equal(v, v2));
// "Ints" view vs. shuffled and sorted
sort(v2);
CHECK(is_sorted(v2));
CHECK(equal(v, v2));
// Shuffled vs. shuffled
v |= actions::shuffle(gen);
v2 = v2 | move | actions::shuffle(gen);
CHECK(!is_sorted(v));
CHECK(!is_sorted(v2));
CHECK(size(v2) == size(v));
CHECK(!equal(v, v2));
// Container algorithms can also be called directly
// in which case they take and return by reference
v = views::ints(0,100) | to<std::vector>();
auto & v3 = actions::shuffle(v, gen);
CHECK(!is_sorted(v));
CHECK(&v3 == &v);
// Create and shuffle container reference
v = views::ints(0,100) | to<std::vector>();
auto r = views::ref(v);
r |= actions::shuffle(gen);
CHECK(!is_sorted(v));
// Can pipe a view to a "container" algorithm.
v = views::ints(0,100) | to<std::vector>();
v | views::stride(2) | actions::shuffle(gen);
CHECK(!is_sorted(v));
return ::test_result();
}

View File

@@ -0,0 +1,71 @@
// 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)
#include <array>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/stride.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/action/slice.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
{
auto v = views::ints(0, 100) | to<std::vector>();
auto v2 = v | copy | actions::slice(10, 20);
CHECK(size(v2) == 10u);
CPP_assert(same_as<decltype(v), decltype(v2)>);
::check_equal(v2, {10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
v2 = v2 | move | actions::slice(2, 8);
::check_equal(v2, {12, 13, 14, 15, 16, 17});
v2 |= actions::slice(0, 0);
CHECK(v2.size() == 0u);
auto &v3 = actions::slice(v, 90, 100);
CHECK(&v3 == &v);
::check_equal(v, {90, 91, 92, 93, 94, 95, 96, 97, 98, 99});
}
{
auto rng = views::ints(0, 100) | to<std::vector>();
rng |= actions::slice(20, end - 70);
CHECK(size(rng) == 10u);
::check_equal(rng, {20, 21, 22, 23, 24, 25, 26, 27, 28, 29});
rng |= actions::slice(end - 10, end - 5);
CHECK(size(rng) == 5u);
::check_equal(rng, {20, 21, 22, 23, 24});
}
{
auto rng = views::ints(0, 100) | to<std::vector>();
auto &rng_copy = actions::slice(rng, 90, end);
CHECK(&rng_copy == &rng);
CHECK(size(rng_copy) == 10u);
::check_equal(rng, {90, 91, 92, 93, 94, 95, 96, 97, 98, 99});
rng |= actions::slice(end - 5, end);
CHECK(&rng_copy == &rng);
CHECK(size(rng_copy) == 5u);
::check_equal(rng, {95, 96, 97, 98, 99});
}
return ::test_result();
}

View File

@@ -0,0 +1,69 @@
// 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)
#include <array>
#include <random>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/stride.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/algorithm/shuffle.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/is_sorted.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/action/shuffle.hpp>
#include <range/v3/action/sort.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
std::mt19937 gen;
auto v = views::ints(0,100) | to<std::vector>();
v |= actions::shuffle(gen);
CHECK(!is_sorted(v));
auto v2 = v | copy | actions::sort;
CHECK(size(v2) == size(v));
CHECK(is_sorted(v2));
CHECK(!is_sorted(v));
CPP_assert(same_as<decltype(v), decltype(v2)>);
v |= actions::sort;
CHECK(is_sorted(v));
v |= actions::shuffle(gen);
CHECK(!is_sorted(v));
v = v | move | actions::sort(std::less<int>());
CHECK(is_sorted(v));
CHECK(equal(v, v2));
// Container algorithms can also be called directly
// in which case they take and return by reference
shuffle(v, gen);
CHECK(!is_sorted(v));
auto & v3 = actions::sort(v);
CHECK(is_sorted(v));
CHECK(&v3 == &v);
auto r = views::ref(v);
r |= actions::sort;
// Can pipe a view to a "container" algorithm.
actions::sort(v, std::greater<int>());
v | views::stride(2) | actions::sort;
check_equal(views::take(v, 10), {1,98,3,96,5,94,7,92,9,90});
return ::test_result();
}

View File

@@ -0,0 +1,139 @@
// 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)
#include <cctype>
#include <string>
#include <vector>
#include <range/v3/action/split.hpp>
#include <range/v3/action/split_when.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/core.hpp>
#include <range/v3/view/c_str.hpp>
#include <range/v3/view/iota.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
{
auto v = views::ints(1, 21) | to<std::vector>();
std::vector<std::vector<int>> rgv = actions::split(v, 10);
CHECK(rgv.size() == 2u);
::check_equal(rgv[0], {1,2,3,4,5,6,7,8,9});
::check_equal(rgv[1], {11,12,13,14,15,16,17,18,19,20});
using I = std::vector<int>::iterator;
std::vector<std::vector<int>> rgv2 = actions::split_when(
v, [](I b, I) { return std::make_pair(0 == (*b) % 2, next(b)); });
CHECK(rgv2.size() == 10u);
::check_equal(rgv2[0], {1});
::check_equal(rgv2[1], {3});
::check_equal(rgv2[2], {5});
::check_equal(rgv2[3], {7});
::check_equal(rgv2[4], {9});
::check_equal(rgv2[5], {11});
::check_equal(rgv2[6], {13});
::check_equal(rgv2[7], {15});
::check_equal(rgv2[8], {17});
::check_equal(rgv2[9], {19});
}
{
std::string s{"This is his face"};
std::vector<std::string> rgs = actions::split(s, views::c_str(" "));
CHECK(rgs.size() == 4u);
CHECK(rgs[0] == "This");
CHECK(rgs[1] == "is");
CHECK(rgs[2] == "his");
CHECK(rgs[3] == "face");
}
{
std::string s{"This is his face"};
std::vector<std::string> rgs = std::move(s) | actions::split(views::c_str(" "));
CHECK(rgs.size() == 4u);
CHECK(rgs[0] == "This");
CHECK(rgs[1] == "is");
CHECK(rgs[2] == "his");
CHECK(rgs[3] == "face");
}
{
std::string s{"This is his face"};
char ch[] = {' '};
std::vector<std::string> rgs = actions::split(s, ch);
CHECK(rgs.size() == 4u);
CHECK(rgs[0] == "This");
CHECK(rgs[1] == "is");
CHECK(rgs[2] == "his");
CHECK(rgs[3] == "face");
}
{
std::string s{"This is his face"};
char ch[] = {' '};
std::vector<std::string> rgs = std::move(s) | actions::split(ch);
CHECK(rgs.size() == 4u);
CHECK(rgs[0] == "This");
CHECK(rgs[1] == "is");
CHECK(rgs[2] == "his");
CHECK(rgs[3] == "face");
}
{
auto rgi = views::ints(1,21);
std::vector<std::vector<int>> rgv3 = actions::split(rgi, 10);
CHECK(rgv3.size() == 2u);
::check_equal(rgv3[0], {1,2,3,4,5,6,7,8,9});
::check_equal(rgv3[1], {11,12,13,14,15,16,17,18,19,20});
}
{
auto rgi = views::ints(1,21);
std::vector<std::vector<int>> rgv3 = std::move(rgi) | actions::split(10);
CHECK(rgv3.size() == 2u);
::check_equal(rgv3[0], {1,2,3,4,5,6,7,8,9});
::check_equal(rgv3[1], {11,12,13,14,15,16,17,18,19,20});
}
{
std::string str("now is \t the\ttime");
auto toks = actions::split_when(str, +[](int i) { return std::isspace(i); });
static_assert(std::is_same<decltype(toks), std::vector<std::string>>::value, "");
CHECK(toks.size() == 4u);
if(toks.size() == 4u)
{
CHECK(toks[0] == "now");
CHECK(toks[1] == "is");
CHECK(toks[2] == "the");
CHECK(toks[3] == "time");
}
}
{
std::string str("now is \t the\ttime");
auto toks =
std::move(str) | actions::split_when(+[](int i) { return std::isspace(i); });
static_assert(std::is_same<decltype(toks), std::vector<std::string>>::value, "");
CHECK(toks.size() == 4u);
if(toks.size() == 4u)
{
CHECK(toks[0] == "now");
CHECK(toks[1] == "is");
CHECK(toks[2] == "the");
CHECK(toks[3] == "time");
}
}
return ::test_result();
}

View File

@@ -0,0 +1,88 @@
// 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)
#include <array>
#include <random>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/stride.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/algorithm/shuffle.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/is_sorted.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/action/shuffle.hpp>
#include <range/v3/action/stable_sort.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#if !defined(__clang__) || !defined(_MSVC_STL_VERSION) // Avoid #890
void test_bug632()
{
const std::vector<double> scores = { 3.0, 1.0, 2.0 };
std::vector<int> indices = { 0, 1, 2 };
indices |= ranges::actions::stable_sort(
ranges::less{},
[&] (const int &x) { return scores[ (std::size_t)x ]; }
);
::check_equal( indices, {1, 2, 0} );
}
int main()
{
using namespace ranges;
std::mt19937 gen;
auto v = views::ints(0,100) | to<std::vector>();
v |= actions::shuffle(gen);
CHECK(!is_sorted(v));
auto v2 = v | copy | actions::stable_sort;
CHECK(size(v2) == size(v));
CHECK(is_sorted(v2));
CHECK(!is_sorted(v));
CPP_assert(same_as<decltype(v), decltype(v2)>);
v |= actions::stable_sort;
CHECK(is_sorted(v));
v |= actions::shuffle(gen);
CHECK(!is_sorted(v));
v = v | move | actions::stable_sort(std::less<int>());
CHECK(is_sorted(v));
CHECK(equal(v, v2));
// Container algorithms can also be called directly
// in which case they take and return by reference
shuffle(v, gen);
CHECK(!is_sorted(v));
auto & v3 = actions::stable_sort(v);
CHECK(is_sorted(v));
CHECK(&v3 == &v);
auto r = views::ref(v);
r |= actions::stable_sort;
// Can pipe a view to a "container" algorithm.
actions::stable_sort(v, std::greater<int>());
v | views::stride(2) | actions::stable_sort;
check_equal(views::take(v, 10), {1,98,3,96,5,94,7,92,9,90});
test_bug632();
return ::test_result();
}
#else // Avoid #890
int main() {}
#endif // Avoid #890

View File

@@ -0,0 +1,47 @@
// 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)
#include <array>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/action/stride.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
auto v = views::ints(0,100) | to<std::vector>();
auto v2 = v | copy | actions::stride(10);
CHECK(size(v2) == 10u);
CPP_assert(same_as<decltype(v), decltype(v2)>);
::check_equal(v2, {0,10,20,30,40,50,60,70,80,90});
v2 = v2 | move | actions::stride(4);
::check_equal(v2, {0,40,80});
v2 |= actions::stride(2);
::check_equal(v2, {0,80});
v2 |= actions::stride(1);
::check_equal(v2, {0,80});
v2 |= actions::stride(10);
::check_equal(v2, {0});
auto & v3 = actions::stride(v, 30);
CHECK(&v3 == &v);
::check_equal(v, {0,30,60,90});
return ::test_result();
}

View File

@@ -0,0 +1,43 @@
// 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)
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/action/take.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
auto v = views::ints(1,21) | to<std::vector>();
auto & v2 = actions::take(v, 17);
CHECK(&v2 == &v);
CHECK(v.size() == 17u);
CHECK(v.back() == 17);
v = std::move(v) | actions::take(14);
CHECK(v.size() == 14u);
CHECK(v.back() == 14);
v |= actions::take(11);
CHECK(v.size() == 11u);
CHECK(v.back() == 11);
v |= actions::take(100);
CHECK(v.size() == 11u);
v |= actions::take(0);
CHECK(v.size() == 0u);
return ::test_result();
}

View File

@@ -0,0 +1,44 @@
// 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)
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/action/take_while.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
using namespace std::placeholders;
auto v = views::ints(1,21) | to<std::vector>();
auto & v2 = actions::take_while(v, std::bind(std::less<int>(), _1, 18));
CHECK(&v2 == &v);
CHECK(v.size() == 17u);
CHECK(v.back() == 17);
v = std::move(v) | actions::take_while([](int i){return i < 15;});
CHECK(v.size() == 14u);
CHECK(v.back() == 14);
v |= actions::take_while([](int i){return i < 12;});
CHECK(v.size() == 11u);
CHECK(v.back() == 11);
v |= actions::take_while([](int){return true;});
CHECK(v.size() == 11u);
v |= actions::take_while([](int){return false;});
CHECK(v.size() == 0u);
return ::test_result();
}

View File

@@ -0,0 +1,35 @@
// 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)
#include <array>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/algorithm/move.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/action/transform.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
auto v = views::ints(0,10) | to<std::vector>();
auto v0 = v | copy | actions::transform([](int i){return i*i;});
CPP_assert(same_as<decltype(v), decltype(v0)>);
::check_equal(v0, {0,1,4,9,16,25,36,49,64,81});
actions::transform(v, [](int i){return i*i;});
::check_equal(v, {0,1,4,9,16,25,36,49,64,81});
return ::test_result();
}

View File

@@ -0,0 +1,44 @@
// 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)
#include <random>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/repeat_n.hpp>
#include <range/v3/view/for_each.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/algorithm/shuffle.hpp>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/algorithm/is_sorted.hpp>
#include <range/v3/action/shuffle.hpp>
#include <range/v3/action/sort.hpp>
#include <range/v3/action/unique.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
int main()
{
using namespace ranges;
std::mt19937 gen;
// [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,...]
auto v =
views::for_each(views::ints(1,100), [](int i){
return yield_from(views::repeat_n(i,i));
}) | to<std::vector>();
check_equal(views::take(v, 15), {1,2,2,3,3,3,4,4,4,4,5,5,5,5,5});
v |= actions::shuffle(gen);
CHECK(!is_sorted(v));
v |= actions::sort | actions::unique;
CHECK(equal(v, views::ints(1,100)));
return ::test_result();
}

View File

@@ -0,0 +1,281 @@
// Range v3 library
//
// Copyright Andrey Diduh 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 <vector>
#include <cstdlib>
#include <ctime>
#include <random>
#include <range/v3/action/unstable_remove_if.hpp>
#include <range/v3/action/remove_if.hpp>
#include <range/v3/action/sort.hpp>
#include "../array.hpp"
#include "../simple_test.hpp"
#include "../test_utils.hpp"
void logic_test()
{
using namespace ranges;
const auto make_vector = []() -> std::vector<int> {
return {1,2,3,4,5};
};
// empty
{
std::vector<int> vec;
vec |= actions::unstable_remove_if([](int) { return true; });
CHECK(vec.empty());
}
// all stay
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int) { return false; });
check_equal(vec, {1,2,3,4,5});
}
// all remove
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int) { return true; });
CHECK(vec.empty());
}
// remove one in the middle
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i == 2; });
check_equal(vec, {1,5,3,4});
}
// remove first
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i == 1; });
check_equal(vec, {5,2,3,4});
}
// remove last
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i == 5; });
check_equal(vec, {1,2,3,4});
}
// remove group in the middle
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i == 2 || i == 3 || i == 4; });
check_equal(vec, {1,5});
}
// remove group in the begin
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i == 1 || i == 2 || i == 3; });
check_equal(vec, {5,4});
}
// remove group in the end
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i == 3 || i == 4 || i == 5; });
check_equal(vec, {1,2});
}
// remains one in the middle
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return i != 3; });
check_equal(vec, {3});
}
// remains group in the middle
{
std::vector<int> vec = make_vector();
vec |= actions::unstable_remove_if([](int i) { return (i != 3) && (i != 4); });
check_equal(vec, {4,3});
}
}
void num_pred_calls_test()
{
// std::ranges::remove_if requires:
// "Exactly N applications of the corresponding predicate and any projection, where N = (last - first)"
// https://en.cppreference.com/w/cpp/algorithm/ranges/remove
// so expect the same of unstable_remove_if
using namespace ranges;
int pred_invocation_counter = 0;
auto is_zero_count_invocations = [&pred_invocation_counter](int i) {
++pred_invocation_counter;
return i == 0;
};
{
std::vector<int> vec{0};
pred_invocation_counter = 0;
vec |= actions::unstable_remove_if(is_zero_count_invocations);
check_equal(pred_invocation_counter, 1);
}
{
std::vector<int> vec{1,1,1};
pred_invocation_counter = 0;
vec |= actions::unstable_remove_if(is_zero_count_invocations);
check_equal(pred_invocation_counter, 3);
}
{
std::vector<int> vec{1,0};
pred_invocation_counter = 0;
vec |= actions::unstable_remove_if(is_zero_count_invocations);
check_equal(pred_invocation_counter, 2);
}
{
std::vector<int> vec{1,2,0};
pred_invocation_counter = 0;
vec |= actions::unstable_remove_if(is_zero_count_invocations);
check_equal(pred_invocation_counter, 3);
}
{
std::vector<int> vec{0,0,0,0};
pred_invocation_counter = 0;
vec |= actions::unstable_remove_if(is_zero_count_invocations);
check_equal(pred_invocation_counter, 4);
}
{
std::vector<int> vec{1,2,3,0,0,0,0,4,5};
pred_invocation_counter = 0;
vec |= actions::unstable_remove_if(is_zero_count_invocations);
check_equal(pred_invocation_counter, 9);
}
}
class fuzzy_test_fn
{
int size;
#if defined(__GLIBCXX__) && defined(RANGES_WORKAROUND_VALGRIND_RDRAND)
std::random_device rd{"/dev/urandom"};
#else
std::random_device rd;
#endif
std::mt19937 eng{rd()};
std::uniform_int_distribution<int> distr;
public:
explicit fuzzy_test_fn(int sz)
: size(sz)
, distr{0, sz}
{}
void operator()()
{
struct Int
{
int value;
explicit Int(int v)
: value(v)
{}
Int(Int const &) = default;
Int(Int&& other) noexcept
: value(0)
{
*this = std::move(other);
}
Int &operator=(Int const &) = default;
Int &operator=(Int&& other) noexcept
{
const int sentinel = -1;
CHECK(other.value != sentinel);
value = other.value;
other.value = sentinel;
return *this;
}
RANGES_DIAGNOSTIC_PUSH
RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
bool operator==(Int const &other) const
{
return value == other.value;
}
bool operator!=(Int const &other) const
{
return value != other.value;
}
bool operator<(Int const &other) const
{
return value < other.value;
}
bool operator>(Int const &other) const
{
return value > other.value;
}
bool operator<=(Int const &other) const
{
return value <= other.value;
}
bool operator>=(Int const &other) const
{
return value >= other.value;
}
RANGES_DIAGNOSTIC_POP
};
using namespace ranges;
std::vector<Int> ordered_list;
std::vector<Int> unordered_list;
// fill
for(int i=0; i < size; ++i)
{
ordered_list.emplace_back(i);
unordered_list.emplace_back(i);
}
// erase
const int erase_count = distr(eng);
for(int i=0; i < erase_count; ++i)
{
const int value = distr(eng);
const auto pred = [value](Int j) { return j.value == value; };
unordered_list |= actions::unstable_remove_if(pred);
ordered_list |= actions::remove_if(pred);
}
// compare
unordered_list |= actions::sort;
CHECK(ordered_list == unordered_list);
}
};
int main()
{
logic_test();
num_pred_calls_test();
{
const int size = 100;
const int repeats = 1000;
fuzzy_test_fn fuzzy_test(size);
for(int i=0; i < repeats; ++i)
fuzzy_test();
}
return ::test_result();
}

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();
}

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