blob: 786f7ef402f8690fe557d776b68785c386815eb9 [file] [log] [blame]
#pragma once
#include <type_traits>
#include <variant>
/** See `sdbusplus::utility::dedup_variant` below. */
namespace sdbusplus
{
namespace utility
{
namespace details
{
/** Find the deduplicated variant type.
*
* @tparam T - A type of the form 'variant<...>'.
* @tparam Unused - An empty type set (non-empty sets are matched in
* specialization).
*
* This template is only matched when Unused is empty, which means all
* types have been processed (deduplicated).
*/
template <typename T, typename... Unused>
struct dedup_variant
{
using type = T;
static_assert(sizeof...(Unused) == 0);
};
/** Find the deduplicated variant type.
*
* @tparam Done - The types which have already been deduplicated.
* @tparam First - The first type to be deduplicated.
* @tparam Rest - The remaining types to be deduplicated.
*
* This template specialization is matched when there are remaining
* items to be analyzed, since the 'First' is a stronger match than the
* (empty) 'Types' in the previous template.
*
* Check for First in Done and recursively create the variant type as
* appropriate (add First if First not in Done, skip otherwise).
*/
template <typename... Done, typename First, typename... Rest>
struct dedup_variant<std::variant<Done...>, First, Rest...> :
public std::conditional_t<
(std::is_same_v<First, Done> || ...),
dedup_variant<std::variant<Done...>, Rest...>,
dedup_variant<std::variant<Done..., First>, Rest...>>
{};
} // namespace details
/** This type is useful for generated code which may inadvertantly contain
* duplicate types if specified simply as `std::variant<A, B, C>`. Some
* types, such as `uint32_t` and `size_t` are the same on some architectures
* and different on others. `dedup_variant_t<uint32_t, size_t>` will evalute
* to `std::variant<uint32_t>` on architectures where there is a collision.
*/
template <typename T, typename... Types>
using dedup_variant_t =
typename details::dedup_variant<std::variant<T>, Types...>::type;
// Keep temporarily for backwards compatibility.
// openbmc/bmcweb
// openbmc/smbios-mdr
template <typename T, typename... Types>
using dedup_variant = dedup_variant_t<T, Types...>;
} // namespace utility
} // namespace sdbusplus