// -*- 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 // SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// #ifndef _LIBCUDACXX___RANGES_CONCEPTS_H #define _LIBCUDACXX___RANGES_CONCEPTS_H #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include _LIBCUDACXX_BEGIN_NAMESPACE_RANGES #if !defined(_CCCL_NO_CONCEPTS) // [range.range] template concept range = requires(_Tp& __t) { _CUDA_VRANGES::begin(__t); // sometimes equality-preserving _CUDA_VRANGES::end(__t); }; template concept input_range = range<_Tp> && input_iterator>; template concept borrowed_range = range<_Range> && (is_lvalue_reference_v<_Range> || enable_borrowed_range>); // `iterator_t` defined in <__ranges/access.h> template using sentinel_t = decltype(_CUDA_VRANGES::end(_CUDA_VSTD::declval<_Rp&>())); template using range_difference_t = iter_difference_t>; template using range_value_t = iter_value_t>; template using range_reference_t = iter_reference_t>; template using range_rvalue_reference_t = iter_rvalue_reference_t>; template using range_common_reference_t = iter_common_reference_t>; // [range.sized] template concept sized_range = range<_Tp> && requires(_Tp& __t) { _CUDA_VRANGES::size(__t); }; template using range_size_t = decltype(_CUDA_VRANGES::size(_CUDA_VSTD::declval<_Rp&>())); // `disable_sized_range` defined in `<__ranges/size.h>` // [range.view], views // `enable_view` defined in <__ranges/enable_view.h> // `view_base` defined in <__ranges/enable_view.h> template concept view = range<_Tp> && movable<_Tp> && enable_view<_Tp>; template concept __simple_view = view<_Range> && range && same_as, iterator_t> && same_as, sentinel_t>; // [range.refinements], other range refinements template concept output_range = range<_Rp> && output_iterator, _Tp>; template concept forward_range = input_range<_Tp> && forward_iterator>; template concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator>; template concept random_access_range = bidirectional_range<_Tp> && random_access_iterator>; template concept contiguous_range = random_access_range<_Tp> && contiguous_iterator> && requires(_Tp& __t) { { _CUDA_VRANGES::data(__t) } -> same_as>>; }; template concept common_range = range<_Tp> && same_as, sentinel_t<_Tp>>; template _CCCL_INLINE_VAR constexpr bool __is_std_initializer_list = false; template _CCCL_INLINE_VAR constexpr bool __is_std_initializer_list> = true; template concept viewable_range = range<_Tp> && ((view> && constructible_from, _Tp>) || (!view> && (is_lvalue_reference_v<_Tp> || (movable> && !__is_std_initializer_list>) ))); #else // ^^^ !_CCCL_NO_CONCEPTS ^^^ / vvv _CCCL_NO_CONCEPTS vvv // [range.range] // clang-format off template _CCCL_CONCEPT range = _CCCL_REQUIRES_EXPR((_Tp), _Tp& __t) ( void(_CUDA_VRANGES::begin(__t)), void(_CUDA_VRANGES::end(__t)) ); template _CCCL_CONCEPT input_range = _CCCL_REQUIRES_EXPR((_Tp)) ( requires(range<_Tp>), requires(input_iterator>) ); // clang-format on template _CCCL_CONCEPT_FRAGMENT( __borrowed_range_, requires()(requires(range<_Range>), requires((is_lvalue_reference_v<_Range> || enable_borrowed_range>) ))); template _CCCL_CONCEPT borrowed_range = _CCCL_FRAGMENT(__borrowed_range_, _Range); // `iterator_t` defined in <__ranges/access.h> template using sentinel_t = enable_if_t, decltype(_CUDA_VRANGES::end(_CUDA_VSTD::declval<_Rp&>()))>; template using range_difference_t = enable_if_t, iter_difference_t>>; template using range_value_t = enable_if_t, iter_value_t>>; template using range_reference_t = enable_if_t, iter_reference_t>>; template using range_rvalue_reference_t = enable_if_t, iter_rvalue_reference_t>>; template using range_common_reference_t = enable_if_t, iter_common_reference_t>>; // [range.sized] template _CCCL_CONCEPT_FRAGMENT(__sized_range_, requires(_Tp& __t)(requires(range<_Tp>), typename(decltype(_CUDA_VRANGES::size(__t))))); template _CCCL_CONCEPT sized_range = _CCCL_FRAGMENT(__sized_range_, _Tp); template using range_size_t = enable_if_t, decltype(_CUDA_VRANGES::size(_CUDA_VSTD::declval<_Rp&>()))>; // `disable_sized_range` defined in `<__ranges/size.h>` // [range.view], views // `enable_view` defined in <__ranges/enable_view.h> // `view_base` defined in <__ranges/enable_view.h> template _CCCL_CONCEPT_FRAGMENT(__view_, requires()(requires(range<_Tp>), requires(movable<_Tp>), requires(enable_view<_Tp>))); template _CCCL_CONCEPT view = _CCCL_FRAGMENT(__view_, _Tp); template _CCCL_CONCEPT_FRAGMENT( __simple_view_, requires()(requires(view<_Range>), requires(range), requires(same_as, iterator_t>), requires(same_as, sentinel_t>))); template _CCCL_CONCEPT __simple_view = _CCCL_FRAGMENT(__simple_view_, _Range); // [range.refinements], other range refinements template _CCCL_CONCEPT_FRAGMENT(__output_range_, requires()(requires(range<_Rp>), requires(output_iterator, _Tp>))); template _CCCL_CONCEPT output_range = _CCCL_FRAGMENT(__output_range_, _Rp, _Tp); template _CCCL_CONCEPT_FRAGMENT(__forward_range_, requires()(requires(input_range<_Tp>), requires(forward_iterator>))); template _CCCL_CONCEPT forward_range = _CCCL_FRAGMENT(__forward_range_, _Tp); template _CCCL_CONCEPT_FRAGMENT(__bidirectional_range_, requires()(requires(forward_range<_Tp>), requires(bidirectional_iterator>))); template _CCCL_CONCEPT bidirectional_range = _CCCL_FRAGMENT(__bidirectional_range_, _Tp); template _CCCL_CONCEPT_FRAGMENT( __random_access_range_, requires()(requires(bidirectional_range<_Tp>), requires(random_access_iterator>))); template _CCCL_CONCEPT random_access_range = _CCCL_FRAGMENT(__random_access_range_, _Tp); template _CCCL_CONCEPT_FRAGMENT( __contiguous_range_, requires(_Tp& __t)(requires(random_access_range<_Tp>), requires(contiguous_iterator>), requires(same_as>>))); template _CCCL_CONCEPT contiguous_range = _CCCL_FRAGMENT(__contiguous_range_, _Tp); template _CCCL_CONCEPT_FRAGMENT(__common_range_, requires()(requires(range<_Tp>), requires(same_as, sentinel_t<_Tp>>))); template _CCCL_CONCEPT common_range = _CCCL_FRAGMENT(__common_range_, _Tp); template _CCCL_INLINE_VAR constexpr bool __is_std_initializer_list = false; template _CCCL_INLINE_VAR constexpr bool __is_std_initializer_list> = true; template _CCCL_CONCEPT_FRAGMENT( __viewable_range_, requires()( requires(range<_Tp>), requires(((view> && constructible_from, _Tp>) || (!view> && (is_lvalue_reference_v<_Tp> || (movable> && !__is_std_initializer_list>) )))))); template _CCCL_CONCEPT viewable_range = _CCCL_FRAGMENT(__viewable_range_, _Tp); #endif // _CCCL_NO_CONCEPTS //[container.intro.reqmts] #if !defined(_CCCL_NO_CONCEPTS) template concept __container_compatible_range = input_range<_Range> && convertible_to, _Tp>; #else // ^^^ !_CCCL_NO_CONCEPTS ^^^ / vvv _CCCL_NO_CONCEPTS vvv template _CCCL_CONCEPT_FRAGMENT( __container_compatible_range_, requires()(requires(input_range<_Range>), requires(convertible_to, _Tp>))); template _CCCL_CONCEPT __container_compatible_range = _CCCL_FRAGMENT(__container_compatible_range_, _Range, _Tp); #endif // _CCCL_NO_CONCEPTS _LIBCUDACXX_END_NAMESPACE_RANGES #endif // _LIBCUDACXX___RANGES_CONCEPTS_H