/*
 * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 * SPDX-License-Identifier: LicenseRef-NvidiaProprietary
 *
 * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
 * property and proprietary rights in and to this material, related
 * documentation and any modifications thereto. Any use, reproduction,
 * disclosure or distribution of this material and related documentation
 * without an express license agreement from NVIDIA CORPORATION or
 * its affiliates is strictly prohibited.
 */

#pragma once

namespace __nvhpc_std {

template< class _exec_space
        , class _ElementType_x
        , class _SizeType_x
        , ::std::size_t ... _ext_x
        , class _Layout_x
        , class _Accessor_x
        , class _ElementType_y
        , class _SizeType_y
        , ::std::size_t ... _ext_y
        , class _Layout_y
        , class _Accessor_y
        >
void copy( __nvhpc_exec< _exec_space > __exec
         , std::mdspan< _ElementType_x, std::extents<_SizeType_x, _ext_x ...>, _Layout_x, _Accessor_x > __x
         , std::mdspan< _ElementType_y, std::extents<_SizeType_y, _ext_y ...>, _Layout_y, _Accessor_y > __y
         )
{
    constexpr bool __types_supported = __data_types_supported( __stdblas_data_type<_ElementType_x>, __stdblas_output_data_type<_ElementType_y> );
    constexpr bool     __x_supported = __input_supported < _Layout_x, _Accessor_x >();
    constexpr bool     __y_supported = __output_supported< _Layout_y, _Accessor_y >();

#ifndef STDBLAS_FALLBACK_UNSUPPORTED_CASES
    __STDBLAS_STATIC_ASSERT_TYPES ( __types_supported      );
    __STDBLAS_STATIC_ASSERT_INPUT (     __x_supported, __x );
    __STDBLAS_STATIC_ASSERT_OUTPUT(     __y_supported, __y );
#endif

    if constexpr ( __types_supported && __x_supported && __y_supported )
    {
        __copy_impl( __exec, __x, __y );
    }
    else
    {
#ifdef STDBLAS_VERBOSE
        __STDBLAS_COMPILE_TIME_FALLBACK_MESSAGE( copy );
#endif
        std::linalg::copy( std::execution::seq, __x, __y );
    }
}

}
