Program Listing for File TypeTraits.hpp
↰ Return to documentation for file (nvcv_types/include/nvcv/cuda/TypeTraits.hpp
)
std::cout << pix;
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NVCV_CUDA_TYPE_TRAITS_HPP
#define NVCV_CUDA_TYPE_TRAITS_HPP
#include "detail/Metaprogramming.hpp" // for detail::TypeTraits, etc.
#include <cassert> // for assert, etc.
#include <ostream> // for std::ostream, etc.
namespace nvcv::cuda {
using detail::TypeTraits;
// Metatype to serve as a requirement for a template object to meet the given boolean expression.
template<bool B>
using Require = std::enable_if_t<B>;
// Metavariable to check if one or more types have type traits.
template<typename... Ts>
constexpr bool HasTypeTraits = (detail::HasTypeTraits_t<Ts>::value && ...);
// Metavariable to check if a type is a CUDA compound type.
template<class T, class = Require<HasTypeTraits<T>>>
constexpr bool IsCompound = TypeTraits<T>::components >= 1;
// Metavariable to check if a CUDA compound type T has N or more components.
template<typename T, int N, class = Require<HasTypeTraits<T>>>
constexpr bool HasEnoughComponents = N <= TypeTraits<T>::components;
template<class T, class = Require<HasTypeTraits<T>>>
using BaseType = typename TypeTraits<T>::base_type;
template<class T, class = Require<HasTypeTraits<T>>>
constexpr int NumComponents = TypeTraits<T>::components;
template<class T, class = Require<HasTypeTraits<T>>>
constexpr int NumElements = TypeTraits<T>::elements;
// Metavariable to get the lowest value from a regular C or CUDA compound type T.
template<typename T, class = Require<HasTypeTraits<T>>>
constexpr BaseType<T> Lowest = std::is_floating_point_v<BaseType<T>> ? -TypeTraits<T>::max : TypeTraits<T>::min;
template<class T, int C, class = Require<HasTypeTraits<T>>>
using MakeType = detail::MakeType_t<T, C>;
template<class BT, class T, class = Require<HasTypeTraits<BT, T>>>
using ConvertBaseTypeTo = detail::ConvertBaseTypeTo_t<BT, T>;
template<typename T, typename RT = detail::CopyConstness_t<T, std::conditional_t<IsCompound<T>, BaseType<T>, T>>,
class = Require<HasTypeTraits<T>>>
__host__ __device__ RT &GetElement(T &v, int eidx)
{
if constexpr (IsCompound<T>)
{
assert(eidx < NumElements<T>);
return reinterpret_cast<RT *>(&v)[eidx];
}
else
{
return v;
}
}
template<typename T, class = Require<HasTypeTraits<T>>>
__host__ __device__ T SetAll(BaseType<T> x)
{
T out{};
#pragma unroll
for (int e = 0; e < NumElements<T>; ++e)
{
GetElement(out, e) = x;
}
return out;
}
template<int N, typename BT, typename RT = MakeType<BT, N>, class = Require<HasTypeTraits<BT>>>
__host__ __device__ RT SetAll(BT x)
{
return SetAll<RT>(x);
}
template<class T, class = Require<HasTypeTraits<T>>>
__host__ const char *GetTypeName()
{
return TypeTraits<T>::name;
}
} // namespace nvcv::cuda
template<class T, class = nvcv::cuda::Require<nvcv::cuda::IsCompound<T>>>
__host__ std::ostream &operator<<(std::ostream &out, const T &v)
{
using BT = nvcv::cuda::BaseType<T>;
using OutType = std::conditional_t<sizeof(BT) == 1, int, BT>;
constexpr int NC = nvcv::cuda::NumComponents<T>;
out << nvcv::cuda::GetTypeName<T>() << "(";
for (int c = 0; c < NC; ++c)
{
if (c > 0)
{
out << ", ";
}
out << static_cast<OutType>(nvcv::cuda::GetElement(v, c));
}
out << ")";
return out;
}
#endif // NVCV_CUDA_TYPE_TRAITS_HPP