diff --git a/libcudacxx/.upstream-tests/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp b/libcudacxx/.upstream-tests/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp new file mode 100644 index 0000000000..a21846caef --- /dev/null +++ b/libcudacxx/.upstream-tests/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// projected + +#include + +#include +#include + +#include "test_iterators.h" + +using IntPtr = cuda::std::projected; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), int const&>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +struct S { }; + +using Cpp17InputIterator = cuda::std::projected, int S::*>; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), int&>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +using Cpp20InputIterator = cuda::std::projected, int S::*>; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), int&>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +using ForwardIterator = cuda::std::projected, int (S::*)()>; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), int>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +using BidirectionalIterator = cuda::std::projected, S* (S::*)() const>; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), S*>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +using RandomAccessIterator = cuda::std::projected, S && (S::*)()>; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), S&&>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +using ContiguousIterator = cuda::std::projected, S& (S::*)() const>; +static_assert(cuda::std::same_as); +static_assert(cuda::std::same_as()), S&>); +static_assert(cuda::std::same_as, cuda::std::ptrdiff_t>); + +#if TEST_STD_VER > 17 +template +constexpr bool projectable = requires { + typename cuda::std::projected; +}; +#else +template +_LIBCUDACXX_CONCEPT_FRAGMENT( + projectable_, + requires() // + (typename(cuda::std::projected))); + +template +_LIBCUDACXX_CONCEPT projectable = _LIBCUDACXX_FRAGMENT(projectable_, I, F); +#endif + +static_assert(!projectable); // int isn't indirectly_readable +static_assert(!projectable); // S isn't weakly_incrementable +static_assert(!projectable); // void(int) doesn't satisfy indirectly_regular_unary_invcable + +int main(int, char**) +{ + return 0; +} diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt b/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt index 570fb045d2..f3fe97ad8f 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt @@ -102,6 +102,7 @@ set(files __iterator/ostreambuf_iterator.h __iterator/permutable.h __iterator/prev.h + __iterator/projected.h __iterator/readable_traits.h __iterator/reverse_access.h __iterator/reverse_iterator.h diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/projected.h b/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/projected.h new file mode 100644 index 0000000000..d2cd9b6cbf --- /dev/null +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/__iterator/projected.h @@ -0,0 +1,53 @@ +// -*- 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) 2023 NVIDIA CORPORATION & AFFILIATES +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCUDACXX___ITERATOR_PROJECTED_H +#define _LIBCUDACXX___ITERATOR_PROJECTED_H + +#ifndef __cuda_std__ +#include <__config> +#endif // __cuda_std__ + +#include "../__iterator/concepts.h" +#include "../__iterator/incrementable_traits.h" +#include "../__type_traits/enable_if.h" +#include "../__type_traits/remove_cvref.h" + +#if defined(_LIBCUDACXX_USE_PRAGMA_GCC_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCUDACXX_BEGIN_NAMESPACE_STD + +#if _LIBCUDACXX_STD_VER > 14 + +_LIBCUDACXX_TEMPLATE(class _It, class _Proj) + (requires indirectly_readable<_It> _LIBCUDACXX_AND indirectly_regular_unary_invocable<_Proj, _It>) +struct projected { + using value_type = remove_cvref_t>; + _LIBCUDACXX_INLINE_VISIBILITY indirect_result_t<_Proj&, _It> operator*() const; // not defined +}; + +#if _LIBCUDACXX_STD_VER > 17 +template +struct incrementable_traits> { + using difference_type = iter_difference_t<_It>; +}; +#else +template +struct incrementable_traits, enable_if_t>> { + using difference_type = iter_difference_t<_It>; +}; +#endif // _LIBCUDACXX_STD_VER > 17 + +#endif // _LIBCUDACXX_STD_VER > 14 + +_LIBCUDACXX_END_NAMESPACE_STD + +#endif // _LIBCUDACXX___ITERATOR_PROJECTED_H diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/iterator b/libcudacxx/include/cuda/std/detail/libcxx/include/iterator index 3e797f900d..7ff2ab5633 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/iterator +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/iterator @@ -704,6 +704,7 @@ template constexpr const E* data(initializer_list il) noexcept; #include "__iterator/ostreambuf_iterator.h" #include "__iterator/permutable.h" #include "__iterator/prev.h" +#include "__iterator/projected.h" #include "__iterator/readable_traits.h" #include "__iterator/reverse_access.h" #include "__iterator/reverse_iterator.h" diff --git a/libcudacxx/libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp b/libcudacxx/libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp new file mode 100644 index 0000000000..ba13106be9 --- /dev/null +++ b/libcudacxx/libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// projected + +#include + +#include +#include + +#include "test_iterators.h" + +using IntPtr = std::projected; +static_assert(std::same_as); +static_assert(std::same_as()), int const&>); +static_assert(std::same_as, std::ptrdiff_t>); + +struct S { }; + +using Cpp17InputIterator = std::projected, int S::*>; +static_assert(std::same_as); +static_assert(std::same_as()), int&>); +static_assert(std::same_as, std::ptrdiff_t>); + +using Cpp20InputIterator = std::projected, int S::*>; +static_assert(std::same_as); +static_assert(std::same_as()), int&>); +static_assert(std::same_as, std::ptrdiff_t>); + +using ForwardIterator = std::projected, int (S::*)()>; +static_assert(std::same_as); +static_assert(std::same_as()), int>); +static_assert(std::same_as, std::ptrdiff_t>); + +using BidirectionalIterator = std::projected, S* (S::*)() const>; +static_assert(std::same_as); +static_assert(std::same_as()), S*>); +static_assert(std::same_as, std::ptrdiff_t>); + +using RandomAccessIterator = std::projected, S && (S::*)()>; +static_assert(std::same_as); +static_assert(std::same_as()), S&&>); +static_assert(std::same_as, std::ptrdiff_t>); + +using ContiguousIterator = std::projected, S& (S::*)() const>; +static_assert(std::same_as); +static_assert(std::same_as()), S&>); +static_assert(std::same_as, std::ptrdiff_t>); + +template +constexpr bool projectable = requires { + typename std::projected; +}; + +static_assert(!projectable); // int isn't indirectly_readable +static_assert(!projectable); // S isn't weakly_incrementable +static_assert(!projectable); // void(int) doesn't satisfy indirectly_regular_unary_invcable + +int main(int, char**) { + return 0; +}