Skip to content

Commit

Permalink
Iterators C++20 disable operator* when it invalid (#1797)
Browse files Browse the repository at this point in the history
---------

Signed-off-by: Dan Hoeflinger <[email protected]>
  • Loading branch information
danhoeflinger authored Aug 27, 2024
1 parent fbd529c commit 2fcf2ad
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
29 changes: 25 additions & 4 deletions include/oneapi/dpl/pstl/iterator_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <tuple>
#include <cassert>

#include "onedpl_config.h"
#include "utils.h"
#include "tuple_impl.h"

Expand Down Expand Up @@ -105,7 +106,10 @@ class zip_forward_iterator
zip_forward_iterator() : __my_it_() {}
explicit zip_forward_iterator(_Types... __args) : __my_it_(__tuple_t<_Types...>{__args...}) {}

reference operator*() const
// On windows, this requires clause is necessary so that concepts in MSVC STL do not detect the iterator as
// dereferenceable when a source iterator is a sycl_iterator, which is a supported type.
reference
operator*() const _ONEDPL_CPP20_REQUIRES(std::indirectly_readable<_Types> &&...)
{
return __make_references<reference>()(__my_it_, ::std::make_index_sequence<__num_types>());
}
Expand Down Expand Up @@ -285,7 +289,10 @@ class zip_iterator
explicit zip_iterator(_Types... __args) : __my_it_(::std::make_tuple(__args...)) {}
explicit zip_iterator(std::tuple<_Types...> __arg) : __my_it_(__arg) {}

reference operator*() const
// On windows, this requires clause is necessary so that concepts in MSVC STL do not detect the iterator as
// dereferenceable when a source iterator is a sycl_iterator, which is a supported type.
reference
operator*() const _ONEDPL_CPP20_REQUIRES(std::indirectly_readable<_Types> &&...)
{
return oneapi::dpl::__internal::__make_references<reference>()(__my_it_,
::std::make_index_sequence<__num_types>());
Expand Down Expand Up @@ -459,7 +466,14 @@ class transform_iterator
}
return *this;
}
reference operator*() const { return __my_unary_func_(*__my_it_); }

// On windows, this requires clause is necessary so that concepts in MSVC STL do not detect the iterator as
// dereferenceable when the source iterator is a sycl_iterator, which is a supported type.
reference
operator*() const _ONEDPL_CPP20_REQUIRES(std::indirectly_readable<_Iter>)
{
return __my_unary_func_(*__my_it_);
}
reference operator[](difference_type __i) const { return *(*this + __i); }
transform_iterator&
operator++()
Expand Down Expand Up @@ -641,7 +655,14 @@ class permutation_iterator
return my_index;
}

reference operator*() const { return my_source_it[*my_index]; }
// On windows, this requires clause is necessary so that concepts in MSVC STL do not detect the iterator as
// dereferenceable when the source or map iterator is a sycl_iterator, which is a supported type for both.
reference
operator*() const
_ONEDPL_CPP20_REQUIRES(std::indirectly_readable<SourceIterator> && std::indirectly_readable<IndexMap>)
{
return my_source_it[*my_index];
}

reference operator[](difference_type __i) const { return *(*this + __i); }

Expand Down
6 changes: 6 additions & 0 deletions include/oneapi/dpl/pstl/onedpl_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@
(!_ONEDPL_CPP20_CONCEPTS_PRESENT || \
(_ONEDPL_CPP23_RANGES_ZIP_PRESENT && _ONEDPL_CPP23_TUPLE_LIKE_COMMON_REFERENCE_PRESENT))
#if _ONEDPL_CPP20_CONCEPTS_PRESENT
# define _ONEDPL_CPP20_REQUIRES(req) requires(req)
#else
# define _ONEDPL_CPP20_REQUIRES(req)
#endif
#define _ONEDPL_BUILT_IN_STABLE_NAME_PRESENT __has_builtin(__builtin_sycl_unique_stable_name)
#if defined(_MSC_VER) && __INTEL_LLVM_COMPILER < 20240100
Expand Down

0 comments on commit 2fcf2ad

Please sign in to comment.