Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:42

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03___RANGES_ZIP_VIEW_H
0011 #define _LIBCPP___CXX03___RANGES_ZIP_VIEW_H
0012 
0013 #include <__cxx03/__config>
0014 
0015 #include <__cxx03/__algorithm/ranges_min.h>
0016 #include <__cxx03/__compare/three_way_comparable.h>
0017 #include <__cxx03/__concepts/convertible_to.h>
0018 #include <__cxx03/__concepts/equality_comparable.h>
0019 #include <__cxx03/__functional/invoke.h>
0020 #include <__cxx03/__functional/operations.h>
0021 #include <__cxx03/__iterator/concepts.h>
0022 #include <__cxx03/__iterator/incrementable_traits.h>
0023 #include <__cxx03/__iterator/iter_move.h>
0024 #include <__cxx03/__iterator/iter_swap.h>
0025 #include <__cxx03/__iterator/iterator_traits.h>
0026 #include <__cxx03/__ranges/access.h>
0027 #include <__cxx03/__ranges/all.h>
0028 #include <__cxx03/__ranges/concepts.h>
0029 #include <__cxx03/__ranges/empty_view.h>
0030 #include <__cxx03/__ranges/enable_borrowed_range.h>
0031 #include <__cxx03/__ranges/size.h>
0032 #include <__cxx03/__ranges/view_interface.h>
0033 #include <__cxx03/__type_traits/is_nothrow_constructible.h>
0034 #include <__cxx03/__type_traits/make_unsigned.h>
0035 #include <__cxx03/__utility/declval.h>
0036 #include <__cxx03/__utility/forward.h>
0037 #include <__cxx03/__utility/integer_sequence.h>
0038 #include <__cxx03/__utility/move.h>
0039 #include <__cxx03/__utility/pair.h>
0040 #include <__cxx03/tuple>
0041 
0042 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0043 #  pragma GCC system_header
0044 #endif
0045 
0046 _LIBCPP_PUSH_MACROS
0047 #include <__cxx03/__undef_macros>
0048 
0049 _LIBCPP_BEGIN_NAMESPACE_STD
0050 
0051 #if _LIBCPP_STD_VER >= 23
0052 
0053 namespace ranges {
0054 
0055 template <class... _Ranges>
0056 concept __zip_is_common =
0057     (sizeof...(_Ranges) == 1 && (common_range<_Ranges> && ...)) ||
0058     (!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
0059     ((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
0060 
0061 template <typename _Tp, typename _Up>
0062 auto __tuple_or_pair_test() -> pair<_Tp, _Up>;
0063 
0064 template <typename... _Types>
0065   requires(sizeof...(_Types) != 2)
0066 auto __tuple_or_pair_test() -> tuple<_Types...>;
0067 
0068 template <class... _Types>
0069 using __tuple_or_pair = decltype(__tuple_or_pair_test<_Types...>());
0070 
0071 template <class _Fun, class _Tuple>
0072 _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
0073   return std::apply(
0074       [&]<class... _Types>(_Types&&... __elements) {
0075         return __tuple_or_pair<invoke_result_t<_Fun&, _Types>...>(
0076             std::invoke(__f, std::forward<_Types>(__elements))...);
0077       },
0078       std::forward<_Tuple>(__tuple));
0079 }
0080 
0081 template <class _Fun, class _Tuple>
0082 _LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
0083   std::apply(
0084       [&]<class... _Types>(_Types&&... __elements) {
0085         (static_cast<void>(std::invoke(__f, std::forward<_Types>(__elements))), ...);
0086       },
0087       std::forward<_Tuple>(__tuple));
0088 }
0089 
0090 template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices>
0091 _LIBCPP_HIDE_FROM_ABI constexpr __tuple_or_pair<
0092     invoke_result_t<_Fun&,
0093                     typename tuple_element<_Indices, remove_cvref_t<_Tuple1>>::type,
0094                     typename tuple_element<_Indices, remove_cvref_t<_Tuple2>>::type>...>
0095 __tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, index_sequence<_Indices...>) {
0096   return {std::invoke(__f,
0097                       std::get<_Indices>(std::forward<_Tuple1>(__tuple1)),
0098                       std::get<_Indices>(std::forward<_Tuple2>(__tuple2)))...};
0099 }
0100 
0101 template <class _Fun, class _Tuple1, class _Tuple2>
0102 _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) {
0103   return ranges::__tuple_zip_transform(
0104       __f,
0105       std::forward<_Tuple1>(__tuple1),
0106       std::forward<_Tuple2>(__tuple2),
0107       std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
0108 }
0109 
0110 template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices>
0111 _LIBCPP_HIDE_FROM_ABI constexpr void
0112 __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, index_sequence<_Indices...>) {
0113   (std::invoke(
0114        __f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)), std::get<_Indices>(std::forward<_Tuple2>(__tuple2))),
0115    ...);
0116 }
0117 
0118 template <class _Fun, class _Tuple1, class _Tuple2>
0119 _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) {
0120   return ranges::__tuple_zip_for_each(
0121       __f,
0122       std::forward<_Tuple1>(__tuple1),
0123       std::forward<_Tuple2>(__tuple2),
0124       std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
0125 }
0126 
0127 template <class _Tuple1, class _Tuple2>
0128 _LIBCPP_HIDE_FROM_ABI constexpr bool __tuple_any_equals(const _Tuple1& __tuple1, const _Tuple2& __tuple2) {
0129   const auto __equals = ranges::__tuple_zip_transform(std::equal_to<>(), __tuple1, __tuple2);
0130   return std::apply([](auto... __bools) { return (__bools || ...); }, __equals);
0131 }
0132 
0133 // abs in cstdlib is not constexpr
0134 // TODO : remove __abs once P0533R9 is implemented.
0135 template <class _Tp>
0136 _LIBCPP_HIDE_FROM_ABI constexpr _Tp __abs(_Tp __t) {
0137   return __t < 0 ? -__t : __t;
0138 }
0139 
0140 template <input_range... _Views>
0141   requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
0142 class zip_view : public view_interface<zip_view<_Views...>> {
0143   _LIBCPP_NO_UNIQUE_ADDRESS tuple<_Views...> __views_;
0144 
0145   template <bool>
0146   class __iterator;
0147 
0148   template <bool>
0149   class __sentinel;
0150 
0151 public:
0152   _LIBCPP_HIDE_FROM_ABI zip_view() = default;
0153 
0154   _LIBCPP_HIDE_FROM_ABI constexpr explicit zip_view(_Views... __views) : __views_(std::move(__views)...) {}
0155 
0156   _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
0157     requires(!(__simple_view<_Views> && ...))
0158   {
0159     return __iterator<false>(ranges::__tuple_transform(ranges::begin, __views_));
0160   }
0161 
0162   _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
0163     requires(range<const _Views> && ...)
0164   {
0165     return __iterator<true>(ranges::__tuple_transform(ranges::begin, __views_));
0166   }
0167 
0168   _LIBCPP_HIDE_FROM_ABI constexpr auto end()
0169     requires(!(__simple_view<_Views> && ...))
0170   {
0171     if constexpr (!__zip_is_common<_Views...>) {
0172       return __sentinel<false>(ranges::__tuple_transform(ranges::end, __views_));
0173     } else if constexpr ((random_access_range<_Views> && ...)) {
0174       return begin() + iter_difference_t<__iterator<false>>(size());
0175     } else {
0176       return __iterator<false>(ranges::__tuple_transform(ranges::end, __views_));
0177     }
0178   }
0179 
0180   _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
0181     requires(range<const _Views> && ...)
0182   {
0183     if constexpr (!__zip_is_common<const _Views...>) {
0184       return __sentinel<true>(ranges::__tuple_transform(ranges::end, __views_));
0185     } else if constexpr ((random_access_range<const _Views> && ...)) {
0186       return begin() + iter_difference_t<__iterator<true>>(size());
0187     } else {
0188       return __iterator<true>(ranges::__tuple_transform(ranges::end, __views_));
0189     }
0190   }
0191 
0192   _LIBCPP_HIDE_FROM_ABI constexpr auto size()
0193     requires(sized_range<_Views> && ...)
0194   {
0195     return std::apply(
0196         [](auto... __sizes) {
0197           using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
0198           return ranges::min({_CT(__sizes)...});
0199         },
0200         ranges::__tuple_transform(ranges::size, __views_));
0201   }
0202 
0203   _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
0204     requires(sized_range<const _Views> && ...)
0205   {
0206     return std::apply(
0207         [](auto... __sizes) {
0208           using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
0209           return ranges::min({_CT(__sizes)...});
0210         },
0211         ranges::__tuple_transform(ranges::size, __views_));
0212   }
0213 };
0214 
0215 template <class... _Ranges>
0216 zip_view(_Ranges&&...) -> zip_view<views::all_t<_Ranges>...>;
0217 
0218 template <bool _Const, class... _Views>
0219 concept __zip_all_random_access = (random_access_range<__maybe_const<_Const, _Views>> && ...);
0220 
0221 template <bool _Const, class... _Views>
0222 concept __zip_all_bidirectional = (bidirectional_range<__maybe_const<_Const, _Views>> && ...);
0223 
0224 template <bool _Const, class... _Views>
0225 concept __zip_all_forward = (forward_range<__maybe_const<_Const, _Views>> && ...);
0226 
0227 template <bool _Const, class... _Views>
0228 consteval auto __get_zip_view_iterator_tag() {
0229   if constexpr (__zip_all_random_access<_Const, _Views...>) {
0230     return random_access_iterator_tag();
0231   } else if constexpr (__zip_all_bidirectional<_Const, _Views...>) {
0232     return bidirectional_iterator_tag();
0233   } else if constexpr (__zip_all_forward<_Const, _Views...>) {
0234     return forward_iterator_tag();
0235   } else {
0236     return input_iterator_tag();
0237   }
0238 }
0239 
0240 template <bool _Const, class... _Views>
0241 struct __zip_view_iterator_category_base {};
0242 
0243 template <bool _Const, class... _Views>
0244   requires __zip_all_forward<_Const, _Views...>
0245 struct __zip_view_iterator_category_base<_Const, _Views...> {
0246   using iterator_category = input_iterator_tag;
0247 };
0248 
0249 template <input_range... _Views>
0250   requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
0251 template <bool _Const>
0252 class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base<_Const, _Views...> {
0253   __tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current_;
0254 
0255   _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(
0256       __tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current)
0257       : __current_(std::move(__current)) {}
0258 
0259   template <bool>
0260   friend class zip_view<_Views...>::__iterator;
0261 
0262   template <bool>
0263   friend class zip_view<_Views...>::__sentinel;
0264 
0265   friend class zip_view<_Views...>;
0266 
0267 public:
0268   using iterator_concept = decltype(__get_zip_view_iterator_tag<_Const, _Views...>());
0269   using value_type       = __tuple_or_pair<range_value_t<__maybe_const<_Const, _Views>>...>;
0270   using difference_type  = common_type_t<range_difference_t<__maybe_const<_Const, _Views>>...>;
0271 
0272   _LIBCPP_HIDE_FROM_ABI __iterator() = default;
0273 
0274   _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
0275     requires _Const && (convertible_to<iterator_t<_Views>, iterator_t<__maybe_const<_Const, _Views>>> && ...)
0276       : __current_(std::move(__i.__current_)) {}
0277 
0278   _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
0279     return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
0280   }
0281 
0282   _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
0283     ranges::__tuple_for_each([](auto& __i) { ++__i; }, __current_);
0284     return *this;
0285   }
0286 
0287   _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
0288 
0289   _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
0290     requires __zip_all_forward<_Const, _Views...>
0291   {
0292     auto __tmp = *this;
0293     ++*this;
0294     return __tmp;
0295   }
0296 
0297   _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
0298     requires __zip_all_bidirectional<_Const, _Views...>
0299   {
0300     ranges::__tuple_for_each([](auto& __i) { --__i; }, __current_);
0301     return *this;
0302   }
0303 
0304   _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
0305     requires __zip_all_bidirectional<_Const, _Views...>
0306   {
0307     auto __tmp = *this;
0308     --*this;
0309     return __tmp;
0310   }
0311 
0312   _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
0313     requires __zip_all_random_access<_Const, _Views...>
0314   {
0315     ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i += iter_difference_t<_Iter>(__x); }, __current_);
0316     return *this;
0317   }
0318 
0319   _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
0320     requires __zip_all_random_access<_Const, _Views...>
0321   {
0322     ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i -= iter_difference_t<_Iter>(__x); }, __current_);
0323     return *this;
0324   }
0325 
0326   _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const
0327     requires __zip_all_random_access<_Const, _Views...>
0328   {
0329     return ranges::__tuple_transform(
0330         [&]<class _Iter>(_Iter& __i) -> decltype(auto) { return __i[iter_difference_t<_Iter>(__n)]; }, __current_);
0331   }
0332 
0333   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
0334     requires(equality_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
0335   {
0336     if constexpr (__zip_all_bidirectional<_Const, _Views...>) {
0337       return __x.__current_ == __y.__current_;
0338     } else {
0339       return ranges::__tuple_any_equals(__x.__current_, __y.__current_);
0340     }
0341   }
0342 
0343   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
0344     requires __zip_all_random_access<_Const, _Views...>
0345   {
0346     return __x.__current_ < __y.__current_;
0347   }
0348 
0349   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
0350     requires __zip_all_random_access<_Const, _Views...>
0351   {
0352     return __y < __x;
0353   }
0354 
0355   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
0356     requires __zip_all_random_access<_Const, _Views...>
0357   {
0358     return !(__y < __x);
0359   }
0360 
0361   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
0362     requires __zip_all_random_access<_Const, _Views...>
0363   {
0364     return !(__x < __y);
0365   }
0366 
0367   _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
0368     requires __zip_all_random_access<_Const, _Views...> &&
0369              (three_way_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
0370   {
0371     return __x.__current_ <=> __y.__current_;
0372   }
0373 
0374   _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
0375     requires __zip_all_random_access<_Const, _Views...>
0376   {
0377     auto __r = __i;
0378     __r += __n;
0379     return __r;
0380   }
0381 
0382   _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
0383     requires __zip_all_random_access<_Const, _Views...>
0384   {
0385     return __i + __n;
0386   }
0387 
0388   _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
0389     requires __zip_all_random_access<_Const, _Views...>
0390   {
0391     auto __r = __i;
0392     __r -= __n;
0393     return __r;
0394   }
0395 
0396   _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
0397     requires(sized_sentinel_for<iterator_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_Const, _Views>>> &&
0398              ...)
0399   {
0400     const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __x.__current_, __y.__current_);
0401     return std::apply(
0402         [](auto... __ds) {
0403           return ranges::min({difference_type(__ds)...}, [](auto __a, auto __b) {
0404             return ranges::__abs(__a) < ranges::__abs(__b);
0405           });
0406         },
0407         __diffs);
0408   }
0409 
0410   _LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __iterator& __i) noexcept(
0411       (noexcept(ranges::iter_move(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
0412       (is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) {
0413     return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
0414   }
0415 
0416   _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
0417       (noexcept(ranges::iter_swap(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
0418                                   std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
0419        ...))
0420     requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
0421   {
0422     ranges::__tuple_zip_for_each(ranges::iter_swap, __l.__current_, __r.__current_);
0423   }
0424 };
0425 
0426 template <input_range... _Views>
0427   requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
0428 template <bool _Const>
0429 class zip_view<_Views...>::__sentinel {
0430   __tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end_;
0431 
0432   _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(
0433       __tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end)
0434       : __end_(__end) {}
0435 
0436   friend class zip_view<_Views...>;
0437 
0438   // hidden friend cannot access private member of iterator because they are friends of friends
0439   template <bool _OtherConst>
0440   _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
0441   __iter_current(zip_view<_Views...>::__iterator<_OtherConst> const& __it) {
0442     return (__it.__current_);
0443   }
0444 
0445 public:
0446   _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
0447 
0448   _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
0449     requires _Const && (convertible_to<sentinel_t<_Views>, sentinel_t<__maybe_const<_Const, _Views>>> && ...)
0450       : __end_(std::move(__i.__end_)) {}
0451 
0452   template <bool _OtherConst>
0453     requires(sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
0454              ...)
0455   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
0456     return ranges::__tuple_any_equals(__iter_current(__x), __y.__end_);
0457   }
0458 
0459   template <bool _OtherConst>
0460     requires(
0461         sized_sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
0462         ...)
0463   _LIBCPP_HIDE_FROM_ABI friend constexpr common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>
0464   operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
0465     const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __iter_current(__x), __y.__end_);
0466     return std::apply(
0467         [](auto... __ds) {
0468           using _Diff = common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>;
0469           return ranges::min({_Diff(__ds)...}, [](auto __a, auto __b) {
0470             return ranges::__abs(__a) < ranges::__abs(__b);
0471           });
0472         },
0473         __diffs);
0474   }
0475 
0476   template <bool _OtherConst>
0477     requires(
0478         sized_sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
0479         ...)
0480   _LIBCPP_HIDE_FROM_ABI friend constexpr common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>
0481   operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) {
0482     return -(__x - __y);
0483   }
0484 };
0485 
0486 template <class... _Views>
0487 inline constexpr bool enable_borrowed_range<zip_view<_Views...>> = (enable_borrowed_range<_Views> && ...);
0488 
0489 namespace views {
0490 namespace __zip {
0491 
0492 struct __fn {
0493   _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()() noexcept { return empty_view<tuple<>>{}; }
0494 
0495   template <class... _Ranges>
0496   _LIBCPP_HIDE_FROM_ABI static constexpr auto
0497   operator()(_Ranges&&... __rs) noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)))
0498       -> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)) {
0499     return zip_view<all_t<_Ranges>...>(std::forward<_Ranges>(__rs)...);
0500   }
0501 };
0502 
0503 } // namespace __zip
0504 inline namespace __cpo {
0505 inline constexpr auto zip = __zip::__fn{};
0506 } // namespace __cpo
0507 } // namespace views
0508 } // namespace ranges
0509 
0510 #endif // _LIBCPP_STD_VER >= 23
0511 
0512 _LIBCPP_END_NAMESPACE_STD
0513 
0514 _LIBCPP_POP_MACROS
0515 
0516 #endif // _LIBCPP___CXX03___RANGES_ZIP_VIEW_H