//===----------------------------------------------------------------------===// // // 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-24 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// // Modifications Copyright (c) 2025 Advanced Micro Devices, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #ifndef _LIBCUDACXX___ALGORITHM_COPY_H #define _LIBCUDACXX___ALGORITHM_COPY_H #include #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 #include #include #include #include #include #include #include #include #include // memmove _LIBCUDACXX_BEGIN_NAMESPACE_STD _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr pair<_InputIterator, _OutputIterator> __copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { for (; __first != __last; ++__first, (void) ++__result) { *__result = *__first; } return {__last, __result}; } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool __dispatch_memmove(_Up* __result, _Tp* __first, const size_t __n) { #if defined(_CCCL_BUILTIN_MEMMOVE) _CCCL_BUILTIN_MEMMOVE(__result, __first, __n * sizeof(_Up)); return true; #else // ^^^ _CCCL_BUILTIN_MEMMOVE ^^^ / vvv !_CCCL_BUILTIN_MEMMOVE vvv if (!_CUDA_VSTD::__cccl_default_is_constant_evaluated()) { _CUDA_VSTD::memmove(__result, __first, __n * sizeof(_Up)); return true; } return false; #endif // ^^^ !_CCCL_BUILTIN_MEMMOVE ^^^ } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool __constexpr_tail_overlap_fallback(_Tp* __first, _Up* __needle, _Tp* __last) { while (__first != __last) { if (__first == __needle) { return true; } ++__first; } return false; } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool __constexpr_tail_overlap(_Tp* __first, _Up* __needle, _Tp* __last) { _LIBCUDACXX_UNUSED_VAR(__last); #if defined(_CCCL_BUILTIN_CONSTANT_P) NV_IF_ELSE_TARGET(NV_IS_HOST_LIBHIPCXX, (return _CCCL_BUILTIN_CONSTANT_P(__first < __needle) && __first < __needle;), (return __constexpr_tail_overlap_fallback(__first, __needle, __last);)) #else // ^^^ _CCCL_BUILTIN_CONSTANT_P ^^^ / vvv !_CCCL_BUILTIN_CONSTANT_P vvv return __constexpr_tail_overlap_fallback(__first, __needle, __last); #endif // !_CCCL_BUILTIN_CONSTANT_P } _CCCL_EXEC_CHECK_DISABLE template , _Up), int> = 0, enable_if_t<_CCCL_TRAIT(is_trivially_copyable, _Up), int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair<_Tp*, _Up*> __copy(_Tp* __first, _Tp* __last, _Up* __result) { const ptrdiff_t __n = __last - __first; if (__n > 0) { if (__dispatch_memmove(__result, __first, __n)) { return {__last, __result + __n}; } if ((!_CUDA_VSTD::is_constant_evaluated() && __first < __result) || __constexpr_tail_overlap(__first, __result, __last)) { for (ptrdiff_t __i = __n; __i > 0; --__i) { *(__result + __i - 1) = *(__first + __i - 1); } } else { for (ptrdiff_t __i = 0; __i < __n; ++__i) { *(__result + __i) = *(__first + __i); } } } return {__last, __result + __n}; } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _OutputIterator copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { return _CUDA_VSTD::__copy<_ClassicAlgPolicy>( _CUDA_VSTD::__unwrap_iter(__first), _CUDA_VSTD::__unwrap_iter(__last), _CUDA_VSTD::__unwrap_iter(__result)) .second; } _LIBCUDACXX_END_NAMESPACE_STD #endif // _LIBCUDACXX___ALGORITHM_COPY_H