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:
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();
|
||||
}
|
||||
Reference in New Issue
Block a user