106 changes: 106 additions & 0 deletions libcxx/test/std/ranges/range.adaptors/range.elements/types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ELEMENTS_TYPES_H
#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ELEMENTS_TYPES_H

#include <array>
#include <functional>
#include <ranges>
#include <tuple>

#include "test_macros.h"
#include "test_iterators.h"
#include "test_range.h"

template <class T>
struct BufferView : std::ranges::view_base {
T* buffer_;
std::size_t size_;

template <std::size_t N>
constexpr BufferView(T (&b)[N]) : buffer_(b), size_(N) {}

template <std::size_t N>
constexpr BufferView(std::array<T, N>& arr) : buffer_(arr.data()), size_(N) {}
};

using TupleBufferView = BufferView<std::tuple<int>>;

template <bool Simple>
struct Common : TupleBufferView {
using TupleBufferView::TupleBufferView;

constexpr std::tuple<int>* begin()
requires(!Simple)
{
return buffer_;
}
constexpr const std::tuple<int>* begin() const { return buffer_; }
constexpr std::tuple<int>* end()
requires(!Simple)
{
return buffer_ + size_;
}
constexpr const std::tuple<int>* end() const { return buffer_ + size_; }
};
using SimpleCommon = Common<true>;
using NonSimpleCommon = Common<false>;

using SimpleCommonRandomAccessSized = SimpleCommon;
using NonSimpleCommonRandomAccessSized = NonSimpleCommon;

static_assert(std::ranges::common_range<Common<true>>);
static_assert(std::ranges::random_access_range<SimpleCommon>);
static_assert(std::ranges::sized_range<SimpleCommon>);
LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleCommon>);
LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleCommon>);

template <bool Simple>
struct NonCommon : TupleBufferView {
using TupleBufferView::TupleBufferView;
constexpr std::tuple<int>* begin()
requires(!Simple)
{
return buffer_;
}
constexpr const std::tuple<int>* begin() const { return buffer_; }
constexpr sentinel_wrapper<std::tuple<int>*> end()
requires(!Simple)
{
return sentinel_wrapper<std::tuple<int>*>(buffer_ + size_);
}
constexpr sentinel_wrapper<const std::tuple<int>*> end() const {
return sentinel_wrapper<const std::tuple<int>*>(buffer_ + size_);
}
};

using SimpleNonCommon = NonCommon<true>;
using NonSimpleNonCommon = NonCommon<false>;

static_assert(!std::ranges::common_range<SimpleNonCommon>);
static_assert(std::ranges::random_access_range<SimpleNonCommon>);
static_assert(!std::ranges::sized_range<SimpleNonCommon>);
LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleNonCommon>);
LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleNonCommon>);

template <class Derived>
struct IterBase {
using iterator_concept = std::random_access_iterator_tag;
using value_type = std::tuple<int>;
using difference_type = intptr_t;

constexpr std::tuple<int> operator*() const { return std::tuple<int>(5); }

constexpr Derived& operator++() { return *this; }
constexpr void operator++(int) {}

friend constexpr bool operator==(const IterBase&, const IterBase&) = default;
};

#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ELEMENTS_TYPES_H
2 changes: 2 additions & 0 deletions llvm/utils/gn/secondary/libcxx/include/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -629,10 +629,12 @@ if (current_toolchain == default_toolchain) {
"__tree",
"__tuple_dir/apply_cv.h",
"__tuple_dir/make_tuple_types.h",
"__tuple_dir/pair_like.h",
"__tuple_dir/sfinae_helpers.h",
"__tuple_dir/tuple_element.h",
"__tuple_dir/tuple_indices.h",
"__tuple_dir/tuple_like.h",
"__tuple_dir/tuple_like_ext.h",
"__tuple_dir/tuple_size.h",
"__tuple_dir/tuple_types.h",
"__type_traits/add_const.h",
Expand Down