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
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:
9
Telegram/ThirdParty/range-v3/test/iterator/CMakeLists.txt
vendored
Normal file
9
Telegram/ThirdParty/range-v3/test/iterator/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
set(CMAKE_FOLDER "${CMAKE_FOLDER}/iterator")
|
||||
|
||||
rv3_add_test(test.iter.basic_iterator iter.basic_iterator basic_iterator.cpp)
|
||||
rv3_add_test(test.iter.diffmax_t iter.diffmax_t diffmax_t.cpp)
|
||||
rv3_add_test(test.iter.iterator iter.iterator iterator.cpp)
|
||||
rv3_add_test(test.iter.common_iterator iter.common_iterator common_iterator.cpp)
|
||||
rv3_add_test(test.iter.reverse_iterator iter.reverse_iterator reverse_iterator.cpp)
|
||||
rv3_add_test(test.iter.unformatted_ostream_iterator iter.unformatted_ostream_iterator unformatted_ostream_iterator.cpp)
|
||||
rv3_add_test(test.iter.counted_iterator iter.counted_iterator counted_iterator.cpp)
|
||||
601
Telegram/ThirdParty/range-v3/test/iterator/basic_iterator.cpp
vendored
Normal file
601
Telegram/ThirdParty/range-v3/test/iterator/basic_iterator.cpp
vendored
Normal file
@@ -0,0 +1,601 @@
|
||||
// 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 <tuple>
|
||||
|
||||
#include <range/v3/iterator/basic_iterator.hpp>
|
||||
#include <range/v3/utility/common_tuple.hpp>
|
||||
|
||||
#include "../simple_test.hpp"
|
||||
#include "../test_utils.hpp"
|
||||
|
||||
template<typename T>
|
||||
using iter_cat_t = typename T::iterator_category;
|
||||
template<typename T>
|
||||
using has_iter_cat = meta::is_trait<meta::defer<iter_cat_t, T>>;
|
||||
|
||||
namespace test_weak_input
|
||||
{
|
||||
template<typename I>
|
||||
struct cursor
|
||||
{
|
||||
I it_;
|
||||
struct mixin : ranges::basic_mixin<cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
//using ranges::basic_mixin<cursor>::basic_mixin;
|
||||
explicit mixin(cursor && cur)
|
||||
: ranges::basic_mixin<cursor>(static_cast<cursor &&>(cur))
|
||||
{}
|
||||
explicit mixin(cursor const & cur)
|
||||
: ranges::basic_mixin<cursor>(cur)
|
||||
{}
|
||||
mixin(I i)
|
||||
: mixin(cursor{i})
|
||||
{}
|
||||
};
|
||||
cursor() = default;
|
||||
explicit cursor(I i)
|
||||
: it_(i)
|
||||
{}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::convertible_to<J, I>) //
|
||||
cursor(cursor<J> that)
|
||||
: it_(std::move(that.it_))
|
||||
{}
|
||||
|
||||
auto read() const -> decltype(*it_)
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
};
|
||||
|
||||
CPP_assert(ranges::detail::input_cursor<cursor<char *>>);
|
||||
CPP_assert(!ranges::detail::sentinel_for_cursor<cursor<char *>, cursor<char *>>);
|
||||
|
||||
template<class I>
|
||||
using iterator = ranges::basic_iterator<cursor<I>>;
|
||||
CPP_assert(ranges::indirectly_readable<iterator<char *>>);
|
||||
CPP_assert(ranges::input_iterator<iterator<char *>>);
|
||||
|
||||
static_assert(!has_iter_cat<iterator<char *>>::value, "");
|
||||
static_assert(!has_iter_cat<std::iterator_traits<iterator<char *>>>::value, "");
|
||||
static_assert(
|
||||
std::is_same<iterator<char *>::iterator_concept, std::input_iterator_tag>::value,
|
||||
"");
|
||||
static_assert(!ranges::equality_comparable<iterator<char *>>, "");
|
||||
|
||||
void test()
|
||||
{
|
||||
using namespace ranges;
|
||||
using I = iterator<char const *>;
|
||||
CPP_assert(std::is_same<std::iterator_traits<I>::pointer, char const *>{});
|
||||
|
||||
static char const sz[] = "hello world";
|
||||
I i{sz};
|
||||
CHECK(*i == 'h');
|
||||
CHECK(&*i == i.operator->());
|
||||
++i;
|
||||
CHECK(*i == 'e');
|
||||
CHECK(&*i == i.operator->());
|
||||
}
|
||||
} // namespace test_weak_input
|
||||
|
||||
namespace test_random_access
|
||||
{
|
||||
template<typename I>
|
||||
struct cursor
|
||||
{
|
||||
I it_;
|
||||
struct mixin : ranges::basic_mixin<cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
//using ranges::basic_mixin<cursor>::basic_mixin;
|
||||
explicit mixin(cursor && cur)
|
||||
: ranges::basic_mixin<cursor>(static_cast<cursor &&>(cur))
|
||||
{}
|
||||
explicit mixin(cursor const & cur)
|
||||
: ranges::basic_mixin<cursor>(cur)
|
||||
{}
|
||||
mixin(I i)
|
||||
: mixin(cursor{i})
|
||||
{}
|
||||
};
|
||||
cursor() = default;
|
||||
explicit cursor(I i)
|
||||
: it_(i)
|
||||
{}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::convertible_to<J, I>) //
|
||||
cursor(cursor<J> that)
|
||||
: it_(std::move(that.it_))
|
||||
{}
|
||||
|
||||
auto read() const -> decltype(*it_)
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::sentinel_for<J, I>) //
|
||||
bool equal(cursor<J> const & that) const
|
||||
{
|
||||
return that.it_ == it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
void prev()
|
||||
{
|
||||
--it_;
|
||||
}
|
||||
void advance(ranges::iter_difference_t<I> n)
|
||||
{
|
||||
it_ += n;
|
||||
}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::sized_sentinel_for<J, I>) //
|
||||
ranges::iter_difference_t<I> distance_to(cursor<J> const & that) const
|
||||
{
|
||||
return that.it_ - it_;
|
||||
}
|
||||
};
|
||||
|
||||
CPP_assert(ranges::detail::random_access_cursor<cursor<char *>>);
|
||||
|
||||
template<class I>
|
||||
using iterator = ranges::basic_iterator<cursor<I>>;
|
||||
|
||||
static_assert(std::is_same<iterator<char *>::iterator_category,
|
||||
std::random_access_iterator_tag>::value,
|
||||
"");
|
||||
|
||||
void test()
|
||||
{
|
||||
using namespace ranges;
|
||||
|
||||
iterator<char *> a(nullptr);
|
||||
iterator<char const *> b(nullptr);
|
||||
iterator<char const *> c(a);
|
||||
|
||||
CPP_assert(
|
||||
std::is_same<std::iterator_traits<iterator<char *>>::pointer, char *>{});
|
||||
|
||||
b = a;
|
||||
bool d = a == b;
|
||||
d = (a != b);
|
||||
|
||||
detail::ignore_unused(
|
||||
d, //
|
||||
a < b, //
|
||||
a <= b, //
|
||||
a > b, //
|
||||
a >= b, //
|
||||
(a-b), //
|
||||
(b-a), //
|
||||
(a-a), //
|
||||
(b-b)); //
|
||||
}
|
||||
} // namespace test_random_access
|
||||
|
||||
namespace test_weak_output
|
||||
{
|
||||
template<typename I>
|
||||
struct cursor
|
||||
{
|
||||
struct mixin : ranges::basic_mixin<cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
// using ranges::basic_mixin<cursor>::basic_mixin;
|
||||
explicit mixin(cursor && cur)
|
||||
: ranges::basic_mixin<cursor>(static_cast<cursor &&>(cur))
|
||||
{}
|
||||
explicit mixin(cursor const & cur)
|
||||
: ranges::basic_mixin<cursor>(cur)
|
||||
{}
|
||||
explicit mixin(I i)
|
||||
: mixin(cursor{i})
|
||||
{}
|
||||
};
|
||||
|
||||
cursor() = default;
|
||||
explicit cursor(I i)
|
||||
: it_(i)
|
||||
{}
|
||||
|
||||
void write(ranges::iter_value_t<I> v) const
|
||||
{
|
||||
*it_ = v;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
|
||||
private:
|
||||
I it_;
|
||||
};
|
||||
|
||||
CPP_assert(ranges::detail::output_cursor<cursor<char *>, char>);
|
||||
CPP_assert(!ranges::detail::sentinel_for_cursor<cursor<char *>, cursor<char *>>);
|
||||
|
||||
template<class I>
|
||||
using iterator = ranges::basic_iterator<cursor<I>>;
|
||||
|
||||
CPP_assert(ranges::output_iterator<iterator<char *>, char>);
|
||||
CPP_assert(!ranges::equality_comparable<iterator<char *>>);
|
||||
|
||||
void test()
|
||||
{
|
||||
char buf[10];
|
||||
iterator<char *> i(buf);
|
||||
*i = 'h';
|
||||
++i;
|
||||
*i = 'e';
|
||||
++i;
|
||||
*i = 'l';
|
||||
++i;
|
||||
*i = 'l';
|
||||
++i;
|
||||
*i = 'o';
|
||||
++i;
|
||||
*i = '\0';
|
||||
CHECK(0 == std::strcmp(buf, "hello"));
|
||||
}
|
||||
} // namespace test_weak_output
|
||||
|
||||
namespace test_output
|
||||
{
|
||||
template<typename I>
|
||||
struct cursor
|
||||
{
|
||||
I it_;
|
||||
struct mixin : ranges::basic_mixin<cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
//using ranges::basic_mixin<cursor>::basic_mixin;
|
||||
explicit mixin(cursor && cur)
|
||||
: ranges::basic_mixin<cursor>(static_cast<cursor &&>(cur))
|
||||
{}
|
||||
explicit mixin(cursor const & cur)
|
||||
: ranges::basic_mixin<cursor>(cur)
|
||||
{}
|
||||
mixin(I i)
|
||||
: mixin(cursor{i})
|
||||
{}
|
||||
};
|
||||
cursor() = default;
|
||||
explicit cursor(I i)
|
||||
: it_(i)
|
||||
{}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::convertible_to<J, I>) //
|
||||
cursor(cursor<J> that)
|
||||
: it_(std::move(that.it_))
|
||||
{}
|
||||
|
||||
using value_type = ranges::iter_value_t<I>;
|
||||
value_type read() const
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
void write(value_type v) const
|
||||
{
|
||||
*it_ = v;
|
||||
}
|
||||
I arrow() const
|
||||
{
|
||||
return it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return it_ == that.it_;
|
||||
}
|
||||
};
|
||||
|
||||
CPP_assert(ranges::detail::output_cursor<cursor<char *>, char>);
|
||||
CPP_assert(ranges::detail::forward_cursor<cursor<char *>>);
|
||||
|
||||
template<class I>
|
||||
using iterator = ranges::basic_iterator<cursor<I>>;
|
||||
|
||||
CPP_assert(ranges::output_iterator<iterator<char *>, char>);
|
||||
CPP_assert(ranges::forward_iterator<iterator<char *>>);
|
||||
|
||||
CPP_assert(std::is_same<std::iterator_traits<iterator<char *>>::pointer, char *>());
|
||||
|
||||
void test()
|
||||
{
|
||||
char buf[10];
|
||||
iterator<char *> i(buf);
|
||||
*i = 'h';
|
||||
CHECK(*i == 'h');
|
||||
CHECK(*i == *i);
|
||||
++i;
|
||||
*i = 'e';
|
||||
CHECK('e' == *i);
|
||||
++i;
|
||||
*i = 'l';
|
||||
++i;
|
||||
*i = 'l';
|
||||
++i;
|
||||
*i = 'o';
|
||||
++i;
|
||||
*i = '\0';
|
||||
CHECK(0 == std::strcmp(buf, "hello"));
|
||||
CHECK(i == iterator<char *>{buf + 5});
|
||||
++i;
|
||||
CHECK(i != iterator<char *>{buf + 5});
|
||||
CHECK(i == iterator<char *>{buf + 6});
|
||||
}
|
||||
} // namespace test_output
|
||||
|
||||
namespace test_move_only
|
||||
{
|
||||
struct MoveOnly
|
||||
{
|
||||
MoveOnly() = default;
|
||||
MoveOnly(MoveOnly &&) = default;
|
||||
MoveOnly(MoveOnly const &) = delete;
|
||||
MoveOnly & operator=(MoveOnly &&) = default;
|
||||
MoveOnly & operator=(MoveOnly const &) = delete;
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
struct zip1_cursor
|
||||
{
|
||||
I it_;
|
||||
struct mixin : ranges::basic_mixin<zip1_cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
// using ranges::basic_mixin<zip1_cursor>::basic_mixin;
|
||||
explicit mixin(zip1_cursor && cur)
|
||||
: ranges::basic_mixin<zip1_cursor>(static_cast<zip1_cursor &&>(cur))
|
||||
{}
|
||||
explicit mixin(zip1_cursor const & cur)
|
||||
: ranges::basic_mixin<zip1_cursor>(cur)
|
||||
{}
|
||||
mixin(I i)
|
||||
: mixin(zip1_cursor{i})
|
||||
{}
|
||||
};
|
||||
zip1_cursor() = default;
|
||||
explicit zip1_cursor(I i)
|
||||
: it_(i)
|
||||
{}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::convertible_to<J, I>) //
|
||||
zip1_cursor(zip1_cursor<J> that)
|
||||
: it_(std::move(that.it_))
|
||||
{}
|
||||
|
||||
using value_type = std::tuple<ranges::iter_value_t<I>>;
|
||||
using reference = ranges::common_tuple<ranges::iter_reference_t<I>>;
|
||||
using rvalue_reference = ranges::common_tuple<ranges::iter_rvalue_reference_t<I>>;
|
||||
reference read() const
|
||||
{
|
||||
return reference{*it_};
|
||||
}
|
||||
rvalue_reference move() const
|
||||
{
|
||||
return rvalue_reference{ranges::iter_move(it_)};
|
||||
}
|
||||
void write(reference const & v) const
|
||||
{
|
||||
reference{ *it_} = v;
|
||||
}
|
||||
void write(value_type && v) const
|
||||
{
|
||||
reference{ *it_} = std::move(v);
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
bool equal(zip1_cursor const & that) const
|
||||
{
|
||||
return it_ == that.it_;
|
||||
}
|
||||
};
|
||||
|
||||
CPP_assert(
|
||||
ranges::detail::output_cursor<zip1_cursor<MoveOnly *>, std::tuple<MoveOnly>
|
||||
&&>);
|
||||
CPP_assert(ranges::detail::forward_cursor<zip1_cursor<MoveOnly *>>);
|
||||
|
||||
template<class I>
|
||||
using iterator = ranges::basic_iterator<zip1_cursor<I>>;
|
||||
|
||||
CPP_assert(ranges::output_iterator<iterator<MoveOnly *>, std::tuple<MoveOnly> &&>);
|
||||
CPP_assert(ranges::forward_iterator<iterator<MoveOnly *>>);
|
||||
|
||||
void test()
|
||||
{
|
||||
MoveOnly buf[10] = {};
|
||||
iterator<MoveOnly *> i(buf);
|
||||
*i = std::tuple<MoveOnly>{};
|
||||
ranges::common_tuple<MoveOnly &> x = *i;
|
||||
(void)x;
|
||||
std::tuple<MoveOnly> v = ranges::iter_move(i);
|
||||
*i = std::move(v);
|
||||
}
|
||||
} // namespace test_move_only
|
||||
|
||||
namespace test_forward_sized
|
||||
{
|
||||
template<typename I>
|
||||
struct cursor
|
||||
{
|
||||
I it_;
|
||||
struct mixin : ranges::basic_mixin<cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
// using ranges::basic_mixin<cursor>::basic_mixin;
|
||||
explicit mixin(cursor && cur)
|
||||
: ranges::basic_mixin<cursor>(static_cast<cursor &&>(cur))
|
||||
{}
|
||||
explicit mixin(cursor const & cur)
|
||||
: ranges::basic_mixin<cursor>(cur)
|
||||
{}
|
||||
mixin(I i)
|
||||
: mixin(cursor{i})
|
||||
{}
|
||||
};
|
||||
cursor() = default;
|
||||
explicit cursor(I i)
|
||||
: it_(i)
|
||||
{}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::convertible_to<J, I>) //
|
||||
cursor(cursor<J> that)
|
||||
: it_(std::move(that.it_))
|
||||
{}
|
||||
|
||||
auto read() const -> decltype(*it_)
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::sentinel_for<J, I>) //
|
||||
bool equal(cursor<J> const & that) const
|
||||
{
|
||||
return that.it_ == it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
CPP_template(class J)(
|
||||
/// \pre
|
||||
requires ranges::sized_sentinel_for<J, I>) //
|
||||
ranges::iter_difference_t<I> distance_to(cursor<J> const & that) const
|
||||
{
|
||||
return that.it_ - it_;
|
||||
}
|
||||
};
|
||||
|
||||
CPP_assert(ranges::detail::sized_sentinel_for_cursor<cursor<char *>, cursor<char *>>);
|
||||
CPP_assert(ranges::detail::forward_cursor<cursor<char *>>);
|
||||
|
||||
template<class I>
|
||||
using iterator = ranges::basic_iterator<cursor<I>>;
|
||||
|
||||
static_assert(std::is_same<iterator<char *>::iterator_category,
|
||||
std::forward_iterator_tag>::value,
|
||||
"");
|
||||
|
||||
void test()
|
||||
{
|
||||
using namespace ranges;
|
||||
|
||||
iterator<char *> a(nullptr);
|
||||
iterator<char const *> b(nullptr);
|
||||
iterator<char const *> c(a);
|
||||
|
||||
b = a;
|
||||
bool d = a == b;
|
||||
d = (a != b);
|
||||
|
||||
detail::ignore_unused(
|
||||
d, //
|
||||
a < b, //
|
||||
a <= b, //
|
||||
a > b, //
|
||||
a >= b, //
|
||||
(a-b), //
|
||||
(b-a), //
|
||||
(a-a), //
|
||||
(b-b)); //
|
||||
}
|
||||
} // namespace test_forward_sized
|
||||
|
||||
RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
|
||||
|
||||
void test_box()
|
||||
{
|
||||
struct A : ranges::box<int>
|
||||
{};
|
||||
CHECK(sizeof(A) == sizeof(int));
|
||||
struct empty
|
||||
{};
|
||||
struct B : ranges::box<empty>
|
||||
{
|
||||
int i;
|
||||
};
|
||||
CHECK(sizeof(B) == sizeof(int));
|
||||
B b1, b2;
|
||||
if(ranges::detail::box_compression<empty>() == ranges::detail::box_compress::coalesce)
|
||||
CHECK((&b1.get() == &b2.get()));
|
||||
struct nontrivial
|
||||
{
|
||||
nontrivial()
|
||||
{}
|
||||
};
|
||||
struct C : ranges::box<nontrivial>
|
||||
{
|
||||
int i;
|
||||
};
|
||||
CHECK(sizeof(C) == sizeof(int));
|
||||
C c1, c2;
|
||||
CHECK((&c1.get() != &c2.get()));
|
||||
|
||||
{
|
||||
// empty but not trivial cursor that defines value_type:
|
||||
struct cursor
|
||||
{
|
||||
using value_type = int;
|
||||
cursor()
|
||||
{}
|
||||
int read() const
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
void next()
|
||||
{}
|
||||
};
|
||||
CPP_assert(ranges::detail::box_compression<cursor>() ==
|
||||
ranges::detail::box_compress::ebo);
|
||||
CPP_assert(ranges::same_as<int, ranges::basic_iterator<cursor>::value_type>);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace ranges;
|
||||
std::cout << "\nTesting basic_iterator\n";
|
||||
|
||||
::test_weak_input::test();
|
||||
::test_random_access::test();
|
||||
::test_weak_output::test();
|
||||
::test_output::test();
|
||||
::test_move_only::test();
|
||||
::test_forward_sized::test();
|
||||
::test_box();
|
||||
|
||||
return ::test_result();
|
||||
}
|
||||
155
Telegram/ThirdParty/range-v3/test/iterator/common_iterator.cpp
vendored
Normal file
155
Telegram/ThirdParty/range-v3/test/iterator/common_iterator.cpp
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2015-present
|
||||
// Copyright Casey Carter 2016
|
||||
//
|
||||
// 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 <algorithm>
|
||||
#include <numeric>
|
||||
#include <range/v3/iterator/common_iterator.hpp>
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include "../simple_test.hpp"
|
||||
#include "../test_iterators.hpp"
|
||||
|
||||
RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
|
||||
|
||||
namespace {
|
||||
struct silly_arrow_cursor {
|
||||
int read() const { return 0; }
|
||||
void next() {}
|
||||
int arrow() const { return 42; }
|
||||
};
|
||||
|
||||
int forty_two = 42;
|
||||
struct lvalue_iterator {
|
||||
using difference_type = int;
|
||||
using value_type = int;
|
||||
int& operator*() const { return forty_two; }
|
||||
lvalue_iterator& operator++() & { return *this; }
|
||||
lvalue_iterator operator++(int) & { return *this; }
|
||||
};
|
||||
struct xvalue_iterator : lvalue_iterator {
|
||||
int&& operator*() const { return std::move(forty_two); }
|
||||
xvalue_iterator& operator++() & { return *this; }
|
||||
xvalue_iterator operator++(int) & { return *this; }
|
||||
};
|
||||
|
||||
struct proxy_cursor {
|
||||
int read() const { return 42; }
|
||||
void next() {}
|
||||
};
|
||||
|
||||
void test_operator_arrow() {
|
||||
// I is a pointer type
|
||||
{
|
||||
int i = 42;
|
||||
auto ci = ranges::common_iterator<int*, ranges::unreachable_sentinel_t>{&i};
|
||||
CPP_assert(ranges::same_as<int*, decltype(ci.operator->())>);
|
||||
CHECK(ci.operator->() == &i);
|
||||
}
|
||||
// the expression i.operator->() is well-formed
|
||||
{
|
||||
using I = ranges::basic_iterator<silly_arrow_cursor>;
|
||||
auto ci = ranges::common_iterator<I, ranges::unreachable_sentinel_t>{};
|
||||
CPP_assert(ranges::same_as<I, decltype(ci.operator->())>);
|
||||
CHECK(ci.operator->().operator->() == 42);
|
||||
}
|
||||
// the expression *i is a glvalue [lvalue case]
|
||||
{
|
||||
auto ci = ranges::common_iterator<lvalue_iterator, ranges::unreachable_sentinel_t>{};
|
||||
CPP_assert(ranges::same_as<int*, decltype(ci.operator->())>);
|
||||
CHECK(ci.operator->() == &forty_two);
|
||||
}
|
||||
// the expression *i is a glvalue [xvalue case]
|
||||
{
|
||||
auto ci = ranges::common_iterator<xvalue_iterator, ranges::unreachable_sentinel_t>{};
|
||||
CPP_assert(ranges::same_as<int*, decltype(ci.operator->())>);
|
||||
CHECK(ci.operator->() == &forty_two);
|
||||
}
|
||||
// Otherwise, returns a proxy object
|
||||
{
|
||||
using I = ranges::basic_iterator<proxy_cursor>;
|
||||
auto ci = ranges::common_iterator<I, ranges::unreachable_sentinel_t>{};
|
||||
using A = decltype(ci.operator->());
|
||||
CPP_assert(std::is_class<A>::value);
|
||||
CPP_assert(!std::is_same<I, A>::value);
|
||||
CHECK(*ci.operator->().operator->() == 42);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
{
|
||||
CPP_assert(
|
||||
ranges::forward_iterator<
|
||||
ranges::common_iterator<
|
||||
BidirectionalIterator<const char *>,
|
||||
Sentinel<const char *>>>);
|
||||
CPP_assert(
|
||||
!ranges::bidirectional_iterator<
|
||||
ranges::common_iterator<
|
||||
BidirectionalIterator<const char *>,
|
||||
Sentinel<const char *>>>);
|
||||
CPP_assert(
|
||||
std::is_same<
|
||||
ranges::common_reference<
|
||||
ranges::common_iterator<
|
||||
BidirectionalIterator<const char *>,
|
||||
Sentinel<const char *>
|
||||
>&,
|
||||
ranges::common_iterator<
|
||||
BidirectionalIterator<const char *>,
|
||||
Sentinel<const char *>
|
||||
>
|
||||
>::type,
|
||||
ranges::common_iterator<
|
||||
BidirectionalIterator<const char *>,
|
||||
Sentinel<const char *>
|
||||
>
|
||||
>::value);
|
||||
// Sized iterator range tests
|
||||
CPP_assert(
|
||||
!ranges::sized_sentinel_for<
|
||||
ranges::common_iterator<
|
||||
ForwardIterator<int*>,
|
||||
Sentinel<int*, true> >,
|
||||
ranges::common_iterator<
|
||||
ForwardIterator<int*>,
|
||||
Sentinel<int*, true> > >);
|
||||
CPP_assert(
|
||||
ranges::sized_sentinel_for<
|
||||
ranges::common_iterator<
|
||||
RandomAccessIterator<int*>,
|
||||
Sentinel<int*, true> >,
|
||||
ranges::common_iterator<
|
||||
RandomAccessIterator<int*>,
|
||||
Sentinel<int*, true> > >);
|
||||
CPP_assert(
|
||||
!ranges::sized_sentinel_for<
|
||||
ranges::common_iterator<
|
||||
RandomAccessIterator<int*>,
|
||||
Sentinel<int*, false> >,
|
||||
ranges::common_iterator<
|
||||
RandomAccessIterator<int*>,
|
||||
Sentinel<int*, false> > >);
|
||||
}
|
||||
{
|
||||
int rgi[] {0,1,2,3,4,5,6,7,8,9};
|
||||
using CI = ranges::common_iterator<
|
||||
RandomAccessIterator<int*>,
|
||||
Sentinel<int*>>;
|
||||
CI first{RandomAccessIterator<int*>{rgi}};
|
||||
CI last{Sentinel<int*>{rgi+10}};
|
||||
CHECK(std::accumulate(first, last, 0, std::plus<int>{}) == 45);
|
||||
}
|
||||
|
||||
test_operator_arrow();
|
||||
|
||||
return test_result();
|
||||
}
|
||||
40
Telegram/ThirdParty/range-v3/test/iterator/counted_iterator.cpp
vendored
Normal file
40
Telegram/ThirdParty/range-v3/test/iterator/counted_iterator.cpp
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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/iterator/counted_iterator.hpp>
|
||||
|
||||
#include "../simple_test.hpp"
|
||||
|
||||
// iterator that models input_iterator (has void-returning postfix increment operator)
|
||||
struct Iterator
|
||||
{
|
||||
using value_type = int;
|
||||
using difference_type = int;
|
||||
|
||||
int counter = 0;
|
||||
|
||||
int operator*() const { return counter; }
|
||||
Iterator& operator++() { ++counter; return *this; }
|
||||
void operator++(int) { ++counter; }
|
||||
bool operator==(const Iterator& rhs) const { return counter == rhs.counter; }
|
||||
bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
CPP_assert(ranges::input_iterator<Iterator>);
|
||||
auto cnt = ranges::counted_iterator<Iterator>(Iterator(), 1);
|
||||
CHECK(*cnt == 0);
|
||||
cnt++;
|
||||
CHECK(cnt == ranges::default_sentinel);
|
||||
|
||||
return test_result();
|
||||
}
|
||||
72
Telegram/ThirdParty/range-v3/test/iterator/diffmax_t.cpp
vendored
Normal file
72
Telegram/ThirdParty/range-v3/test/iterator/diffmax_t.cpp
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2019-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/iterator/diffmax_t.hpp>
|
||||
#include "../simple_test.hpp"
|
||||
#include "../test_utils.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <functional>
|
||||
using ranges::detail::diffmax_t;
|
||||
|
||||
template<template<typename> class Op>
|
||||
void check_1(std::ptrdiff_t a, std::ptrdiff_t b)
|
||||
{
|
||||
// std::cout << std::dec;
|
||||
// std::cout << a << "&" << b << " == " << (a&b) << std::endl;
|
||||
// std::cout << std::hex;
|
||||
// std::cout << a << "&" << b << " == " << (a&b) << std::endl;
|
||||
CHECK(Op<diffmax_t>{}(a, b) == Op<std::ptrdiff_t>{}(a, b));
|
||||
}
|
||||
template<>
|
||||
void check_1<std::divides>(std::ptrdiff_t a, std::ptrdiff_t b)
|
||||
{
|
||||
if(b)
|
||||
CHECK(std::divides<diffmax_t>{}(a, b) == std::divides<std::ptrdiff_t>{}(a, b));
|
||||
}
|
||||
template<>
|
||||
void check_1<std::modulus>(std::ptrdiff_t a, std::ptrdiff_t b)
|
||||
{
|
||||
if(b)
|
||||
CHECK(std::modulus<diffmax_t>{}(a, b) == std::modulus<std::ptrdiff_t>{}(a, b));
|
||||
}
|
||||
|
||||
template<template<typename> class Op>
|
||||
void check()
|
||||
{
|
||||
check_1<Op>(0, 0);
|
||||
check_1<Op>(-1, 0);
|
||||
check_1<Op>(0, -1);
|
||||
check_1<Op>(1, 0);
|
||||
check_1<Op>(0, 1);
|
||||
check_1<Op>(1, 1);
|
||||
check_1<Op>(-1, -1);
|
||||
check_1<Op>(-5, -4);
|
||||
check_1<Op>(-4, -5);
|
||||
check_1<Op>(5, -4);
|
||||
check_1<Op>(-4, 5);
|
||||
check_1<Op>(-5, 4);
|
||||
check_1<Op>(4, -5);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
check<std::plus>();
|
||||
check<std::minus>();
|
||||
check<std::multiplies>();
|
||||
check<std::divides>();
|
||||
check<std::modulus>();
|
||||
check<std::bit_and>();
|
||||
check<std::bit_or>();
|
||||
check<std::bit_xor>();
|
||||
|
||||
return test_result();
|
||||
}
|
||||
445
Telegram/ThirdParty/range-v3/test/iterator/iterator.cpp
vendored
Normal file
445
Telegram/ThirdParty/range-v3/test/iterator/iterator.cpp
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014, 2016
|
||||
// Copyright Casey Carter 2016
|
||||
//
|
||||
// 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 <list>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <meta/meta.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/move_iterators.hpp>
|
||||
#include <range/v3/iterator/insert_iterators.hpp>
|
||||
#include <range/v3/iterator/stream_iterators.hpp>
|
||||
#include <range/v3/algorithm/copy.hpp>
|
||||
#include "../simple_test.hpp"
|
||||
#include "../test_utils.hpp"
|
||||
|
||||
using namespace ranges;
|
||||
|
||||
struct MoveOnlyReadable
|
||||
{
|
||||
using value_type = std::unique_ptr<int>;
|
||||
value_type operator*() const;
|
||||
};
|
||||
|
||||
CPP_assert(indirectly_readable<MoveOnlyReadable>);
|
||||
|
||||
void test_insert_iterator()
|
||||
{
|
||||
CPP_assert(output_iterator<insert_iterator<std::vector<int>>, int&&>);
|
||||
CPP_assert(!equality_comparable<insert_iterator<std::vector<int>>>);
|
||||
std::vector<int> vi{5,6,7,8};
|
||||
copy(std::initializer_list<int>{1,2,3,4}, inserter(vi, vi.begin()+2));
|
||||
::check_equal(vi, {5,6,1,2,3,4,7,8});
|
||||
}
|
||||
|
||||
void test_ostream_joiner()
|
||||
{
|
||||
std::ostringstream oss;
|
||||
std::vector<int> vi{};
|
||||
copy(vi, make_ostream_joiner(oss, ","));
|
||||
::check_equal(oss.str(), std::string{""});
|
||||
vi = {1,2,3,4};
|
||||
copy(vi, make_ostream_joiner(oss, ","));
|
||||
::check_equal(oss.str(), std::string{"1,2,3,4"});
|
||||
}
|
||||
|
||||
void test_move_iterator()
|
||||
{
|
||||
std::vector<MoveOnlyString> in;
|
||||
in.emplace_back("this");
|
||||
in.emplace_back("is");
|
||||
in.emplace_back("his");
|
||||
in.emplace_back("face");
|
||||
std::vector<MoveOnlyString> out;
|
||||
auto first = ranges::make_move_iterator(in.begin());
|
||||
using I = decltype(first);
|
||||
CPP_assert(input_iterator<I>);
|
||||
CPP_assert(!forward_iterator<I>);
|
||||
CPP_assert(same_as<I, ranges::move_iterator<std::vector<MoveOnlyString>::iterator>>);
|
||||
auto last = ranges::make_move_sentinel(in.end());
|
||||
using S = decltype(last);
|
||||
CPP_assert(sentinel_for<S, I>);
|
||||
CPP_assert(sized_sentinel_for<I, I>);
|
||||
CHECK((first - first) == 0);
|
||||
CPP_assert(sized_sentinel_for<S, I>);
|
||||
CHECK(static_cast<std::size_t>(last - first) == in.size());
|
||||
ranges::copy(first, last, ranges::back_inserter(out));
|
||||
::check_equal(in, {"","","",""});
|
||||
::check_equal(out, {"this","is","his","face"});
|
||||
}
|
||||
|
||||
template<class I>
|
||||
using RI = std::reverse_iterator<I>;
|
||||
|
||||
void issue_420_regression()
|
||||
{
|
||||
// Verify that sized_sentinel_for<std::reverse_iterator<S>, std::reverse_iterator<I>>
|
||||
// properly requires sized_sentinel_for<I, S>
|
||||
CPP_assert(sized_sentinel_for<RI<int*>, RI<int*>>);
|
||||
CPP_assert(!sized_sentinel_for<RI<int*>, RI<float*>>);
|
||||
using BI = BidirectionalIterator<int*>;
|
||||
CPP_assert(!sized_sentinel_for<RI<BI>, RI<BI>>);
|
||||
}
|
||||
|
||||
struct value_type_tester_thingy {};
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
template<>
|
||||
struct indirectly_readable_traits<::value_type_tester_thingy>
|
||||
{
|
||||
using value_type = int;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct with_value_type { using value_type = T; };
|
||||
template<typename T>
|
||||
struct with_element_type { using element_type = T; };
|
||||
|
||||
// arrays of known bound
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<int[4]>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<const int[4]>::value_type>);
|
||||
CPP_assert(same_as<int*, ranges::indirectly_readable_traits<int*[4]>::value_type>);
|
||||
CPP_assert(same_as<with_value_type<int>, ranges::indirectly_readable_traits<with_value_type<int>[4]>::value_type>);
|
||||
|
||||
#if !defined(__GNUC__) || defined(__clang__)
|
||||
// arrays of unknown bound
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<int[]>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<const int[]>::value_type>);
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
using readable_traits_value_type_t = typename ranges::indirectly_readable_traits<T>::value_type;
|
||||
template<typename T>
|
||||
using readable_traits_value_type = meta::defer<readable_traits_value_type_t, T>;
|
||||
|
||||
// object pointer types
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<int*>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<int*const>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<int const*>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<int const*const>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<int(*)[4]>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<const int(*)[4]>::value_type>);
|
||||
struct incomplete;
|
||||
CPP_assert(same_as<incomplete, ranges::indirectly_readable_traits<incomplete*>::value_type>);
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<void*>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<void const*>>::value, "");
|
||||
|
||||
// class types with member value_type
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<with_value_type<int>>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<with_value_type<int> const>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<value_type_tester_thingy>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<value_type_tester_thingy const>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<with_value_type<int[4]>>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<with_value_type<int[4]> const>::value_type>);
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_value_type<void>>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_value_type<int(int)>>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_value_type<int&>>>::value, "");
|
||||
|
||||
// class types with member element_type
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<with_element_type<int>>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<with_element_type<int> const>::value_type>);
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<with_element_type<int const>>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<with_element_type<int[4]>>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<with_element_type<int[4]> const>::value_type>);
|
||||
CPP_assert(same_as<int[4], ranges::indirectly_readable_traits<with_element_type<int const[4]>>::value_type>);
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_element_type<void>>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_element_type<void const>>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_element_type<void> const>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_element_type<int(int)>>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<with_element_type<int&>>>::value, "");
|
||||
|
||||
// cv-void
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<void>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<void const>>::value, "");
|
||||
// reference types
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<int&>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<int&&>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<int*&>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<int*&&>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<int(&)(int)>>::value, "");
|
||||
static_assert(!meta::is_trait<readable_traits_value_type<std::ostream&>>::value, "");
|
||||
|
||||
CPP_assert(indirectly_swappable<int *, int *>);
|
||||
CPP_assert(indirectly_movable<int const *, int *>);
|
||||
CPP_assert(!indirectly_swappable<int const *, int const *>);
|
||||
CPP_assert(!indirectly_movable<int const *, int const *>);
|
||||
|
||||
namespace Boost
|
||||
{
|
||||
struct S {}; // just to have a type from Boost namespace
|
||||
template<typename I, typename D>
|
||||
void advance(I&, D)
|
||||
{}
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/ericniebler/range-v3/issues/845
|
||||
void test_845()
|
||||
{
|
||||
std::list<std::pair<Boost::S, int>> v = { {Boost::S{}, 0} };
|
||||
auto itr = v.begin();
|
||||
ranges::advance(itr, 1); // Should not create ambiguity
|
||||
}
|
||||
|
||||
// Test for https://github.com/ericniebler/range-v3/issues/1110
|
||||
void test_1110()
|
||||
{
|
||||
// this should not trigger assertation error
|
||||
std::vector<int> v = {1,2,3};
|
||||
auto e = ranges::end(v);
|
||||
ranges::advance(e, 0, ranges::begin(v));
|
||||
}
|
||||
|
||||
// Test the deep integration with the STL
|
||||
#if defined(RANGES_DEEP_STL_INTEGRATION) && RANGES_DEEP_STL_INTEGRATION
|
||||
|
||||
struct X
|
||||
{
|
||||
int& operator*() const;
|
||||
X & operator++();
|
||||
struct proxy { operator int() const; };
|
||||
proxy operator++(int);
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct iterator_traits<::X>
|
||||
{
|
||||
using value_type = int;
|
||||
using reference = int&;
|
||||
using pointer = int*;
|
||||
using difference_type = ptrdiff_t;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
};
|
||||
}
|
||||
|
||||
static_assert(ranges::input_iterator<X>, "");
|
||||
|
||||
struct Y
|
||||
{
|
||||
using value_type = int;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using reference = int&;
|
||||
using pointer = int*;
|
||||
int& operator*() const noexcept;
|
||||
};
|
||||
|
||||
static_assert(std::is_same<std::add_pointer_t<int&>, int*>::value, "");
|
||||
|
||||
struct Z
|
||||
{
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
int& operator*() const noexcept;
|
||||
Z& operator++();
|
||||
Z operator++(int);
|
||||
bool operator==(Z) const;
|
||||
bool operator!=(Z) const;
|
||||
};
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
template <>
|
||||
struct indirectly_readable_traits<::Z>
|
||||
{
|
||||
using value_type = int;
|
||||
};
|
||||
}
|
||||
|
||||
// Looks like an STL2 forward iterator, but the conformance beyond
|
||||
// input is "accidental".
|
||||
struct WouldBeFwd
|
||||
{
|
||||
using value_type = struct S{ };
|
||||
using difference_type = std::ptrdiff_t;
|
||||
S & operator*() const;
|
||||
WouldBeFwd& operator++();
|
||||
WouldBeFwd operator++(int);
|
||||
//S* operator->() const;
|
||||
bool operator==(WouldBeFwd) const;
|
||||
bool operator!=(WouldBeFwd) const;
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct iterator_traits<::WouldBeFwd>
|
||||
{
|
||||
using value_type = ::WouldBeFwd::value_type;
|
||||
using difference_type = ::WouldBeFwd::difference_type;
|
||||
using reference = iter_reference_t<::WouldBeFwd>;
|
||||
using pointer = add_pointer_t<reference>;
|
||||
// Explicit opt-out of stl2's forward_iterator concept:
|
||||
using iterator_category = std::input_iterator_tag; // STL1-style iterator category
|
||||
};
|
||||
}
|
||||
|
||||
// Looks like an STL2 bidirectional iterator, but the conformance beyond
|
||||
// forward is "accidental".
|
||||
struct WouldBeBidi
|
||||
{
|
||||
using value_type = struct S{ };
|
||||
using difference_type = std::ptrdiff_t;
|
||||
// using iterator_category = std::input_iterator_tag;
|
||||
// using iterator_concept = std::forward_iterator_tag;
|
||||
S operator*() const; // by value!
|
||||
WouldBeBidi& operator++();
|
||||
WouldBeBidi operator++(int);
|
||||
WouldBeBidi& operator--();
|
||||
WouldBeBidi operator--(int);
|
||||
//S* operator->() const;
|
||||
bool operator==(WouldBeBidi) const;
|
||||
bool operator!=(WouldBeBidi) const;
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct iterator_traits<::WouldBeBidi>
|
||||
{
|
||||
using value_type = ::WouldBeBidi::value_type;
|
||||
using difference_type = ::WouldBeBidi::difference_type;
|
||||
using reference = value_type;
|
||||
using pointer = value_type*;
|
||||
using iterator_category = std::input_iterator_tag; // STL1-style iterator category
|
||||
// Explicit opt-out of stl2's bidirectional_iterator concept:
|
||||
using iterator_concept = std::forward_iterator_tag; // STL2-style iterator category
|
||||
};
|
||||
}
|
||||
|
||||
struct OutIter
|
||||
{
|
||||
using difference_type = std::ptrdiff_t;
|
||||
OutIter& operator=(int);
|
||||
OutIter& operator*();
|
||||
OutIter& operator++();
|
||||
OutIter& operator++(int);
|
||||
};
|
||||
|
||||
// proxy iterator
|
||||
struct bool_iterator
|
||||
{
|
||||
using value_type = bool;
|
||||
struct reference
|
||||
{
|
||||
operator bool() const { return true; }
|
||||
reference();
|
||||
reference(reference const &);
|
||||
reference& operator=(reference);
|
||||
reference& operator=(bool);
|
||||
};
|
||||
using difference_type = std::ptrdiff_t;
|
||||
reference operator*() const;
|
||||
bool_iterator& operator++();
|
||||
bool_iterator operator++(int);
|
||||
bool operator==(bool_iterator) const;
|
||||
bool operator!=(bool_iterator) const;
|
||||
friend reference iter_move(bool_iterator i) { return *i; }
|
||||
friend void iter_swap(bool_iterator, bool_iterator) { }
|
||||
};
|
||||
|
||||
void deep_integration_test()
|
||||
{
|
||||
using std::is_same;
|
||||
using std::iterator_traits;
|
||||
using ranges::iter_value_t;
|
||||
using ranges::iter_difference_t;
|
||||
static_assert(is_same<iter_difference_t<std::int_least16_t>, int>::value, "");
|
||||
static_assert(is_same<iter_difference_t<std::uint_least16_t>, int>::value, "");
|
||||
static_assert(is_same<iter_difference_t<std::int_least32_t>, std::int_least32_t>::value, "");
|
||||
static_assert(is_same<iter_difference_t<std::uint_least32_t>, meta::_t<std::make_signed<std::uint_least32_t>>>::value, "");
|
||||
static_assert(is_same<iter_difference_t<std::uint_least64_t>, meta::_t<std::make_signed<std::uint_least64_t>>>::value, "");
|
||||
|
||||
static_assert(is_same<iter_value_t<const int*>, int>::value, "");
|
||||
static_assert(is_same<iter_difference_t<const int*>, ptrdiff_t>::value, "");
|
||||
static_assert(is_same<iter_difference_t<int* const>, ptrdiff_t>::value, "");
|
||||
|
||||
static_assert(detail::is_std_iterator_traits_specialized_v<X>, "");
|
||||
static_assert(is_same<iterator_traits<X>::value_type, int>::value, "");
|
||||
static_assert(is_same<iter_value_t<X>, int>::value, "");
|
||||
|
||||
static_assert(!detail::is_std_iterator_traits_specialized_v<Y>, "");
|
||||
static_assert(is_same<iterator_traits<Y>::value_type, int>::value, "");
|
||||
static_assert(is_same<iter_value_t<Y>, int>::value, "");
|
||||
|
||||
// libc++ has a broken std::iterator_traits primary template
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=39619
|
||||
#ifndef _LIBCPP_VERSION
|
||||
// iterator_traits uses specializations of ranges::indirectly_readable_traits:
|
||||
static_assert(!detail::is_std_iterator_traits_specialized_v<Z>, "");
|
||||
static_assert(is_same<iterator_traits<Z>::value_type, int>::value, "");
|
||||
static_assert(is_same<iter_value_t<Z>, int>::value, "");
|
||||
static_assert(is_same<iterator_traits<Z>::iterator_category,
|
||||
std::bidirectional_iterator_tag>::value, "");
|
||||
#endif
|
||||
|
||||
static_assert(ranges::input_iterator<WouldBeFwd>, "");
|
||||
static_assert(!ranges::forward_iterator<WouldBeFwd>, "");
|
||||
static_assert(is_same<iterator_traits<WouldBeFwd>::iterator_category,
|
||||
std::input_iterator_tag>::value, "");
|
||||
|
||||
static_assert(ranges::forward_iterator<WouldBeBidi>, "");
|
||||
static_assert(!ranges::bidirectional_iterator<WouldBeBidi>, "");
|
||||
static_assert(is_same<iterator_traits<WouldBeBidi>::iterator_category,
|
||||
std::input_iterator_tag>::value, "");
|
||||
|
||||
static_assert(ranges::input_or_output_iterator<OutIter>, "");
|
||||
static_assert(!ranges::input_iterator<OutIter>, "");
|
||||
static_assert(is_same<iterator_traits<OutIter>::difference_type,
|
||||
std::ptrdiff_t>::value, "");
|
||||
static_assert(is_same<iterator_traits<OutIter>::iterator_category,
|
||||
std::output_iterator_tag>::value, "");
|
||||
|
||||
static_assert(ranges::contiguous_iterator<int volatile *>, "");
|
||||
|
||||
static_assert(ranges::forward_iterator<bool_iterator>, "");
|
||||
static_assert(is_same<iterator_traits<bool_iterator>::iterator_category,
|
||||
std::input_iterator_tag>::value, "");
|
||||
// static_assert(_Cpp98InputIterator<int volatile*>);
|
||||
// static_assert(_Cpp98InputIterator<bool_iterator>);
|
||||
|
||||
// // Test subsumption:
|
||||
// test(WouldBeFwd{});
|
||||
// test(WouldBeBidi{});
|
||||
// test(meta::detail::nullptr_v<int>);
|
||||
|
||||
// // Test subsumption:
|
||||
// test2(OutIter{});
|
||||
// test2(meta::detail::nullptr_v<int>);
|
||||
|
||||
// // Test subsumption:
|
||||
// test3(WouldBeFwd{}, WouldBeFwd{});
|
||||
// test3(meta::detail::nullptr_v<int>, meta::detail::nullptr_v<int>);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
test_insert_iterator();
|
||||
test_move_iterator();
|
||||
test_ostream_joiner();
|
||||
issue_420_regression();
|
||||
test_1110();
|
||||
|
||||
{
|
||||
struct S { using value_type = int; };
|
||||
CPP_assert(same_as<int, ranges::indirectly_readable_traits<S const>::value_type>);
|
||||
}
|
||||
|
||||
return ::test_result();
|
||||
}
|
||||
480
Telegram/ThirdParty/range-v3/test/iterator/reverse_iterator.cpp
vendored
Normal file
480
Telegram/ThirdParty/range-v3/test/iterator/reverse_iterator.cpp
vendored
Normal file
@@ -0,0 +1,480 @@
|
||||
// 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
|
||||
//
|
||||
// These tests of reverse_iterator have been adapted from libc++
|
||||
// (http://libcxx.llvm.org).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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/range/access.hpp>
|
||||
#include <range/v3/view/iota.hpp>
|
||||
#include "../simple_test.hpp"
|
||||
#include "../test_iterators.hpp"
|
||||
|
||||
template<class It> void test() { ranges::reverse_iterator<It>{}; }
|
||||
|
||||
template<class It> void test2(It i) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
CHECK(r.base() == i);
|
||||
}
|
||||
|
||||
template<class It, class U> void test3(U u) {
|
||||
const ranges::reverse_iterator<U> r2(u);
|
||||
ranges::reverse_iterator<It> r1 = ranges::reverse_iterator<It>(r2);
|
||||
CHECK(r1.base() == u);
|
||||
}
|
||||
|
||||
struct Base {};
|
||||
struct Derived : Base {};
|
||||
|
||||
template<class It> void test4(It i) {
|
||||
const ranges::reverse_iterator<It> r = ranges::make_reverse_iterator(i);
|
||||
CHECK(r.base() == i);
|
||||
}
|
||||
|
||||
template<class It> void test5(It l, It r, bool x) {
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 != r2) == x);
|
||||
}
|
||||
|
||||
template<class It> void test6(It i, It x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> rr = r++;
|
||||
CHECK(r.base() == x);
|
||||
CHECK(rr.base() == i);
|
||||
}
|
||||
|
||||
template<class It> void test7(It i, It x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> &rr = ++r;
|
||||
CHECK(r.base() == x);
|
||||
CHECK(&rr == &r);
|
||||
}
|
||||
|
||||
template<class It>
|
||||
void test8(It i, ranges::iter_difference_t<It> n, It x) {
|
||||
const ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> rr = r + n;
|
||||
CHECK(rr.base() == x);
|
||||
}
|
||||
|
||||
template<class It>
|
||||
void test9(It i, ranges::iter_difference_t<It> n, It x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> &rr = r += n;
|
||||
CHECK(r.base() == x);
|
||||
CHECK(&rr == &r);
|
||||
}
|
||||
|
||||
template<class It> void test10(It i, It x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> rr = r--;
|
||||
CHECK(r.base() == x);
|
||||
CHECK(rr.base() == i);
|
||||
}
|
||||
template<class It> void test11(It i, It x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> &rr = --r;
|
||||
CHECK(r.base() == x);
|
||||
CHECK(&rr == &r);
|
||||
}
|
||||
template<class It>
|
||||
void test12(It i, ranges::iter_difference_t<It> n, It x) {
|
||||
const ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> rr = r - n;
|
||||
CHECK(rr.base() == x);
|
||||
}
|
||||
|
||||
template<class It>
|
||||
void test13(It i, ranges::iter_difference_t<It> n, It x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> &rr = r -= n;
|
||||
CHECK(r.base() == x);
|
||||
CHECK(&rr == &r);
|
||||
}
|
||||
|
||||
class A {
|
||||
int data_ = 1;
|
||||
|
||||
public:
|
||||
A() = default;
|
||||
|
||||
friend bool operator==(const A &x, const A &y) { return x.data_ == y.data_; }
|
||||
};
|
||||
|
||||
template<class It> void test14(It i, ranges::iter_value_t<It> x) {
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
CHECK(*r == x);
|
||||
}
|
||||
|
||||
template<class It, class U> void test15(U u) {
|
||||
const ranges::reverse_iterator<U> r2(u);
|
||||
ranges::reverse_iterator<It> r1;
|
||||
ranges::reverse_iterator<It> &rr = r1 = r2;
|
||||
CHECK(r1.base() == u);
|
||||
CHECK(&rr == &r1);
|
||||
}
|
||||
template<class It> void test16(It l, It r, bool x) {
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 == r2) == x);
|
||||
}
|
||||
|
||||
template<class It1, class It2> void test17(It1 l, It2 r, std::ptrdiff_t x) {
|
||||
const ranges::reverse_iterator<It1> r1(l);
|
||||
const ranges::reverse_iterator<It2> r2(r);
|
||||
CHECK((r1 - r2) == x);
|
||||
}
|
||||
|
||||
template<class It> void test18(It l, It r, bool x) {
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 > r2) == x);
|
||||
}
|
||||
|
||||
template<class It> void test19(It l, It r, bool x) {
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 >= r2) == x);
|
||||
}
|
||||
|
||||
template<class It>
|
||||
void test20(It i, ranges::iter_difference_t<It> n,
|
||||
ranges::iter_value_t<It> x) {
|
||||
const ranges::reverse_iterator<It> r(i);
|
||||
ranges::iter_value_t<It> rr = r[n];
|
||||
CHECK(rr == x);
|
||||
}
|
||||
|
||||
template<class It> void test21(It l, It r, bool x) {
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 < r2) == x);
|
||||
}
|
||||
|
||||
template<class It>
|
||||
void
|
||||
test22(It l, It r, bool x)
|
||||
{
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 < r2) == x);
|
||||
}
|
||||
|
||||
template<class It>
|
||||
void
|
||||
test23(It l, It r, bool x)
|
||||
{
|
||||
const ranges::reverse_iterator<It> r1(l);
|
||||
const ranges::reverse_iterator<It> r2(r);
|
||||
CHECK((r1 <= r2) == x);
|
||||
}
|
||||
|
||||
|
||||
class B
|
||||
{
|
||||
int data_ = 1;
|
||||
public:
|
||||
B() = default;
|
||||
|
||||
int get() const {return data_;}
|
||||
|
||||
friend bool operator==(const B& x, const B& y)
|
||||
{return x.data_ == y.data_;}
|
||||
};
|
||||
|
||||
template<class It>
|
||||
void
|
||||
test24(It i, ranges::iter_value_t<It> x)
|
||||
{
|
||||
ranges::reverse_iterator<It> r(i);
|
||||
CHECK((*r).get() == x.get());
|
||||
}
|
||||
|
||||
|
||||
class C
|
||||
{
|
||||
int data_ = 1;
|
||||
public:
|
||||
C(int d) : data_(d) {}
|
||||
C() = default;
|
||||
|
||||
int get() const {return data_;}
|
||||
|
||||
friend bool operator==(const C& x, const C& y)
|
||||
{return x.data_ == y.data_;}
|
||||
const C *operator&() const { return nullptr; }
|
||||
C *operator&() { return nullptr; }
|
||||
};
|
||||
|
||||
template<class It>
|
||||
void
|
||||
test25(It i, ranges::iter_difference_t<It> n, It x)
|
||||
{
|
||||
const ranges::reverse_iterator<It> r(i);
|
||||
ranges::reverse_iterator<It> rr = n + r;
|
||||
CHECK(rr.base() == x);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
static_assert(
|
||||
ranges::detail::bidirectional_cursor<
|
||||
ranges::detail::reverse_cursor<BidirectionalIterator<const char *>>>,
|
||||
"");
|
||||
static_assert(
|
||||
ranges::detail::bidirectional_cursor<
|
||||
ranges::detail::reverse_cursor<RandomAccessIterator<const char *>>>,
|
||||
"");
|
||||
static_assert(
|
||||
ranges::detail::random_access_cursor<
|
||||
ranges::detail::reverse_cursor<RandomAccessIterator<const char *>>>,
|
||||
"");
|
||||
static_assert(
|
||||
ranges::bidirectional_iterator<
|
||||
ranges::reverse_iterator<BidirectionalIterator<const char *>>>,
|
||||
"");
|
||||
static_assert(
|
||||
ranges::random_access_iterator<
|
||||
ranges::reverse_iterator<RandomAccessIterator<const char *>>>,
|
||||
"");
|
||||
}
|
||||
{ // test
|
||||
test<BidirectionalIterator<const char *>>();
|
||||
test<RandomAccessIterator<char *>>();
|
||||
test<char *>();
|
||||
test<const char *>();
|
||||
}
|
||||
{ // test 2
|
||||
const char s[] = "123";
|
||||
test2(BidirectionalIterator<const char *>(s));
|
||||
test2(RandomAccessIterator<const char *>(s));
|
||||
}
|
||||
{ // test3
|
||||
Derived d;
|
||||
test3<BidirectionalIterator<Base *>>(
|
||||
BidirectionalIterator<Derived *>(&d));
|
||||
//test3<RandomAccessIterator<const Base *>>(
|
||||
// RandomAccessIterator<Derived *>(&d));
|
||||
}
|
||||
//{ // test4
|
||||
// const char *s = "1234567890";
|
||||
// RandomAccessIterator<const char *> b(s);
|
||||
// RandomAccessIterator<const char *> e(s + 10);
|
||||
// while (b != e)
|
||||
// test4(b++);
|
||||
//}
|
||||
//{ // test5
|
||||
// const char *s = "1234567890";
|
||||
// test5(BidirectionalIterator<const char *>(s),
|
||||
// BidirectionalIterator<const char *>(s), false);
|
||||
// test5(BidirectionalIterator<const char *>(s),
|
||||
// BidirectionalIterator<const char *>(s + 1), true);
|
||||
// test5(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s), false);
|
||||
// test5(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s + 1), true);
|
||||
// test5(s, s, false);
|
||||
// test5(s, s + 1, true);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "123";
|
||||
// test6(BidirectionalIterator<const char *>(s + 1),
|
||||
// BidirectionalIterator<const char *>(s));
|
||||
// test6(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s));
|
||||
// test6(s + 1, s);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "123";
|
||||
// test7(BidirectionalIterator<const char *>(s + 1),
|
||||
// BidirectionalIterator<const char *>(s));
|
||||
// test7(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s));
|
||||
// test7(s + 1, s);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test8(RandomAccessIterator<const char *>(s + 5), 5,
|
||||
// RandomAccessIterator<const char *>(s));
|
||||
// test8(s + 5, 5, s);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test9(RandomAccessIterator<const char *>(s + 5), 5,
|
||||
// RandomAccessIterator<const char *>(s));
|
||||
// test9(s + 5, 5, s);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "123";
|
||||
// test10(BidirectionalIterator<const char *>(s + 1),
|
||||
// BidirectionalIterator<const char *>(s + 2));
|
||||
// test10(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s + 2));
|
||||
// test10(s + 1, s + 2);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "123";
|
||||
// test11(BidirectionalIterator<const char *>(s + 1),
|
||||
// BidirectionalIterator<const char *>(s + 2));
|
||||
// test11(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s + 2));
|
||||
// test11(s + 1, s + 2);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test12(RandomAccessIterator<const char *>(s + 5), 5,
|
||||
// RandomAccessIterator<const char *>(s + 10));
|
||||
// test12(s + 5, 5, s + 10);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test13(RandomAccessIterator<const char *>(s + 5), 5,
|
||||
// RandomAccessIterator<const char *>(s + 10));
|
||||
// test13(s + 5, 5, s + 10);
|
||||
//}
|
||||
//{
|
||||
// A a;
|
||||
// test14(&a + 1, A());
|
||||
//}
|
||||
//{
|
||||
// Derived d;
|
||||
|
||||
// test15<BidirectionalIterator<Base *>>(
|
||||
// BidirectionalIterator<Derived *>(&d));
|
||||
// test15<RandomAccessIterator<const Base *>>(
|
||||
// RandomAccessIterator<Derived *>(&d));
|
||||
// test15<Base *>(&d);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test16(BidirectionalIterator<const char *>(s),
|
||||
// BidirectionalIterator<const char *>(s), true);
|
||||
// test16(BidirectionalIterator<const char *>(s),
|
||||
// BidirectionalIterator<const char *>(s + 1), false);
|
||||
// test16(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s), true);
|
||||
// test16(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s + 1), false);
|
||||
// test16(s, s, true);
|
||||
// test16(s, s + 1, false);
|
||||
//}
|
||||
//{
|
||||
// char s[3] = {0};
|
||||
// test17(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<char *>(s), 0);
|
||||
// RandomAccessIterator<char *> inp1(s);
|
||||
// test17(RandomAccessIterator<char *>(s),
|
||||
// RandomAccessIterator<const char *>(s + 1), 1);
|
||||
// test17(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<char *>(s), -1);
|
||||
// test17(s, s, 0);
|
||||
// test17(s, s + 1, 1);
|
||||
// test17(s + 1, s, -1);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test18(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s), false);
|
||||
// test18(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s + 1), true);
|
||||
// test18(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s), false);
|
||||
// test18(s, s, false);
|
||||
// test18(s, s + 1, true);
|
||||
// test18(s + 1, s, false);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test19(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s), true);
|
||||
// test19(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s + 1), true);
|
||||
// test19(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s), false);
|
||||
// test19(s, s, true);
|
||||
// test19(s, s + 1, true);
|
||||
// test19(s + 1, s, false);
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test20(RandomAccessIterator<const char *>(s + 5), 4, '1');
|
||||
// test20(s + 5, 4, '1');
|
||||
//}
|
||||
//{
|
||||
// const char *s = "1234567890";
|
||||
// test21(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s), false);
|
||||
// test21(RandomAccessIterator<const char *>(s),
|
||||
// RandomAccessIterator<const char *>(s + 1), false);
|
||||
// test21(RandomAccessIterator<const char *>(s + 1),
|
||||
// RandomAccessIterator<const char *>(s), true);
|
||||
// test21(s, s, false);
|
||||
// test21(s, s + 1, false);
|
||||
// test21(s + 1, s, true);
|
||||
//}
|
||||
//{
|
||||
// const char* s = "1234567890";
|
||||
// test22(RandomAccessIterator<const char*>(s), RandomAccessIterator<const char*>(s), false);
|
||||
// test22(RandomAccessIterator<const char*>(s), RandomAccessIterator<const char*>(s+1), false);
|
||||
// test22(RandomAccessIterator<const char*>(s+1), RandomAccessIterator<const char*>(s), true);
|
||||
// test22(s, s, false);
|
||||
// test22(s, s+1, false);
|
||||
// test22(s+1, s, true);
|
||||
//}
|
||||
//{
|
||||
// const char* s = "1234567890";
|
||||
// test23(RandomAccessIterator<const char*>(s), RandomAccessIterator<const char*>(s), true);
|
||||
// test23(RandomAccessIterator<const char*>(s), RandomAccessIterator<const char*>(s+1), false);
|
||||
// test23(RandomAccessIterator<const char*>(s+1), RandomAccessIterator<const char*>(s), true);
|
||||
// test23(s, s, true);
|
||||
// test23(s, s+1, false);
|
||||
// test23(s+1, s, true);
|
||||
//}
|
||||
//{
|
||||
// B a;
|
||||
// test24(&a+1, B());
|
||||
//}
|
||||
//{
|
||||
// C l[3] = {C(0), C(1), C(2)};
|
||||
|
||||
// auto ri = ranges::rbegin(l);
|
||||
// CHECK ( ri->get() == 2 );
|
||||
// CHECK ( (*ri).get() == 2 );
|
||||
// CHECK ( ri.operator->() == ranges::prev(ri.base()) );
|
||||
// ++ri;
|
||||
// CHECK ( ri->get() == 1 );
|
||||
// CHECK ( (*ri).get() == 1 );
|
||||
// CHECK ( ri.operator->() == ranges::prev(ri.base()) );
|
||||
// ++ri;
|
||||
// CHECK ( ri->get() == 0 );
|
||||
// CHECK ( (*ri).get() == 0 );
|
||||
// CHECK ( ri.operator->() == ranges::prev(ri.base()) );
|
||||
// ++ri;
|
||||
// CHECK ( ri == ranges::rend(l));
|
||||
//}
|
||||
//{
|
||||
// const char* s = "1234567890";
|
||||
// test25(RandomAccessIterator<const char*>(s+5), 5, RandomAccessIterator<const char*>(s));
|
||||
// test25(s+5, 5, s);
|
||||
//}
|
||||
|
||||
return test_result();
|
||||
}
|
||||
114
Telegram/ThirdParty/range-v3/test/iterator/unformatted_ostream_iterator.cpp
vendored
Normal file
114
Telegram/ThirdParty/range-v3/test/iterator/unformatted_ostream_iterator.cpp
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
// Copyright Google LLC 2020-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 <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <range/v3/algorithm/copy.hpp>
|
||||
#include <range/v3/iterator/stream_iterators.hpp>
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
#include <range/v3/view/for_each.hpp>
|
||||
#include <range/v3/view/reverse.hpp>
|
||||
#include <range/v3/view/sliding.hpp>
|
||||
#include <range/v3/view/stride.hpp>
|
||||
|
||||
#include "../simple_test.hpp"
|
||||
#include "../test_utils.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
template<typename>
|
||||
std::string endian_adjust(std::string const & s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
#else
|
||||
template<typename T>
|
||||
std::string endian_adjust(std::string const & s)
|
||||
{
|
||||
namespace rv = ranges::views;
|
||||
return rv::sliding(s, static_cast<std::ptrdiff_t>(sizeof(T))) //
|
||||
| rv::stride(static_cast<std::ptrdiff_t>(sizeof(T))) //
|
||||
| rv::for_each([](auto x) { return x | rv::reverse; }) //
|
||||
| ranges::to<std::string>;
|
||||
}
|
||||
#endif // endianness
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
constexpr auto expected = "\x21\x22\x23\x24";
|
||||
|
||||
{
|
||||
auto const input = std::vector<char>{0x21, 0x22, 0x23, 0x24};
|
||||
auto output = std::ostringstream();
|
||||
ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));
|
||||
|
||||
auto const actual = output.str();
|
||||
CHECK(actual == expected);
|
||||
}
|
||||
{
|
||||
auto const input = std::vector<unsigned short>{0x2122, 0x2324};
|
||||
auto output = std::ostringstream();
|
||||
ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));
|
||||
|
||||
auto const actual = endian_adjust<unsigned short>(output.str());
|
||||
CHECK(actual == expected);
|
||||
}
|
||||
#if __cplusplus > 201703L
|
||||
{
|
||||
// float computed to be *exactly* 0x21222324.
|
||||
auto const input = std::vector<float>{0x1.4446480000000000179Dp-61f};
|
||||
auto output = std::ostringstream();
|
||||
ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));
|
||||
|
||||
auto const actual = endian_adjust<float>(output.str());
|
||||
CHECK(actual == expected);
|
||||
}
|
||||
#endif // __cplusplus > 201703L
|
||||
}
|
||||
{
|
||||
constexpr auto expected = "\x21\x22\x23\x24\x25\x26\x27\x28";
|
||||
{
|
||||
auto const input = std::vector<unsigned int>{0x21222324, 0x25262728};
|
||||
auto output = std::ostringstream();
|
||||
ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));
|
||||
|
||||
auto const actual = endian_adjust<unsigned int>(output.str());
|
||||
CHECK(actual == expected);
|
||||
}
|
||||
#if __cplusplus > 201703L
|
||||
{
|
||||
// floats computed to be *exactly* 0x21222324 and 0x25262728.
|
||||
auto const input =
|
||||
std::vector<float>{0x1.4446480000000000179Dp-61f, 0x1.4C4E5p-53f};
|
||||
auto output = std::ostringstream();
|
||||
ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));
|
||||
|
||||
auto const actual = endian_adjust<unsigned int>(output.str());
|
||||
CHECK(actual == expected);
|
||||
}
|
||||
{
|
||||
// double computed to be *exactly* 0x2122232425262728.
|
||||
auto const input = std::vector<double>{0x1.223242526272800006F2p-493};
|
||||
auto output = std::ostringstream();
|
||||
ranges::copy(input, ranges::unformatted_ostream_iterator<>(output));
|
||||
|
||||
auto const actual = endian_adjust<double>(output.str());
|
||||
CHECK(actual == expected);
|
||||
}
|
||||
#endif // __cplusplus > 201703L
|
||||
}
|
||||
return ::test_result();
|
||||
}
|
||||
Reference in New Issue
Block a user