================ @@ -0,0 +1,333 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 _LIBCPP___RANGES_ENUMERATE_VIEW_H +#define _LIBCPP___RANGES_ENUMERATE_VIEW_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/iter_move.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/all.h> +#include <__ranges/concepts.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/range_adaptor.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.h> +#include <__type_traits/maybe_const.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <tuple> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +namespace ranges { + +// [concept.object] + +template <class _Rp> +concept __range_with_movable_references = + ranges::input_range<_Rp> && std::move_constructible<ranges::range_reference_t<_Rp>> && + std::move_constructible<ranges::range_rvalue_reference_t<_Rp>>; + +// [range.enumerate.view] + +template <view _View> + requires __range_with_movable_references<_View> +class enumerate_view : public view_interface<enumerate_view<_View>> { + _View __base_ = _View(); + + // [range.enumerate.iterator] + template <bool _Const> + class __iterator; + + // [range.enumerate.sentinel] + template <bool _Const> + class __sentinel; + + template <bool _AnyConst> + _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) { + return (__iter.__current_); + } + +public: + _LIBCPP_HIDE_FROM_ABI constexpr enumerate_view() + requires(default_initializable<_View>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr explicit enumerate_view(_View __base) : __base_(std::move(__base)){}; + + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + requires(!__simple_view<_View>) + { + return __iterator<false>(ranges::begin(__base_), 0); + } + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const + requires __range_with_movable_references<const _View> + { + return __iterator<true>(ranges::begin(__base_), 0); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() + requires(!__simple_view<_View>) + { + if constexpr (common_range<_View> && sized_range<_View>) + return __iterator<false>(ranges::end(__base_), ranges::distance(__base_)); + else + return __sentinel<false>(ranges::end(__base_)); + } + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + requires __range_with_movable_references<const _View> + { + if constexpr (common_range<const _View> && sized_range<const _View>) + return __iterator<true>(ranges::end(__base_), ranges::distance(__base_)); + else + return __sentinel<true>(ranges::end(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() + requires sized_range<_View> + { + return ranges::size(__base_); + } + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + requires sized_range<const _View> + { + return ranges::size(__base_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + requires copy_constructible<_View> + { + return __base_; + } + _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } +}; + +template <class _Range> +enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>; + +// [range.enumerate.iterator] + +template <view _View> + requires __range_with_movable_references<_View> +template <bool _Const> +class enumerate_view<_View>::__iterator { + using _Base = __maybe_const<_Const, _View>; + + static consteval auto __get_iterator_concept() { + if constexpr (random_access_range<_Base>) { + return random_access_iterator_tag{}; + } else if constexpr (bidirectional_range<_Base>) { + return bidirectional_iterator_tag{}; + } else if constexpr (forward_range<_Base>) { + return forward_iterator_tag{}; + } else { + return input_iterator_tag{}; + } + } + + friend class enumerate_view<_View>; + +public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(__get_iterator_concept()); + using difference_type = range_difference_t<_Base>; + using value_type = tuple<difference_type, range_value_t<_Base>>; + +private: + using __reference_type = tuple<difference_type, range_reference_t<_Base>>; + iterator_t<_Base> __current_ = iterator_t<_Base>(); + difference_type __pos_ = 0; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current, difference_type __pos) + : __current_(std::move(__current)), __pos_(__pos) {} + +public: + _LIBCPP_HIDE_FROM_ABI __iterator() + requires(default_initializable<iterator_t<_Base>>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i) + requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>> + : __current_(std::move(__i.__current_)), __pos_(__i.__pos_) {} + + _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI constexpr difference_type index() const noexcept { return __pos_; } + + _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const { return __reference_type(__pos_, *__current_); } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { + ++__current_; + ++__pos_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { return ++*this; } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) + requires forward_range<_Base> + { + auto __temp = *this; + ++*this; + return __temp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() + requires bidirectional_range<_Base> + { + --__current_; + --__pos_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) ---------------- cjdb wrote:
Per the above conversation with @philnik777, I'm withdrawing this comment for the time being. https://github.com/llvm/llvm-project/pull/73617 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits