diff --git a/libcudacxx/include/cuda/std/__string/helper_functions.h b/libcudacxx/include/cuda/std/__string/helper_functions.h index be414f7d837..610962ca5e8 100644 --- a/libcudacxx/include/cuda/std/__string/helper_functions.h +++ b/libcudacxx/include/cuda/std/__string/helper_functions.h @@ -32,6 +32,7 @@ _LIBCUDACXX_BEGIN_NAMESPACE_STD +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) noexcept @@ -48,6 +49,7 @@ __cccl_str_find(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) noexce return static_cast<_SizeT>(__r - __p); } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr const _CharT* __cccl_search_substring(const _CharT* __first1, const _CharT* __last1, const _CharT* __first2, const _CharT* __last2) @@ -121,6 +123,7 @@ __cccl_str_find(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, return static_cast<_SizeT>(__r - __p); } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_rfind(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) noexcept @@ -147,6 +150,7 @@ __cccl_str_rfind(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) noexc return __npos; } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_rfind(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) noexcept @@ -169,6 +173,7 @@ __cccl_str_rfind(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos return static_cast<_SizeT>(__r - __p); } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find_first_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) noexcept @@ -185,6 +190,7 @@ __cccl_str_find_first_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _Siz return static_cast<_SizeT>(__r - __p); } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find_last_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) noexcept @@ -211,6 +217,7 @@ __cccl_str_find_last_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _Size return __npos; } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find_first_not_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) noexcept @@ -230,6 +237,7 @@ __cccl_str_find_first_not_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, return __npos; } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find_first_not_of(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) noexcept @@ -248,6 +256,7 @@ __cccl_str_find_first_not_of(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT return __npos; } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find_last_not_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) noexcept @@ -270,6 +279,7 @@ __cccl_str_find_last_not_of(const _CharT* __p, _SizeT __sz, const _CharT* __s, _ return __npos; } +_CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr _SizeT __cccl_str_find_last_not_of(const _CharT* __p, _SizeT __sz, _CharT __c, _SizeT __pos) noexcept diff --git a/libcudacxx/include/cuda/std/string_view b/libcudacxx/include/cuda/std/string_view index db134c0596a..230ba766751 100644 --- a/libcudacxx/include/cuda/std/string_view +++ b/libcudacxx/include/cuda/std/string_view @@ -57,7 +57,7 @@ #include #if !_CCCL_COMPILER(NVRTC) -# include +# include #endif // !_CCCL_COMPILER(NVRTC) #include @@ -69,6 +69,19 @@ _CCCL_CONCEPT __cccl_has_basic_sv_conv_operator = _CCCL_REQUIRES_EXPR((_Range, _CharT, _Traits), remove_cvref_t<_Range>& __d)( (__d.operator _CUDA_VSTD::basic_string_view<_CharT, _Traits>())); +#if !_CCCL_COMPILER(NVRTC) +template +inline constexpr bool __cccl_is_std_basic_string_view_v = false; +template +inline constexpr bool __cccl_is_std_basic_string_view_v = __cccl_is_std_basic_string_view_v<_Tp>; +template +inline constexpr bool __cccl_is_std_basic_string_view_v = __cccl_is_std_basic_string_view_v<_Tp>; +template +inline constexpr bool __cccl_is_std_basic_string_view_v = __cccl_is_std_basic_string_view_v<_Tp>; +template +inline constexpr bool __cccl_is_std_basic_string_view_v<::std::basic_string_view<_CharT, _Traits>> = true; +#endif // !_CCCL_COMPILER(NVRTC) + template class basic_string_view { @@ -105,6 +118,7 @@ public: _CCCL_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) noexcept = default; + _CCCL_EXEC_CHECK_DISABLE _LIBCUDACXX_HIDE_FROM_ABI constexpr basic_string_view(const _CharT* __s) noexcept : __data_{__s} , __size_{_Traits::length(__s)} @@ -146,6 +160,20 @@ public: , __size_{_CUDA_VRANGES::size(__r)} {} +#if !_CCCL_COMPILER(NVRTC) + _CCCL_TEMPLATE(class _Traits2 = _Traits) + _CCCL_REQUIRES(is_same_v<_Traits2, char_traits<_CharT>>) + _CCCL_HIDE_FROM_ABI constexpr basic_string_view(::std::basic_string_view<_CharT> __sv) noexcept + : __data_{__sv.data()} + , __size_{__sv.size()} + {} + + _CCCL_HIDE_FROM_ABI constexpr basic_string_view(::std::basic_string_view<_CharT, _Traits> __sv) noexcept + : __data_{__sv.data()} + , __size_{__sv.size()} + {} +#endif // !_CCCL_COMPILER(NVRTC) + [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { return const_iterator{__data_}; @@ -262,6 +290,7 @@ public: __other.__size_ = __sz; } + _CCCL_EXEC_CHECK_DISABLE _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { if (__pos > __size_) @@ -288,6 +317,7 @@ public: // compare + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr int compare(basic_string_view __sv) const noexcept { const auto __rlen = _CUDA_VSTD::min(__size_, __sv.__size_); @@ -350,6 +380,7 @@ public: return _CUDA_VSTD::__cccl_str_find(__data_, __size_, __s, __pos, __n); } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type find(const _CharT* __s, size_type __pos = 0) const noexcept { _CCCL_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); @@ -379,6 +410,7 @@ public: return _CUDA_VSTD::__cccl_str_rfind(__data_, __size_, __s, __pos, __n); } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type rfind(const _CharT* __s, size_type __pos = npos) const noexcept { @@ -411,6 +443,7 @@ public: __data_, __size_, __s, __pos, __n); } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type find_first_of(const _CharT* __s, size_type __pos = 0) const noexcept { @@ -443,6 +476,7 @@ public: __data_, __size_, __s, __pos, __n); } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type find_last_of(const _CharT* __s, size_type __pos = npos) const noexcept { @@ -476,6 +510,7 @@ public: __data_, __size_, __s, __pos, __n); } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const noexcept { @@ -509,6 +544,7 @@ public: __data_, __size_, __s, __pos, __n); } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const noexcept { @@ -524,6 +560,7 @@ public: return (__size_ >= __s.__size_) && compare(0, __s.__size_, __s) == 0; } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr bool starts_with(value_type __c) const noexcept { return (__size_ > 0) && _Traits::eq(front(), __c); @@ -541,6 +578,7 @@ public: return (__size_ >= __s.__size_) && compare(__size_ - __s.__size_, npos, __s) == 0; } + _CCCL_EXEC_CHECK_DISABLE [[nodiscard]] _LIBCUDACXX_HIDE_FROM_ABI constexpr bool ends_with(value_type __c) const noexcept { return (__size_ > 0) && _Traits::eq(back(), __c); @@ -711,6 +749,20 @@ public: return __lhs.compare(__rhs) >= 0; } +#if !_CCCL_COMPILER(NVRTC) + _CCCL_TEMPLATE(class _Traits2 = _Traits) + _CCCL_REQUIRES(is_same_v<_Traits2, char_traits<_CharT>>) + _CCCL_HIDE_FROM_ABI constexpr operator ::std::basic_string_view<_CharT>() const noexcept + { + return ::std::basic_string_view<_CharT>{__data_, __size_}; + } + + _CCCL_HIDE_FROM_ABI constexpr operator ::std::basic_string_view<_CharT, _Traits>() const noexcept + { + return ::std::basic_string_view<_CharT, _Traits>{__data_, __size_}; + } +#endif // !_CCCL_COMPILER(NVRTC) + private: enum class __assume_valid { @@ -735,19 +787,34 @@ _CCCL_REQUIRES(contiguous_iterator<_It> _CCCL_AND sized_sentinel_for<_End, _It>) _CCCL_HOST_DEVICE basic_string_view(_It, _End) -> basic_string_view>; _CCCL_TEMPLATE(class _Range) -_CCCL_REQUIRES(_CUDA_VRANGES::contiguous_range<_Range>) +_CCCL_REQUIRES(_CUDA_VRANGES::contiguous_range<_Range> _CCCL_AND(!__cccl_is_std_basic_string_view_v<_Range>)) _CCCL_HOST_DEVICE basic_string_view(_Range&&) -> basic_string_view<_CUDA_VRANGES::range_value_t<_Range>>; +#if !_CCCL_COMPILER(NVRTC) +template +_CCCL_HOST_DEVICE basic_string_view(::std::basic_string_view<_CharT>) -> basic_string_view<_CharT>; + +template +_CCCL_HOST_DEVICE basic_string_view(::std::basic_string_view<_CharT, _Traits>) -> basic_string_view<_CharT, _Traits>; +#endif // !_CCCL_COMPILER(NVRTC) + // operator << -#if 0 // todo: we need to implement char_traits stream types & functions +#if !_CCCL_COMPILER(NVRTC) +template +_CCCL_HIDE_FROM_ABI ::std::basic_ostream<_CharT>& +operator<<(::std::basic_ostream<_CharT>& __os, basic_string_view<_CharT> __str) +{ + return __os << ::std::basic_string_view<_CharT>{__str}; +} + template -_LIBCUDACXX_HIDE_FROM_ABI ::std::basic_ostream<_CharT, _Traits>& +_CCCL_HIDE_FROM_ABI ::std::basic_ostream<_CharT, _Traits>& operator<<(::std::basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __str) { - return __os.write(__str.data(), static_cast<::std::streamsize>(__str.size())); + return __os << ::std::basic_string_view<_CharT, _Traits>{__str}; } -#endif // 0 +#endif // !_CCCL_COMPILER(NVRTC) // literals diff --git a/libcudacxx/include/cuda/std/version b/libcudacxx/include/cuda/std/version index 55caafeaf3e..4755562e44b 100644 --- a/libcudacxx/include/cuda/std/version +++ b/libcudacxx/include/cuda/std/version @@ -143,7 +143,7 @@ // # define __cccl_lib_shared_mutex 201505L // # define __cccl_lib_shared_ptr_arrays 201611L // # define __cccl_lib_shared_ptr_weak_type 201606L -// # define __cccl_lib_string_view 201606L +#define __cccl_lib_string_view 201803L // # define __cccl_lib_to_chars 201611L // # define __cccl_lib_uncaught_exceptions 201411L // # define __cccl_lib_unordered_map_try_emplace 201411L @@ -173,7 +173,6 @@ // # define __cccl_lib_constexpr_misc 201811L // # define __cccl_lib_constexpr_numeric 201911L // # define __cccl_lib_constexpr_string 201907L -// # define __cccl_lib_constexpr_string_view 201811L // # define __cccl_lib_constexpr_swap_algorithms 201806L // # define __cccl_lib_constexpr_tuple 201811L // # define __cccl_lib_constexpr_utility 201811L @@ -206,8 +205,6 @@ // # define __cccl_lib_source_location 201907L // # define __cccl_lib_ssize 201902L // # define __cccl_lib_starts_ends_with 201711L -// # undef __cccl_lib_string_view -// # define __cccl_lib_string_view 201803L // # define __cccl_lib_syncbuf 201803L // # define __cccl_lib_three_way_comparison 201907L # define __cccl_lib_unwrap_ref 201811L diff --git a/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.cons.pass.cpp b/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.cons.pass.cpp new file mode 100644 index 00000000000..edbfd5601d9 --- /dev/null +++ b/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.cons.pass.cpp @@ -0,0 +1,119 @@ +// + +// constexpr basic_string_view(std::basic_string_view sv); + +#include +#include +#include + +#include + +#include "literal.h" + +template +constexpr void test_with_default_type_traits() +{ + using HostSV = std::basic_string_view; + using CudaSV = cuda::std::basic_string_view; + + // check that cuda::std::char_traits are mapped to std::char_traits + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + const CharT* str = TEST_STRLIT(CharT, "some text"); + + // test construction from std::basic_string_view> + { + static_assert(cuda::std::is_constructible_v); + static_assert(noexcept(CudaSV{HostSV{}})); + + HostSV host_sv{str}; + CudaSV cuda_sv{host_sv}; + assert(cuda_sv.data() == host_sv.data()); + assert(cuda_sv.size() == host_sv.size()); + } +} + +template +struct custom_type_traits + : private std::char_traits + , private cuda::std::char_traits +{ + using char_type = typename cuda::std::char_traits::char_type; + using int_type = typename cuda::std::char_traits::int_type; + using pos_type = typename std::char_traits::pos_type; + using off_type = typename std::char_traits::off_type; + using state_type = typename std::char_traits::state_type; + + using cuda::std::char_traits::assign; + using cuda::std::char_traits::eq; + using cuda::std::char_traits::lt; + using cuda::std::char_traits::compare; + using cuda::std::char_traits::length; + using cuda::std::char_traits::find; + using cuda::std::char_traits::move; + using cuda::std::char_traits::copy; + using cuda::std::char_traits::to_char_type; + using cuda::std::char_traits::to_int_type; + using cuda::std::char_traits::eq_int_type; + using std::char_traits::eof; + using std::char_traits::not_eof; +}; + +template +constexpr void test_with_custom_type_traits() +{ + using HostSV = std::basic_string_view>; + using CudaSV = cuda::std::basic_string_view>; + + // check that cuda::std::char_traits are mapped to std::char_traits + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + const CharT* str = TEST_STRLIT(CharT, "some text"); + + // test construction from std::basic_string_view> + { + static_assert(cuda::std::is_constructible_v); + static_assert(noexcept(CudaSV{HostSV{}})); + + HostSV host_sv{str}; + CudaSV cuda_sv{host_sv}; + assert(cuda_sv.data() == host_sv.data()); + assert(cuda_sv.size() == host_sv.size()); + } +} + +template +constexpr void test_type() +{ + test_with_default_type_traits(); + test_with_custom_type_traits(); +} + +constexpr bool test() +{ + test_type(); +#if _CCCL_HAS_CHAR8_T() + test_type(); +#endif // _CCCL_HAS_CHAR8_T() + test_type(); + test_type(); +#if _CCCL_HAS_WCHAR_T() + test_type(); +#endif // _CCCL_HAS_WCHAR_T() + + return true; +} + +static_assert(test()); + +int main(int, char**) +{ + NV_IF_TARGET(NV_IS_HOST, (test();)) + return 0; +} diff --git a/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.conversion.pass.cpp b/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.conversion.pass.cpp new file mode 100644 index 00000000000..59947a43454 --- /dev/null +++ b/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.conversion.pass.cpp @@ -0,0 +1,119 @@ +// + +// constexpr operator std::basic_string_view() const noexcept; + +#include +#include +#include + +#include + +#include "literal.h" + +template +constexpr void test_with_default_type_traits() +{ + using HostSV = std::basic_string_view; + using CudaSV = cuda::std::basic_string_view; + + // check that cuda::std::char_traits are mapped to std::char_traits + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + const CharT* str = TEST_STRLIT(CharT, "some text"); + + // test conversion to std::basic_string_view> + { + static_assert(cuda::std::is_convertible_v); + static_assert(noexcept(CudaSV{}.operator HostSV())); + + CudaSV cuda_sv{str}; + HostSV host_sv{cuda_sv}; + assert(host_sv.data() == cuda_sv.data()); + assert(host_sv.size() == cuda_sv.size()); + } +} + +template +struct custom_type_traits + : private std::char_traits + , private cuda::std::char_traits +{ + using char_type = typename cuda::std::char_traits::char_type; + using int_type = typename cuda::std::char_traits::int_type; + using pos_type = typename std::char_traits::pos_type; + using off_type = typename std::char_traits::off_type; + using state_type = typename std::char_traits::state_type; + + using cuda::std::char_traits::assign; + using cuda::std::char_traits::eq; + using cuda::std::char_traits::lt; + using cuda::std::char_traits::compare; + using cuda::std::char_traits::length; + using cuda::std::char_traits::find; + using cuda::std::char_traits::move; + using cuda::std::char_traits::copy; + using cuda::std::char_traits::to_char_type; + using cuda::std::char_traits::to_int_type; + using cuda::std::char_traits::eq_int_type; + using std::char_traits::eof; + using std::char_traits::not_eof; +}; + +template +constexpr void test_with_custom_type_traits() +{ + using HostSV = std::basic_string_view>; + using CudaSV = cuda::std::basic_string_view>; + + // check that cuda::std::char_traits are mapped to std::char_traits + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + const CharT* str = TEST_STRLIT(CharT, "some text"); + + // test conversion to std::basic_string_view> + { + static_assert(cuda::std::is_convertible_v); + static_assert(noexcept(CudaSV{}.operator HostSV())); + + CudaSV cuda_sv{str}; + HostSV host_sv{cuda_sv}; + assert(host_sv.data() == cuda_sv.data()); + assert(host_sv.size() == cuda_sv.size()); + } +} + +template +constexpr void test_type() +{ + test_with_default_type_traits(); + test_with_custom_type_traits(); +} + +constexpr bool test() +{ + test_type(); +#if _CCCL_HAS_CHAR8_T() + test_type(); +#endif // _CCCL_HAS_CHAR8_T() + test_type(); + test_type(); +#if _CCCL_HAS_WCHAR_T() + test_type(); +#endif // _CCCL_HAS_WCHAR_T() + + return true; +} + +static_assert(test()); + +int main(int, char**) +{ + NV_IF_TARGET(NV_IS_HOST, (test();)) + return 0; +} diff --git a/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.deduct.pass.cpp b/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.deduct.pass.cpp new file mode 100644 index 00000000000..4488f73ae84 --- /dev/null +++ b/libcudacxx/test/libcudacxx/cuda/strings/std_interop/string.view.deduct.pass.cpp @@ -0,0 +1,97 @@ +// + +// constexpr basic_string_view(std::basic_string_view sv); + +#include +#include +#include + +#include + +#include "literal.h" + +template +constexpr void test_with_default_type_traits() +{ + const CharT* str = TEST_STRLIT(CharT, "some text"); + + std::basic_string_view host_sv{str}; + cuda::std::basic_string_view cuda_sv{host_sv}; + + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + assert(cuda_sv.data() == host_sv.data()); + assert(cuda_sv.size() == host_sv.size()); +} + +template +struct custom_type_traits + : private std::char_traits + , private cuda::std::char_traits +{ + using char_type = typename cuda::std::char_traits::char_type; + using int_type = typename cuda::std::char_traits::int_type; + using pos_type = typename std::char_traits::pos_type; + using off_type = typename std::char_traits::off_type; + using state_type = typename std::char_traits::state_type; + + using cuda::std::char_traits::assign; + using cuda::std::char_traits::eq; + using cuda::std::char_traits::lt; + using cuda::std::char_traits::compare; + using cuda::std::char_traits::length; + using cuda::std::char_traits::find; + using cuda::std::char_traits::move; + using cuda::std::char_traits::copy; + using cuda::std::char_traits::to_char_type; + using cuda::std::char_traits::to_int_type; + using cuda::std::char_traits::eq_int_type; + using std::char_traits::eof; + using std::char_traits::not_eof; +}; + +template +constexpr void test_with_custom_type_traits() +{ + const CharT* str = TEST_STRLIT(CharT, "some text"); + + std::basic_string_view> host_sv{str}; + cuda::std::basic_string_view cuda_sv{host_sv}; + + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + assert(cuda_sv.data() == host_sv.data()); + assert(cuda_sv.size() == host_sv.size()); +} + +template +constexpr void test_type() +{ + test_with_default_type_traits(); + test_with_custom_type_traits(); +} + +constexpr bool test() +{ + test_type(); +#if _CCCL_HAS_CHAR8_T() + test_type(); +#endif // _CCCL_HAS_CHAR8_T() + test_type(); + test_type(); +#if _CCCL_HAS_WCHAR_T() + test_type(); +#endif // _CCCL_HAS_WCHAR_T() + + return true; +} + +static_assert(test()); + +int main(int, char**) +{ + NV_IF_TARGET(NV_IS_HOST, (test();)) + return 0; +} diff --git a/libcudacxx/test/libcudacxx/std/strings/string.view/string.view.io/stream_insert.pass.cpp b/libcudacxx/test/libcudacxx/std/strings/string.view/string.view.io/stream_insert.pass.cpp new file mode 100644 index 00000000000..b9a2a92f38c --- /dev/null +++ b/libcudacxx/test/libcudacxx/std/strings/string.view/string.view.io/stream_insert.pass.cpp @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// 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) 2025 NVIDIA CORPORATION & AFFILIATES. +// +//===----------------------------------------------------------------------===// + +// + +// template +// basic_ostream& +// operator<<(basic_ostream& os, +// const basic_string_view str); + +#include +#include +#include + +#include + +#include "literal.h" + +template +void test_with_default_type_traits() +{ + using OS = std::basic_ostringstream; + using SV = cuda::std::basic_string_view; + + // check that cuda::std::char_traits are mapped to std::char_traits + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + const CharT* str = TEST_STRLIT(CharT, "some text"); + + // 1. test basic write without formatting + { + OS out{}; + SV sv{str}; + + out << sv; + assert(out.good()); + assert(out.str() == str); + } + + // 2. test basic write with formatting + { + OS out{}; + SV sv{str}; + + out.width(12); + out << sv; + assert(out.good()); + assert(out.str() == TEST_STRLIT(CharT, " some text")); + } +} + +template +struct custom_type_traits + : private std::char_traits + , private cuda::std::char_traits +{ + using char_type = typename cuda::std::char_traits::char_type; + using int_type = typename cuda::std::char_traits::int_type; + using pos_type = typename std::char_traits::pos_type; + using off_type = typename std::char_traits::off_type; + using state_type = typename std::char_traits::state_type; + + using cuda::std::char_traits::assign; + using cuda::std::char_traits::eq; + using cuda::std::char_traits::lt; + using cuda::std::char_traits::compare; + using cuda::std::char_traits::length; + using cuda::std::char_traits::find; + using cuda::std::char_traits::move; + using cuda::std::char_traits::copy; + using cuda::std::char_traits::to_char_type; + using cuda::std::char_traits::to_int_type; + using cuda::std::char_traits::eq_int_type; + using std::char_traits::eof; + using std::char_traits::not_eof; +}; + +template +void test_with_custom_type_traits() +{ + using OS = std::basic_ostringstream>; + using SV = cuda::std::basic_string_view>; + + // check that cuda::std::char_traits are mapped to std::char_traits + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + static_assert(cuda::std::is_same_v); + static_assert(cuda::std::is_same_v>); + + const CharT* str = TEST_STRLIT(CharT, "some text"); + + // 1. test basic write without formatting + { + OS out{}; + SV sv{str}; + + out << sv; + assert(out.good()); + assert(out.str() == str); + } + + // 2. test basic write with formatting + { + OS out{}; + SV sv{str}; + + out.width(12); + out << sv; + assert(out.good()); + assert(out.str() == TEST_STRLIT(CharT, " some text")); + } +} + +template +void test_type() +{ + test_with_default_type_traits(); + test_with_custom_type_traits(); +} + +void test() +{ + test_type(); +#if _CCCL_HAS_WCHAR_T() + test_type(); +#endif // _CCCL_HAS_WCHAR_T() +} + +int main(int, char**) +{ + NV_IF_TARGET(NV_IS_HOST, (test();)) + return 0; +}