#pragma once #include "../../macro/stl_detector.hpp" #if defined(YYCC_STL_CLANGSTL) /** * @private * @file This is the polyfill for LLVM libcxx std::enumerate. * This should be removed once libcxx provide it. * This polyfill is generated by AI. */ #include #include #include #include namespace std { namespace ranges { namespace views { namespace detail { template concept can_reference = requires { typename T&; }; template concept enumerable = ranges::input_range && integral && ranges::view; } // namespace detail // enumerate_view实现 template requires detail::enumerable class enumerate_view : public ranges::view_interface> { private: V _base; I _start; // 迭代器实现 template class iterator { private: using Base = conditional_t; using Parent = conditional_t; Parent* _parent = nullptr; ranges::iterator_t _current; I _index; public: using iterator_category = typename iterator_traits>::iterator_category; using iterator_concept = iterator_category; using value_type = tuple>; using difference_type = ranges::range_difference_t; iterator() = default; constexpr iterator(Parent* parent, ranges::iterator_t current, I index) : _parent(parent), _current(current), _index(index) {} constexpr iterator(iterator other) requires Const && convertible_to, ranges::iterator_t> : _parent(other._parent), _current(other._current), _index(other._index) {} constexpr ranges::iterator_t base() const { return _current; } constexpr auto operator*() const { return tuple>(_index, *_current); } constexpr iterator& operator++() { ++_current; ++_index; return *this; } constexpr iterator operator++(int) { auto tmp = *this; ++*this; return tmp; } constexpr iterator& operator--() requires ranges::bidirectional_range { --_current; --_index; return *this; } constexpr iterator operator--(int) requires ranges::bidirectional_range { auto tmp = *this; --*this; return tmp; } constexpr iterator& operator+=(difference_type n) requires ranges::random_access_range { _current += n; _index += static_cast(n); return *this; } constexpr iterator& operator-=(difference_type n) requires ranges::random_access_range { _current -= n; _index -= static_cast(n); return *this; } constexpr auto operator[](difference_type n) const requires ranges::random_access_range { return tuple>( _index + static_cast(n), _current[n]); } friend constexpr bool operator==(const iterator& x, const iterator& y) { return x._current == y._current; } friend constexpr bool operator<(const iterator& x, const iterator& y) requires ranges::random_access_range { return x._current < y._current; } friend constexpr bool operator>(const iterator& x, const iterator& y) requires ranges::random_access_range { return x._current > y._current; } friend constexpr bool operator<=(const iterator& x, const iterator& y) requires ranges::random_access_range { return x._current <= y._current; } friend constexpr bool operator>=(const iterator& x, const iterator& y) requires ranges::random_access_range { return x._current >= y._current; } friend constexpr iterator operator+(const iterator& i, difference_type n) requires ranges::random_access_range { auto r = i; r += n; return r; } friend constexpr iterator operator+(difference_type n, const iterator& i) requires ranges::random_access_range { return i + n; } friend constexpr iterator operator-(const iterator& i, difference_type n) requires ranges::random_access_range { auto r = i; r -= n; return r; } friend constexpr difference_type operator-(const iterator& x, const iterator& y) requires ranges::random_access_range { return x._current - y._current; } }; public: enumerate_view() = default; constexpr enumerate_view(V base, I start = 0) : _base(std::move(base)), _start(start) {} constexpr V base() const & requires copy_constructible { return _base; } constexpr V base() && { return std::move(_base); } constexpr I start() const { return _start; } constexpr auto begin() requires (!ranges::simple_view) { return iterator(this, ranges::begin(_base), _start); } constexpr auto begin() const requires ranges::range { return iterator(this, ranges::begin(_base), _start); } constexpr auto end() requires (!ranges::simple_view) { return iterator(this, ranges::end(_base), _start + static_cast(ranges::distance(_base))); } constexpr auto end() const requires ranges::range { return iterator(this, ranges::end(_base), _start + static_cast(ranges::distance(_base))); } constexpr auto size() requires ranges::sized_range { return ranges::size(_base); } constexpr auto size() const requires ranges::sized_range { return ranges::size(_base); } }; // 推导指引 template enumerate_view(R&&, I) -> enumerate_view, I>; template enumerate_view(R&&) -> enumerate_view, size_t>; // enumerate适配器对象 struct enumerate_fn { template requires detail::enumerable, I> constexpr auto operator()(R&& r, I start = 0) const { return enumerate_view(views::all(forward(r)), start); } template constexpr auto operator()(I start = 0) const { return ranges::views::__adaptor_invoke(*this, start); } }; // 适配器对象实例 inline constexpr enumerate_fn enumerate; } // namespace views // 使enumerate_view成为view template inline constexpr bool enable_borrowed_range> = ranges::enable_borrowed_range; } // namespace ranges } // namespace std #endif