2025-12-20 22:21:57 +08:00
|
|
|
#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 <ranges>
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <tuple>
|
|
|
|
|
#include <cstddef>
|
2025-12-20 22:32:18 +08:00
|
|
|
#include <iterator>
|
|
|
|
|
|
|
|
|
|
namespace std::ranges::views {
|
|
|
|
|
|
|
|
|
|
// 简化的enumerate实现
|
|
|
|
|
namespace detail {
|
|
|
|
|
|
|
|
|
|
template<typename R>
|
|
|
|
|
class enumerate_view {
|
|
|
|
|
private:
|
|
|
|
|
R _range;
|
|
|
|
|
size_t _start;
|
|
|
|
|
|
|
|
|
|
template<bool Const>
|
|
|
|
|
class iterator {
|
|
|
|
|
using Base = conditional_t<Const, const R, R>;
|
|
|
|
|
using Iter = decltype(std::ranges::begin(std::declval<Base&>()));
|
|
|
|
|
|
|
|
|
|
Iter _iter;
|
|
|
|
|
size_t _index;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
using iterator_category = typename std::iterator_traits<Iter>::iterator_category;
|
|
|
|
|
using value_type = std::tuple<size_t, decltype(*_iter)>;
|
|
|
|
|
using difference_type = typename std::iterator_traits<Iter>::difference_type;
|
|
|
|
|
|
|
|
|
|
iterator(Iter iter, size_t index) : _iter(iter), _index(index) {}
|
|
|
|
|
|
|
|
|
|
auto operator*() const { return std::tuple<size_t, decltype(*_iter)>(_index, *_iter); }
|
|
|
|
|
|
|
|
|
|
iterator& operator++() {
|
|
|
|
|
++_iter;
|
|
|
|
|
++_index;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator operator++(int) {
|
|
|
|
|
auto tmp = *this;
|
|
|
|
|
++*this;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator==(const iterator& other) const { return _iter == other._iter; }
|
|
|
|
|
|
|
|
|
|
bool operator!=(const iterator& other) const { return _iter != other._iter; }
|
|
|
|
|
|
|
|
|
|
// 支持双向迭代
|
|
|
|
|
iterator& operator--()
|
|
|
|
|
requires std::bidirectional_iterator<Iter>
|
|
|
|
|
{
|
|
|
|
|
--_iter;
|
|
|
|
|
--_index;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator operator--(int)
|
|
|
|
|
requires std::bidirectional_iterator<Iter>
|
|
|
|
|
{
|
|
|
|
|
auto tmp = *this;
|
|
|
|
|
--*this;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
enumerate_view(R range, size_t start = 0) : _range(std::move(range)), _start(start) {}
|
|
|
|
|
|
|
|
|
|
auto begin() { return iterator<false>(std::ranges::begin(_range), _start); }
|
|
|
|
|
auto end() { return iterator<false>(std::ranges::end(_range), _start + std::ranges::distance(_range)); }
|
|
|
|
|
|
|
|
|
|
auto begin() const { return iterator<true>(std::ranges::begin(_range), _start); }
|
|
|
|
|
auto end() const { return iterator<true>(std::ranges::end(_range), _start + std::ranges::distance(_range)); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 适配器函数对象
|
|
|
|
|
struct enumerate_fn {
|
|
|
|
|
template<std::ranges::range R>
|
|
|
|
|
auto operator()(R&& r, size_t start = 0) const {
|
|
|
|
|
return enumerate_view<std::ranges::views::all_t<R>>(std::forward<R>(r), start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 用于管道操作符的版本
|
|
|
|
|
auto operator()(size_t start = 0) const {
|
|
|
|
|
return [start](auto&& r) {
|
|
|
|
|
return enumerate_view<std::ranges::views::all_t<decltype(r)>>(std::forward<decltype(r)>(r), start);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
|
|
|
|
inline constexpr detail::enumerate_fn enumerate;
|
|
|
|
|
|
|
|
|
|
} // namespace std::ranges::views
|
2025-12-20 22:21:57 +08:00
|
|
|
|
|
|
|
|
#endif
|