#include <cassert>
#include <iterator>
#include <ranges>
#include <type_traits>
#include <utility>
#include "types.h"
template <class T>
concept HasEnd = requires(T t) { t.end(); };
template <class T>
concept HasConstEnd = requires(const T ct) { ct.end(); };
struct NoConstEndView : TupleBufferView {
using TupleBufferView::TupleBufferView;
constexpr std::tuple<int>* begin() { return buffer_; }
constexpr std::tuple<int>* end() { return buffer_ + size_; }
};
static_assert(HasEnd<std::ranges::elements_view<NoConstEndView, 0>>);
static_assert(!HasConstEnd<std::ranges::elements_view<NoConstEndView, 0>>);
constexpr bool test() {
std::tuple<int> buffer[] = {{1}, {2}, {3}};
{
SimpleCommon v{buffer};
auto ev = std::views::elements<0>(v);
auto it = ev.begin();
decltype(auto) st = ev.end();
assert(st == it + 3);
auto const_it = std::as_const(ev).begin();
decltype(auto) const_st = std::as_const(ev).end();
assert(const_st == const_it + 3);
static_assert(std::same_as<decltype(st), decltype(const_st)>);
static_assert(std::same_as<decltype(st), decltype(it)>);
static_assert(std::same_as<decltype(const_st), decltype(const_it)>);
}
{
SimpleNonCommon v{buffer};
auto ev = std::views::elements<0>(v);
auto it = ev.begin();
decltype(auto) st = ev.end();
assert(st == it + 3);
auto const_it = std::as_const(ev).begin();
decltype(auto) const_st = std::as_const(ev).end();
assert(const_st == const_it + 3);
static_assert(std::same_as<decltype(st), decltype(const_st)>);
static_assert(!std::same_as<decltype(st), decltype(it)>);
static_assert(!std::same_as<decltype(const_st), decltype(const_it)>);
}
{
NonSimpleCommon v{buffer};
auto ev = std::views::elements<0>(v);
auto it = ev.begin();
decltype(auto) st = ev.end();
assert(st == it + 3);
auto const_it = std::as_const(ev).begin();
decltype(auto) const_st = std::as_const(ev).end();
assert(const_st == const_it + 3);
static_assert(!std::same_as<decltype(st), decltype(const_st)>);
static_assert(std::same_as<decltype(st), decltype(it)>);
static_assert(std::same_as<decltype(const_st), decltype(const_it)>);
}
{
NonSimpleNonCommon v{buffer};
auto ev = std::views::elements<0>(v);
auto it = ev.begin();
decltype(auto) st = ev.end();
assert(st == it + 3);
auto const_it = std::as_const(ev).begin();
decltype(auto) const_st = std::as_const(ev).end();
assert(const_st == const_it + 3);
static_assert(!std::same_as<decltype(st), decltype(const_st)>);
static_assert(!std::same_as<decltype(st), decltype(it)>);
static_assert(!std::same_as<decltype(const_st), decltype(const_it)>);
}
{
std::tuple<int, int> x[] = {{0, 0}};
std::ranges::subrange r = {std::counted_iterator(x, 1), std::default_sentinel};
auto v = r | std::views::elements<0>;
assert(v.begin() != v.end());
}
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}