* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#ifndef TLA_TUPLE_HPP
#define TLA_TUPLE_HPP
#include "tla/numeric/integral_constant.hpp"
#include "tla/numeric/integer_sequence.hpp"
namespace tla {
namespace detail {
template <size_t N, class T, bool IsEmpty = std::is_empty<T>::value>
struct EBO;
template <size_t N, class T>
struct EBO<N, T, true> {
CATLASS_HOST_DEVICE constexpr
EBO() {}
CATLASS_HOST_DEVICE constexpr
EBO(T const&) {}
};
template <size_t N, class T>
CATLASS_HOST_DEVICE constexpr
T getv(EBO<N, T, true> const&)
{
return {};
}
template <size_t N, class T>
struct EBO<N, T, false> {
CATLASS_HOST_DEVICE constexpr
EBO() : t_{} {}
CATLASS_HOST_DEVICE constexpr
EBO(T const& t) : t_{t} {}
T t_;
};
template <size_t N, class T>
CATLASS_HOST_DEVICE constexpr
T const& getv(EBO<N, T, false> const& x)
{
return x.t_;
}
template <size_t N, class T>
CATLASS_HOST_DEVICE constexpr
T& getv(EBO<N, T, false>& x)
{
return x.t_;
}
template <class IdxSeq, class... T>
struct TupleBase;
template <size_t... I, class... T>
struct TupleBase<index_sequence<I...>, T...> : EBO<I, T>... {
CATLASS_HOST_DEVICE constexpr
TupleBase() {}
CATLASS_HOST_DEVICE constexpr
TupleBase(T const&... t) : EBO<I, T>(t)... {}
};
}
template <class... T>
struct tuple : detail::TupleBase<make_index_sequence<sizeof...(T)>, T...> {
CATLASS_HOST_DEVICE constexpr
tuple() {}
CATLASS_HOST_DEVICE constexpr
tuple(T const&... t) : detail::TupleBase<make_index_sequence<sizeof...(T)>, T...>(t...) {}
};
template <size_t I, class... T>
CATLASS_HOST_DEVICE constexpr
decltype(auto) get(tuple<T...> const& t) noexcept
{
static_assert(I < sizeof...(T), "Index out of range");
return detail::getv<I>(t);
}
template <size_t I, class... T>
CATLASS_HOST_DEVICE constexpr
decltype(auto) get(tuple<T...>& t) noexcept
{
static_assert(I < sizeof...(T), "Index out of range");
return detail::getv<I>(t);
}
template <size_t I, class... T>
CATLASS_HOST_DEVICE constexpr
decltype(auto) get(tuple<T...>&& t) noexcept
{
static_assert(I < sizeof...(T), "Index out of range");
return detail::getv<I>(static_cast<tuple<T...>&&>(t));
}
namespace detail {
template <class T>
auto has_tuple_size(T*) -> bool_constant<(0 <= tuple_size<T>::value)>;
auto has_tuple_size(...) -> false_type;
}
template <class T>
struct is_tuple : decltype(detail::has_tuple_size((T*)0)) {};
template <class... T>
struct tuple_size<tla::tuple<T...>>
: std::integral_constant<size_t, sizeof...(T)> {};
template <class... T>
struct tuple_size<const tla::tuple<T...>>
: std::integral_constant<size_t, sizeof...(T)> {};
template <class... T>
CATLASS_HOST_DEVICE constexpr
tuple<T...>
MakeTuple(T const&... t)
{
return {t...};
}
}
#endif