From 6e214ef7d2e9fde75ba9c345449ef4c6e443c055 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 13 Feb 2024 02:56:39 -0800 Subject: [PATCH] Implement ranges concepts (#1364) Fixes #1363 --- .../std/detail/libcxx/include/CMakeLists.txt | 1 + .../libcxx/include/__iterator/distance.h | 12 +- .../detail/libcxx/include/__ranges/concepts.h | 348 ++++++++++++++++++ .../cuda/std/detail/libcxx/include/ranges | 3 +- ...range_concept_conformance.compile.pass.cpp | 2 - .../iterator_sentinel.pass.cpp | 1 - .../range.iter.ops.distance/lwg3664.pass.cpp | 1 - .../std/ranges/range.access/data.pass.cpp | 2 - .../std/ranges/range.access/empty.pass.cpp | 6 - .../borrowed_range.compile.pass.cpp | 65 ++++ ...orrowed_range.subsumption.compile.pass.cpp | 30 ++ .../enable_borrowed_range.compile.pass.cpp | 70 ++++ .../helper_aliases.compile.pass.cpp | 41 +++ .../range.range/iterator_t.compile.pass.cpp | 34 ++ .../range.range/range.compile.pass.cpp | 55 +++ .../range.range/range_size_t.compile.pass.cpp | 44 +++ .../range.range/sentinel_t.compile.pass.cpp | 32 ++ .../bidirectional_range.compile.pass.cpp | 58 +++ .../common_range.compile.pass.cpp | 86 +++++ .../contiguous_range.compile.pass.cpp | 97 +++++ .../forward_range.compile.pass.cpp | 59 +++ .../input_range.compile.pass.cpp | 63 ++++ .../output_range.compile.pass.cpp | 68 ++++ .../random_access_range.compile.pass.cpp | 60 +++ .../subsumption.compile.pass.cpp | 97 +++++ .../viewable_range.compile.pass.cpp | 188 ++++++++++ .../range.sized/sized_range.compile.pass.cpp | 81 ++++ .../range.sized/subsumption.compile.pass.cpp | 30 ++ .../range.view/enable_view.compile.pass.cpp | 109 ++++++ .../range.view/view.compile.pass.cpp | 96 +++++ .../view.subsumption.compile.pass.cpp | 48 +++ .../range.view/view_base.compile.pass.cpp | 27 ++ libcudacxx/libcxx/test/support/test_range.h | 85 +++++ ...range_concept_conformance.compile.pass.cpp | 4 +- .../iterator_sentinel.pass.cpp | 3 +- .../range.iter.ops.distance/lwg3664.pass.cpp | 3 +- .../range.iter.ops.distance/range.pass.cpp | 3 +- .../std/ranges/range.access/data.pass.cpp | 4 +- .../std/ranges/range.access/empty.pass.cpp | 8 +- .../borrowed_range.compile.pass.cpp | 69 ++++ ...orrowed_range.subsumption.compile.pass.cpp | 32 ++ .../enable_borrowed_range.compile.pass.cpp | 47 +++ .../helper_aliases.compile.pass.cpp | 40 ++ .../range.range/iterator_t.compile.pass.cpp | 34 ++ .../range.range/range.compile.pass.cpp | 55 +++ .../range.range/range_size_t.compile.pass.cpp | 64 ++++ .../range.range/sentinel_t.compile.pass.cpp | 32 ++ .../bidirectional_range.compile.pass.cpp | 62 ++++ .../common_range.compile.pass.cpp | 90 +++++ .../contiguous_range.compile.pass.cpp | 101 +++++ .../forward_range.compile.pass.cpp | 63 ++++ .../input_range.compile.pass.cpp | 67 ++++ .../output_range.compile.pass.cpp | 72 ++++ .../random_access_range.compile.pass.cpp | 64 ++++ .../subsumption.compile.pass.cpp | 99 +++++ .../viewable_range.compile.pass.cpp | 195 ++++++++++ .../range.sized/sized_range.compile.pass.cpp | 85 +++++ .../range.sized/subsumption.compile.pass.cpp | 32 ++ .../range.view/enable_view.compile.pass.cpp | 120 ++++++ .../range.view/view.compile.pass.cpp | 98 +++++ .../view.subsumption.compile.pass.cpp | 54 +++ .../range.view/view_base.compile.pass.cpp | 29 ++ ...range_concept_conformance.compile.pass.cpp | 4 +- libcudacxx/test/support/test_range.h | 89 +++++ 64 files changed, 3679 insertions(+), 42 deletions(-) create mode 100644 libcudacxx/include/cuda/std/detail/libcxx/include/__ranges/concepts.h create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.subsumption.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/enable_borrowed_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/helper_aliases.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/iterator_t.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/bidirectional_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/forward_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/output_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/random_access_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.sized/subsumption.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.view/enable_view.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.view/view.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.view/view.subsumption.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/std/ranges/range.req/range.view/view_base.compile.pass.cpp create mode 100644 libcudacxx/libcxx/test/support/test_range.h create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/borrowed_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/borrowed_range.subsumption.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/enable_borrowed_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/helper_aliases.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/iterator_t.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/bidirectional_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/forward_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/output_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/random_access_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.sized/subsumption.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.view/enable_view.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.view/view.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.view/view.subsumption.compile.pass.cpp create mode 100644 libcudacxx/test/libcudacxx/std/ranges/range.req/range.view/view_base.compile.pass.cpp create mode 100644 libcudacxx/test/support/test_range.h diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt b/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt index 42f628ee3a5..49f879cefa6 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt @@ -191,6 +191,7 @@ set(files __node_handle __nullptr __ranges/access.h + __ranges/concepts.h __ranges/data.h __ranges/empty.h __ranges/enable_borrowed_range.h diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/distance.h b/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/distance.h index cecbeb40c86..c2b11109b18 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/distance.h +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/distance.h @@ -4,7 +4,7 @@ // 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) 2023 NVIDIA CORPORATION & AFFILIATES. +// SPDX-FileCopyrightText: Copyright (c) 2023-24 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// @@ -18,11 +18,9 @@ #include "../__iterator/concepts.h" #include "../__iterator/incrementable_traits.h" #include "../__iterator/iterator_traits.h" -#ifdef _LIBCUDACXX_HAS_RANGES -# include "../__ranges/access.h" -# include "../__ranges/concepts.h" -# include "../__ranges/size.h" -#endif // _LIBCUDACXX_HAS_RANGES +#include "../__ranges/access.h" +#include "../__ranges/concepts.h" +#include "../__ranges/size.h" #include "../__type_traits/decay.h" #include "../__type_traits/remove_cvref.h" @@ -66,7 +64,6 @@ inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 } _LIBCUDACXX_END_NAMESPACE_STD -#ifdef _LIBCUDACXX_HAS_RANGES # if _CCCL_STD_VER > 2014 && !defined(_LIBCUDACXX_COMPILER_MSVC_2017) // [range.iter.op.distance] @@ -129,6 +126,5 @@ _LIBCUDACXX_CPO_ACCESSIBILITY auto distance = __distance::__fn{}; _LIBCUDACXX_END_NAMESPACE_RANGES # endif // _CCCL_STD_VER > 2014 && !defined(_LIBCUDACXX_COMPILER_MSVC_2017) -#endif // _LIBCUDACXX_HAS_RANGES #endif // _LIBCUDACXX___ITERATOR_DISTANCE_H diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/__ranges/concepts.h b/libcudacxx/include/cuda/std/detail/libcxx/include/__ranges/concepts.h new file mode 100644 index 00000000000..5ef8f4e7c6e --- /dev/null +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/__ranges/concepts.h @@ -0,0 +1,348 @@ +// -*- 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 + +#ifndef __cuda_std__ +#include <__config> +#endif // __cuda_std__ + +#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 "../__concepts/constructible.h" +#include "../__concepts/movable.h" +#include "../__concepts/same_as.h" +#include "../__iterator/concepts.h" +#include "../__iterator/incrementable_traits.h" +#include "../__iterator/iter_move.h" +#include "../__iterator/iterator_traits.h" +#include "../__iterator/readable_traits.h" +#include "../__ranges/access.h" +#include "../__ranges/data.h" +#include "../__ranges/enable_borrowed_range.h" +#include "../__ranges/enable_view.h" +#include "../__ranges/size.h" +#include "../__type_traits/add_pointer.h" +#include "../__type_traits/enable_if.h" +#include "../__type_traits/is_reference.h" +#include "../__type_traits/remove_cvref.h" +#include "../__type_traits/remove_reference.h" +#include "../__utility/declval.h" +#include "../initializer_list" + +_LIBCUDACXX_BEGIN_NAMESPACE_RANGES + +#if _CCCL_STD_VER >= 2017 && !defined(_CCCL_COMPILER_MSVC_2017) + +#if _CCCL_STD_VER >= 2020 + + // [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 + _LIBCUDACXX_INLINE_VAR constexpr bool __is_std_initializer_list = false; + + template + _LIBCUDACXX_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 // ^^^ C++20 ^^^ / vvv C++17 vvv + // [range.range] + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __range_, + requires(_Tp& __t)( + typename(decltype(_CUDA_VRANGES::begin(__t))), + typename(decltype(_CUDA_VRANGES::end(__t))) + )); + + template + _LIBCUDACXX_CONCEPT range = _LIBCUDACXX_FRAGMENT(__range_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __input_range_, + requires()( + requires(range<_Tp>), + requires(input_iterator>) + )); + + template + _LIBCUDACXX_CONCEPT input_range = _LIBCUDACXX_FRAGMENT(__input_range_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __borrowed_range_, + requires()( + requires(range<_Range>), + requires((is_lvalue_reference_v<_Range> || enable_borrowed_range>)) + )); + + template + _LIBCUDACXX_CONCEPT borrowed_range = _LIBCUDACXX_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 + _LIBCUDACXX_CONCEPT_FRAGMENT( + __sized_range_, + requires(_Tp& __t)( + requires(range<_Tp>), + typename(decltype(_CUDA_VRANGES::size(__t))) + )); + + template + _LIBCUDACXX_CONCEPT sized_range = _LIBCUDACXX_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 + _LIBCUDACXX_CONCEPT_FRAGMENT( + __view_, + requires()( + requires(range<_Tp>), + requires(movable<_Tp>), + requires(enable_view<_Tp>) + )); + + template + _LIBCUDACXX_CONCEPT view = _LIBCUDACXX_FRAGMENT(__view_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __simple_view_, + requires()( + requires(view<_Range>), + requires(range), + requires(same_as, iterator_t>), + requires(same_as, sentinel_t>) + )); + + template + _LIBCUDACXX_CONCEPT __simple_view = _LIBCUDACXX_FRAGMENT(__simple_view_, _Range); + + // [range.refinements], other range refinements + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __output_range_, + requires()( + requires(range<_Rp>), + requires(output_iterator, _Tp>) + )); + + template + _LIBCUDACXX_CONCEPT output_range = _LIBCUDACXX_FRAGMENT(__output_range_, _Rp, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __forward_range_, + requires()( + requires(input_range<_Tp>), + requires(forward_iterator>) + )); + + template + _LIBCUDACXX_CONCEPT forward_range = _LIBCUDACXX_FRAGMENT(__forward_range_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __bidirectional_range_, + requires()( + requires(forward_range<_Tp>), + requires(bidirectional_iterator>) + )); + + template + _LIBCUDACXX_CONCEPT bidirectional_range = _LIBCUDACXX_FRAGMENT(__bidirectional_range_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __random_access_range_, + requires()( + requires(bidirectional_range<_Tp>), + requires(random_access_iterator>) + )); + + template + _LIBCUDACXX_CONCEPT random_access_range = _LIBCUDACXX_FRAGMENT(__random_access_range_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __contiguous_range_, + requires(_Tp& __t)( + requires(random_access_range<_Tp>), + requires(contiguous_iterator>), + requires(same_as>>) + )); + + template + _LIBCUDACXX_CONCEPT contiguous_range = _LIBCUDACXX_FRAGMENT(__contiguous_range_, _Tp); + + template + _LIBCUDACXX_CONCEPT_FRAGMENT( + __common_range_, + requires()( + requires(range<_Tp>), + requires(same_as, sentinel_t<_Tp>>) + )); + + template + _LIBCUDACXX_CONCEPT common_range = _LIBCUDACXX_FRAGMENT(__common_range_, _Tp); + + template + _LIBCUDACXX_INLINE_VAR constexpr bool __is_std_initializer_list = false; + + template + _LIBCUDACXX_INLINE_VAR constexpr bool __is_std_initializer_list> = true; + + template + _LIBCUDACXX_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 + _LIBCUDACXX_CONCEPT viewable_range = _LIBCUDACXX_FRAGMENT(__viewable_range_, _Tp); + +#endif // _CCCL_STD_VER >= 2017 + +#endif // _CCCL_STD_VER >= 2017 && !_CCCL_COMPILER_MSVC_2017 + +_LIBCUDACXX_END_NAMESPACE_RANGES + +#endif // _LIBCUDACXX___RANGES_CONCEPTS_H diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/ranges b/libcudacxx/include/cuda/std/detail/libcxx/include/ranges index 0db3682cc9b..9049f3db63c 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/ranges +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/ranges @@ -4,7 +4,7 @@ // 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) 2023 NVIDIA CORPORATION & AFFILIATES. +// SPDX-FileCopyrightText: Copyright (c) 2023-24 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// @@ -312,6 +312,7 @@ namespace std { #include "__assert" // all public C++ headers provide the assertion handler #include "__ranges/access.h" +#include "__ranges/concepts.h" #include "__ranges/data.h" #include "__ranges/empty.h" #include "__ranges/enable_borrowed_range.h" diff --git a/libcudacxx/libcxx/test/std/containers/views/views.span/range_concept_conformance.compile.pass.cpp b/libcudacxx/libcxx/test/std/containers/views/views.span/range_concept_conformance.compile.pass.cpp index f98c366cecb..969a10ff225 100644 --- a/libcudacxx/libcxx/test/std/containers/views/views.span/range_concept_conformance.compile.pass.cpp +++ b/libcudacxx/libcxx/test/std/containers/views/views.span/range_concept_conformance.compile.pass.cpp @@ -18,7 +18,6 @@ using range = std::span; -#ifdef _LIBCUDACXX_HAS_RANGES static_assert(std::same_as, range::iterator>); static_assert(std::ranges::common_range); static_assert(std::ranges::random_access_range); @@ -36,7 +35,6 @@ static_assert(!std::ranges::view && !std::ranges::enable_view); static_assert(std::ranges::borrowed_range); static_assert(std::ranges::viewable_range); -#endif // _LIBCUDACXX_HAS_RANGES int main(int, char**) { diff --git a/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp b/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp index 5dd1353d21b..aa63f3ff3b6 100644 --- a/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp +++ b/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 -// XFAIL: c++20 // template S> // requires (!sized_sentinel_for) diff --git a/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/lwg3664.pass.cpp b/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/lwg3664.pass.cpp index 3df08a1e509..e2258e93966 100644 --- a/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/lwg3664.pass.cpp +++ b/libcudacxx/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/lwg3664.pass.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 -// XFAIL: c++20 // template S> // requires (!sized_sentinel_for) diff --git a/libcudacxx/libcxx/test/std/ranges/range.access/data.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.access/data.pass.cpp index c1899e307c9..357e52a1462 100644 --- a/libcudacxx/libcxx/test/std/ranges/range.access/data.pass.cpp +++ b/libcudacxx/libcxx/test/std/ranges/range.access/data.pass.cpp @@ -82,10 +82,8 @@ constexpr bool testReturnTypes() { char *end() const; int *data(); }; -#if _LIBCUDACXX_HAS_RANGES static_assert(!std::ranges::contiguous_range); static_assert( std::ranges::contiguous_range); -#endif // _LIBCUDACXX_HAS_RANGES ASSERT_SAME_TYPE(decltype(std::ranges::data(std::declval())), int*); static_assert(!std::is_invocable_v); ASSERT_SAME_TYPE(decltype(std::ranges::data(std::declval())), char*); diff --git a/libcudacxx/libcxx/test/std/ranges/range.access/empty.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.access/empty.pass.cpp index 85163f4a1ca..39742e6f6da 100644 --- a/libcudacxx/libcxx/test/std/ranges/range.access/empty.pass.cpp +++ b/libcudacxx/libcxx/test/std/ranges/range.access/empty.pass.cpp @@ -104,10 +104,8 @@ struct BeginEndSizedSentinel { constexpr int *begin() const { return nullptr; } constexpr auto end() const { return sized_sentinel(nullptr); } }; -#ifdef _LIBCUDACXX_HAS_RANGES static_assert(std::ranges::forward_range); static_assert(std::ranges::sized_range); -#endif // _LIBCUDACXX_HAS_RANGES constexpr bool testUsingRangesSize() { SizeMember a{1}; @@ -130,10 +128,8 @@ struct BeginEndNotSizedSentinel { constexpr int *begin() const { return nullptr; } constexpr auto end() const { return sentinel_wrapper(nullptr); } }; -#ifdef _LIBCUDACXX_HAS_RANGES static_assert( std::ranges::forward_range); static_assert(!std::ranges::sized_range); -#endif // _LIBCUDACXX_HAS_RANGES // size is disabled here, so we have to compare begin and end. struct DisabledSizeRangeWithBeginEnd { @@ -143,10 +139,8 @@ struct DisabledSizeRangeWithBeginEnd { }; template<> inline constexpr bool std::ranges::disable_sized_range = true; -#ifdef _LIBCUDACXX_HAS_RANGES static_assert(std::ranges::contiguous_range); static_assert(!std::ranges::sized_range); -#endif // _LIBCUDACXX_HAS_RANGES struct BeginEndAndEmpty { constexpr int *begin() const { return nullptr; } diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.compile.pass.cpp new file mode 100644 index 00000000000..10f501c02c9 --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.compile.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// concept borrowed_range; + +#include + +struct NotRange { + int begin() const; + int end() const; +}; + +struct Range { + int *begin(); + int *end(); +}; + +struct ConstRange { + int *begin() const; + int *end() const; +}; + +struct BorrowedRange { + int *begin() const; + int *end() const; +}; + +template<> +inline constexpr bool std::ranges::enable_borrowed_range = true; + +static_assert(!std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); + +static_assert(!std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); + +static_assert(!std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); +static_assert(!std::ranges::borrowed_range); + +static_assert( std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); +static_assert( std::ranges::borrowed_range); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.subsumption.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.subsumption.compile.pass.cpp new file mode 100644 index 00000000000..78c763acf8b --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/borrowed_range.subsumption.compile.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// concept borrowed_range; + +#include + +template +consteval bool check_subsumption() { + return false; +} + +template +consteval bool check_subsumption() { + return true; +} + +static_assert(check_subsumption()); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/enable_borrowed_range.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/enable_borrowed_range.compile.pass.cpp new file mode 100644 index 00000000000..5a18dd519a9 --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/enable_borrowed_range.compile.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template +// inline constexpr bool enable_borrowed_range = false; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_macros.h" + +struct S {}; + +void test() { + using std::ranges::enable_borrowed_range; + static_assert(!enable_borrowed_range); + static_assert(!enable_borrowed_range); + static_assert(!enable_borrowed_range); + static_assert(!enable_borrowed_range); + + // Sequence containers + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + + // Associative containers + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + + // Unordered associative containers + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + + // Container adaptors + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + static_assert(!enable_borrowed_range >); + + // Both std::span and std::string_view have their own test. +} + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/helper_aliases.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/helper_aliases.compile.pass.cpp new file mode 100644 index 00000000000..40dce31c707 --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/helper_aliases.compile.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// 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>; + +#include + +#include + +#include "test_iterators.h" +#include "test_range.h" + +static_assert(std::same_as >, std::iter_difference_t >); +static_assert(std::same_as >, std::iter_value_t >); +static_assert(std::same_as >, std::iter_reference_t >); +static_assert(std::same_as >, std::iter_rvalue_reference_t >); +static_assert(std::same_as >, std::iter_common_reference_t >); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/iterator_t.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/iterator_t.compile.pass.cpp new file mode 100644 index 00000000000..55566db517b --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/iterator_t.compile.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// using iterator_t = decltype(ranges::begin(declval())); + +#include + +#include + +#include "test_range.h" + + + +static_assert(std::same_as >, cpp17_input_iterator >); +static_assert(std::same_as const>, cpp17_input_iterator >); + +static_assert(std::same_as >, cpp17_input_iterator >); + +static_assert(std::same_as >, cpp17_input_iterator >); +static_assert(std::same_as const>, cpp17_input_iterator >); + +static_assert(std::same_as >, cpp17_input_iterator >); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp new file mode 100644 index 00000000000..bb6f6f2fa46 --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/range.compile.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// concept range; + +#include + +#include + +#include "test_range.h" + + + +static_assert(std::ranges::range >); + +struct incompatible_iterators { + int* begin(); + long* end(); +}; +static_assert(!std::ranges::range); + +struct int_begin_int_end { + int begin(); + int end(); +}; +static_assert(!std::ranges::range); + +struct iterator_begin_int_end { + int* begin(); + int end(); +}; +static_assert(!std::ranges::range); + +struct int_begin_iterator_end { + int begin(); + int* end(); +}; +static_assert(!std::ranges::range); + +// Test ADL-proofing. +struct Incomplete; +template struct Holder { T t; }; +static_assert(!std::ranges::range*>); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp new file mode 100644 index 00000000000..1f892133cc5 --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// using range_size_t = decltype(ranges::size(declval())); + +#include +#include +#include + +#include "test_iterators.h" + +template +concept has_range_size_t = requires { typename std::ranges::range_size_t; }; + +struct A { int *begin(); int *end(); short size(); }; +static_assert(std::same_as, short>); +static_assert(std::same_as, short>); +static_assert(std::same_as, short>); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); + +struct B { int *begin(); int *end(); }; +static_assert(std::same_as, std::size_t>); +static_assert(std::same_as, std::size_t>); +static_assert(std::same_as, std::size_t>); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); + +struct C { bidirectional_iterator begin(); bidirectional_iterator end(); }; +static_assert(!has_range_size_t); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp new file mode 100644 index 00000000000..c910f14502c --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// using sentinel_t = decltype(ranges::end(declval<_Rp&>())); + +#include + +#include + +#include "test_iterators.h" +#include "test_range.h" + + + +static_assert(std::same_as >, sentinel>); +static_assert(std::same_as const>, sentinel>); +static_assert(std::same_as >, sentinel>); +static_assert(std::same_as >, forward_iterator >); +static_assert(std::same_as const>, forward_iterator >); +static_assert(std::same_as >, forward_iterator >); + +int main(int, char**) { + return 0; +} diff --git a/libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/bidirectional_range.compile.pass.cpp b/libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/bidirectional_range.compile.pass.cpp new file mode 100644 index 00000000000..74b4622dcb2 --- /dev/null +++ b/libcudacxx/libcxx/test/std/ranges/range.req/range.refinements/bidirectional_range.compile.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// template +// concept bidirectional_range; + +#include + +#include "test_range.h" + +template