================ @@ -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>>) ---------------- cjdb wrote:
```suggestion requires default_initializable<iterator_t<_Base>> ``` 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