Skip to content

Commit

Permalink
help the ranges concepts recognize standard contiguous iterators in c…
Browse files Browse the repository at this point in the history
…++17
  • Loading branch information
ericniebler committed Dec 19, 2024
1 parent d6253b5 commit d527d62
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 44 deletions.
20 changes: 1 addition & 19 deletions cudax/include/cuda/experimental/__algorithm/common.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,8 @@
namespace cuda::experimental
{

#if _CCCL_STD_VER >= 2020 && defined(_CCCL_SPAN_USES_RANGES)
template <typename _Tp>
concept __valid_1d_copy_fill_argument = _CUDA_VRANGES::contiguous_range<detail::__as_copy_arg_t<_Tp>>;

#else
template <typename _Tp, typename = int>
inline constexpr bool __convertible_to_span = false;

template <typename _Tp>
inline constexpr bool __convertible_to_span<
_Tp,
_CUDA_VSTD::enable_if_t<
_CUDA_VSTD::is_convertible_v<_Tp, _CUDA_VSTD::span<typename _CUDA_VSTD::decay_t<_Tp>::value_type>>,
int>> = true;

template <typename _Tp>
inline constexpr bool __valid_1d_copy_fill_argument =
_CUDA_VRANGES::contiguous_range<detail::__as_copy_arg_t<_Tp>> || __convertible_to_span<_Tp>;

#endif
_CCCL_CONCEPT __valid_1d_copy_fill_argument = _CUDA_VRANGES::contiguous_range<detail::__as_copy_arg_t<_Tp>>;

template <typename _Tp, typename _Decayed = _CUDA_VSTD::decay_t<_Tp>>
using __as_mdspan_t =
Expand Down
88 changes: 63 additions & 25 deletions libcudacxx/include/cuda/std/__iterator/iterator_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <cuda/std/__type_traits/is_primary_template.h>
#include <cuda/std/__type_traits/remove_cv.h>
#include <cuda/std/__type_traits/void_t.h>
#include <cuda/std/__utility/priority_tag.h>
#include <cuda/std/cstddef>

#if !_CCCL_COMPILER(NVRTC)
Expand All @@ -46,6 +47,10 @@
# include <iterator> // for ::std::input_iterator_tag
# endif // !_CCCL_COMPILER(MSVC)

# ifdef _GLIBCXX_DEBUG
# include <debug/safe_iterator.h>
# endif

# if _CCCL_STD_VER >= 2020
template <class _Tp, class = void>
struct __cccl_type_is_defined : _CUDA_VSTD::false_type
Expand Down Expand Up @@ -109,7 +114,7 @@ _CCCL_CONCEPT __dereferenceable = _CCCL_FRAGMENT(__dereferenceable_, _Tp);

// [iterator.traits]
template <class _Tp>
using iter_reference_t = enable_if_t<__dereferenceable<_Tp>, decltype(*_CUDA_VSTD::declval<_Tp&>())>;
using iter_reference_t = enable_if_t<__dereferenceable<_Tp>, decltype(*declval<_Tp&>())>;

template <class, class>
struct _CCCL_TYPE_VISIBILITY_DEFAULT iterator_traits;
Expand Down Expand Up @@ -165,38 +170,71 @@ struct __iter_traits_cache
template <class _Iter>
using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type;

struct __iter_concept_concept_test
{
template <class _Iter>
using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept;
};
struct __iter_concept_category_test
{
template <class _Iter>
using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category;
};
struct __iter_concept_random_fallback
{
template <class _Iter>
using _Apply = enable_if_t<__is_primary_template<iterator_traits<_Iter>>::value, random_access_iterator_tag>;
};
# if defined(_GLIBCXX_DEBUG)
_CCCL_TEMPLATE(class _Iter, class _Ty, class _Range)
_CCCL_REQUIRES(same_as<_Iter, ::__gnu_debug::_Safe_iterator<_Ty*, _Range>>)
auto __iter_concept_fn(::__gnu_debug::_Safe_iterator<_Ty*, _Range>, __priority_tag<3>) -> contiguous_iterator_tag;
# endif
# if defined(__GLIBCXX__)
_CCCL_TEMPLATE(class _Iter, class _Ty, class _Range)
_CCCL_REQUIRES(same_as<_Iter, ::__gnu_cxx::__normal_iterator<_Ty*, _Range>>)
auto __iter_concept_fn(::__gnu_cxx::__normal_iterator<_Ty*, _Range>, __priority_tag<3>) -> contiguous_iterator_tag;
# endif
# if defined(_LIBCPP_VERSION)
_CCCL_TEMPLATE(class _Iter, class _Ty)
_CCCL_REQUIRES(same_as<_Iter, ::std::__wrap_iter<_Ty*>>)
auto __iter_concept_fn(::std::__wrap_iter<_Ty*>, __priority_tag<3>) -> contiguous_iterator_tag;
# endif
# if defined(_MSVC_STL_VERSION) || defined(_IS_WRS)
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_Array_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_Array_const_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_Vector_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_Vector_const_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_String_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_String_const_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
_CCCL_TEMPLATE(class _Iter)
_CCCL_REQUIRES(same_as<_Iter, class _Iter::_String_view_iterator>)
auto __iter_concept_fn(_Iter, __priority_tag<3>) -> contiguous_iterator_tag;
# endif
_CCCL_TEMPLATE(class _Iter, class _Ty)
_CCCL_REQUIRES(same_as<_Iter, _Ty*>)
auto __iter_concept_fn(_Ty*, __priority_tag<3>) -> contiguous_iterator_tag;
template <class _Iter>
auto __iter_concept_fn(_Iter, __priority_tag<2>) -> class _ITER_TRAITS<_Iter>::iterator_concept;
template <class _Iter>
auto __iter_concept_fn(_Iter, __priority_tag<1>) -> class _ITER_TRAITS<_Iter>::iterator_category;
template <class _Iter>
auto __iter_concept_fn(_Iter, __priority_tag<0>)
-> enable_if_t<__is_primary_template<iterator_traits<_Iter>>::value, random_access_iterator_tag>;

template <class _Iter>
using __iter_concept_t =
decltype(_CUDA_VSTD::__iter_concept_fn<_Iter>(declval<_Iter>(), __priority_tag<3>{}));

template <class _Iter, class _Tester>
struct __test_iter_concept
: _IsValidExpansion<_Tester::template _Apply, _Iter>
, _Tester
template <class _Iter, class = void>
struct __iter_concept_cache : __type_defer_quote<__iter_concept_t, _Iter>
{};

template <class _Iter>
struct __iter_concept_cache
struct __iter_concept_cache<_Iter, void_t<__iter_concept_t<_Iter>>>
{
using type = _Or<__test_iter_concept<_Iter, __iter_concept_concept_test>,
__test_iter_concept<_Iter, __iter_concept_category_test>,
__test_iter_concept<_Iter, __iter_concept_random_fallback>>;
using type = __iter_concept_t<_Iter>;
};

template <class _Iter>
using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>;
using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type;

template <class _Tp>
struct __has_iterator_typedefs
Expand Down

0 comments on commit d527d62

Please sign in to comment.