| /* |
| * Copyright (c) 2023 NVIDIA Corporation |
| * |
| * Licensed under the Apache License Version 2.0 with LLVM Exceptions |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * https://llvm.org/LICENSE.txt |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #pragma once |
| |
| #include "__config.hpp" |
| #include "__type_traits.hpp" |
| |
| #if 0 // STDEXEC_HAS_STD_RANGES() |
| |
| #include <ranges> |
| |
| namespace stdexec::ranges { |
| using std::ranges::begin; |
| using std::ranges::end; |
| |
| using std::ranges::range_value_t; |
| using std::ranges::range_reference_t; |
| using std::ranges::iterator_t; |
| using std::ranges::sentinel_t; |
| } |
| |
| #else |
| |
| #include <iterator> |
| |
| namespace stdexec::ranges |
| { |
| |
| namespace __detail |
| { |
| void begin(); |
| void end(); |
| |
| template <class _Ty> |
| concept __has_member_begin = |
| requires(_Ty&& __v) { static_cast<_Ty&&>(__v).begin(); }; |
| |
| template <class _Ty> |
| concept __has_free_begin = |
| __has_member_begin<_Ty> || |
| requires(_Ty&& __v) { begin((static_cast<_Ty&&>(__v))); }; |
| |
| template <class _Ty> |
| concept __has_member_end = |
| requires(_Ty&& __v) { static_cast<_Ty&&>(__v).end(); }; |
| |
| template <class _Ty> |
| concept __has_free_end = |
| __has_member_end<_Ty> || |
| requires(_Ty&& __v) { end((static_cast<_Ty&&>(__v))); }; |
| |
| struct __begin_t |
| { |
| template <class _Range> |
| requires __has_member_begin<_Range> |
| auto operator()(_Range&& __rng) const |
| noexcept(noexcept((static_cast<_Range&&>(__rng)).begin())) |
| -> decltype((static_cast<_Range&&>(__rng)).begin()) |
| { |
| return static_cast<_Range&&>(__rng).begin(); |
| } |
| |
| template <class _Range> |
| requires __has_free_begin<_Range> |
| auto operator()(_Range&& __rng) const |
| noexcept(noexcept(begin((static_cast<_Range&&>(__rng))))) |
| -> decltype(begin((static_cast<_Range&&>(__rng)))) |
| { |
| return begin((static_cast<_Range&&>(__rng))); |
| } |
| }; |
| |
| struct __end_t |
| { |
| template <class _Range> |
| requires __has_member_end<_Range> |
| auto operator()(_Range&& __rng) const |
| noexcept(noexcept((static_cast<_Range&&>(__rng)).end())) |
| -> decltype((static_cast<_Range&&>(__rng)).end()) |
| { |
| return static_cast<_Range&&>(__rng).end(); |
| } |
| |
| template <class _Range> |
| requires __has_free_end<_Range> |
| auto operator()(_Range&& __rng) const |
| noexcept(noexcept(end((static_cast<_Range&&>(__rng))))) |
| -> decltype(end((static_cast<_Range&&>(__rng)))) |
| { |
| return end((static_cast<_Range&&>(__rng))); |
| } |
| }; |
| } // namespace __detail |
| |
| inline constexpr __detail::__begin_t begin{}; |
| inline constexpr __detail::__end_t end{}; |
| |
| template <class _Range> |
| using iterator_t = decltype(begin((__declval<_Range>()))); |
| |
| template <class _Range> |
| using sentinel_t = decltype(end((__declval<_Range>()))); |
| |
| template <class _Range> |
| using range_reference_t = decltype(*begin((__declval<_Range>()))); |
| |
| template <class _Range> |
| using range_value_t = |
| typename std::iterator_traits<iterator_t<_Range>>::value_type; |
| |
| } // namespace stdexec::ranges |
| |
| #endif |