Skip to content

Commit

Permalink
Fix some clang-tidy warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
mikir committed Sep 6, 2024
1 parent 3514c90 commit ae051d1
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 78 deletions.
114 changes: 79 additions & 35 deletions runtime/src/zserio/Variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ struct type_at
using type = std::tuple_element_t<I, std::tuple<T...>>;
};

template <size_t I, class... T>
constexpr bool is_heap_allocated_v = variant_element<typename type_at<I, T...>::type>::is_heap_allocated::value;
template <auto I, typename... T>
using type_at_t = typename type_at<static_cast<size_t>(I), T...>::type;

template <auto I, class... T>
constexpr bool is_heap_allocated_v =
variant_element<typename type_at<static_cast<size_t>(I), T...>::type>::is_heap_allocated::value;

template <typename... ARGS>
struct is_first_alloc : is_first_allocator<::std::decay_t<ARGS>...>
Expand Down Expand Up @@ -94,7 +98,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
AllocatorHolder<ALLOC>(allocator)
{
if constexpr (detail::is_heap_allocated_v<0, T...>)
{
emplace<INDEX{}>(); // enforce no empty state like std::variant
}
}

/**
Expand All @@ -103,11 +109,10 @@ class BasicVariant : public AllocatorHolder<ALLOC>
* \param in_place_index Index of the active element.
* \param args Arguments to be forwarded for element construction.
*/
template <INDEX I, typename... ARGS,
std::enable_if_t<!detail::is_heap_allocated_v<size_t(I), T...>>* = nullptr,
template <INDEX I, typename... ARGS, std::enable_if_t<!detail::is_heap_allocated_v<I, T...>>* = nullptr,
std::enable_if_t<!detail::is_first_alloc<ARGS...>::value>* = nullptr>
BasicVariant(zserio::in_place_index_t<I>, ARGS&&... args) :
m_data(std::in_place_index<size_t(I)>, std::forward<ARGS>(args)...)
explicit BasicVariant(zserio::in_place_index_t<I>, ARGS&&... args) :
m_data(std::in_place_index<static_cast<size_t>(I)>, std::forward<ARGS>(args)...)
{}

/**
Expand All @@ -117,11 +122,10 @@ class BasicVariant : public AllocatorHolder<ALLOC>
* \param allocator Allocator to be used.
* \param args Arguments to be forwarded for element construction.
*/
template <INDEX I, typename... ARGS,
std::enable_if_t<!detail::is_heap_allocated_v<size_t(I), T...>>* = nullptr>
template <INDEX I, typename... ARGS, std::enable_if_t<!detail::is_heap_allocated_v<I, T...>>* = nullptr>
BasicVariant(zserio::in_place_index_t<I>, const ALLOC& allocator, ARGS&&... args) :
AllocatorHolder<ALLOC>(allocator),
m_data(std::in_place_index<size_t(I)>, std::forward<ARGS>(args)...)
m_data(std::in_place_index<static_cast<size_t>(I)>, std::forward<ARGS>(args)...)
{}

/**
Expand All @@ -131,11 +135,10 @@ class BasicVariant : public AllocatorHolder<ALLOC>
* \param allocator Allocator to be used.
* \param args Arguments to be forwarded for element construction.
*/
template <INDEX I, typename... ARGS,
std::enable_if_t<detail::is_heap_allocated_v<size_t(I), T...>>* = nullptr>
template <INDEX I, typename... ARGS, std::enable_if_t<detail::is_heap_allocated_v<I, T...>>* = nullptr>
BasicVariant(zserio::in_place_index_t<I>, const ALLOC& allocator, ARGS&&... args) :
AllocatorHolder<ALLOC>(allocator),
m_data(std::in_place_index<size_t(I)>, nullptr)
m_data(std::in_place_index<static_cast<size_t>(I)>, nullptr)
{
emplace<I>(std::forward<ARGS>(args)...);
}
Expand All @@ -146,11 +149,10 @@ class BasicVariant : public AllocatorHolder<ALLOC>
* \param in_place_index Index of the active element.
* \param args Arguments to be forwarded for element construction.
*/
template <INDEX I, typename... ARGS,
std::enable_if_t<detail::is_heap_allocated_v<size_t(I), T...>>* = nullptr,
template <INDEX I, typename... ARGS, std::enable_if_t<detail::is_heap_allocated_v<I, T...>>* = nullptr,
std::enable_if_t<!detail::is_first_alloc<ARGS...>::value>* = nullptr>
BasicVariant(zserio::in_place_index_t<I>, ARGS&&... args) :
m_data(std::in_place_index<size_t(I)>, nullptr)
explicit BasicVariant(zserio::in_place_index_t<I>, ARGS&&... args) :
m_data(std::in_place_index<static_cast<size_t>(I)>, nullptr)
{
emplace<I>(std::forward<ARGS>(args)...);
}
Expand Down Expand Up @@ -200,7 +202,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
{
clear();
if constexpr (AllocTraits::propagate_on_container_copy_assignment::value)
{
set_allocator(other.get_allocator_ref());
}
copy(other);
}

Expand Down Expand Up @@ -242,8 +246,10 @@ class BasicVariant : public AllocatorHolder<ALLOC>
if (this != &other)
{
clear();
if (AllocTraits::propagate_on_container_move_assignment::value)
if constexpr (AllocTraits::propagate_on_container_move_assignment::value)
{
set_allocator(std::move(other.get_allocator_ref()));
}
move(std::move(other));
}

Expand All @@ -267,15 +273,15 @@ class BasicVariant : public AllocatorHolder<ALLOC>
decltype(auto) emplace(ARGS&&... args)
{
clear();
if constexpr (detail::is_heap_allocated_v<size_t(I), T...>)
if constexpr (detail::is_heap_allocated_v<I, T...>)
{
using U = typename detail::type_at<size_t(I), T...>::type;
using U = detail::type_at_t<I, T...>;
U* ptr = allocateValue<U>(std::forward<ARGS>(args)...);
return *m_data.template emplace<size_t(I)>(ptr);
return *m_data.template emplace<static_cast<size_t>(I)>(ptr);
}
else
{
return m_data.template emplace<size_t(I)>(std::forward<ARGS>(args)...);
return m_data.template emplace<static_cast<size_t>(I)>(std::forward<ARGS>(args)...);
}
}

Expand All @@ -290,44 +296,57 @@ class BasicVariant : public AllocatorHolder<ALLOC>
/**
* Returns a pointer to an element at index I or nullptr if index doesn't match.
*/
template <INDEX I, typename U = typename detail::type_at<static_cast<size_t>(I), T...>::type>
template <INDEX I, typename U = detail::type_at_t<I, T...>>
U* get_if() noexcept
{
if (I != index() || valueless_by_exception())
{
return nullptr;

if constexpr (detail::is_heap_allocated_v<size_t(I), T...>)
}
if constexpr (detail::is_heap_allocated_v<I, T...>)
{
return std::get<static_cast<size_t>(I)>(m_data);
}
else
{
return std::addressof(std::get<static_cast<size_t>(I)>(m_data));
}
}

/**
* Returns a pointer to an element at index I or nullptr if index doesn't match.
*/
template <INDEX I, typename U = typename detail::type_at<static_cast<size_t>(I), T...>::type>
template <INDEX I, typename U = detail::type_at_t<I, T...>>
const U* get_if() const noexcept
{
if (I != index() || valueless_by_exception())
{
return nullptr;

if constexpr (detail::is_heap_allocated_v<size_t(I), T...>)
}
if constexpr (detail::is_heap_allocated_v<I, T...>)
{
return std::get<static_cast<size_t>(I)>(m_data);
}
else
{
return std::addressof(std::get<static_cast<size_t>(I)>(m_data));
}
}

/**
* Returns element at index I. Throws if index doesn't match
*
* \throw BadVariantAccess if the requested index doesn't match.
*/
template <INDEX I, typename U = typename detail::type_at<static_cast<size_t>(I), T...>::type>
template <INDEX I, typename U = detail::type_at_t<I, T...>>
U& get()
{
auto ptr = get_if<I>();
if (!ptr)
throw BadVariantAccess("Variant: Attempt to retrieve an inactive element at index ") << size_t(I);
{
throw BadVariantAccess("Variant: Attempt to retrieve an inactive element at index ")
<< static_cast<size_t>(I);
}
return *ptr;
}

Expand All @@ -336,12 +355,15 @@ class BasicVariant : public AllocatorHolder<ALLOC>
*
* \throw BadVariantAccess if the requested index doesn't match.
*/
template <INDEX I, typename U = typename detail::type_at<static_cast<size_t>(I), T...>::type>
template <INDEX I, typename U = detail::type_at_t<I, T...>>
const U& get() const
{
auto ptr = get_if<I>();
if (!ptr)
throw BadVariantAccess("Variant: Attempt to retrieve an inactive element at index ") << size_t(I);
{
throw BadVariantAccess("Variant: Attempt to retrieve an inactive element at index ")
<< static_cast<size_t>(I);
}
return *ptr;
}

Expand All @@ -353,11 +375,13 @@ class BasicVariant : public AllocatorHolder<ALLOC>
* \throw BadVariantAccess if variant is in valueless state.
*/
template <typename F>
auto visit(F&& fun) -> decltype(fun(std::declval<typename detail::type_at<0, T...>::type>()))
auto visit(F&& fun) -> decltype(fun(std::declval<detail::type_at_t<0, T...>>()))
{
if (valueless_by_exception())
{
throw BadVariantAccess("Variant: Cannot visit variant in valueless state");
using R = decltype(fun(std::declval<typename detail::type_at<0, T...>::type>()));
}
using R = decltype(fun(std::declval<detail::type_at_t<0, T...>>()));
if constexpr (std::is_same_v<R, void>)
{
std::nullptr_t dummy;
Expand All @@ -379,11 +403,13 @@ class BasicVariant : public AllocatorHolder<ALLOC>
* \throw BadVariantAccess if variant is in valueless state.
*/
template <typename F>
auto visit(F&& fun) const -> decltype(fun(std::declval<typename detail::type_at<0, T...>::type>()))
auto visit(F&& fun) const -> decltype(fun(std::declval<detail::type_at_t<0, T...>>()))
{
if (valueless_by_exception())
{
throw BadVariantAccess("Variant: Cannot visit variant in valueless state");
using R = decltype(fun(std::declval<typename detail::type_at<0, T...>::type>()));
}
using R = decltype(fun(std::declval<detail::type_at_t<0, T...>>()));
if constexpr (std::is_same_v<R, void>)
{
std::nullptr_t dummy;
Expand All @@ -405,7 +431,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
bool operator==(const BasicVariant& other) const
{
if (index() != other.index())
{
return false;
}
return equalSeq(other, std::make_index_sequence<sizeof...(T)>());
}

Expand All @@ -427,7 +455,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
bool operator<(const BasicVariant& other) const
{
if (index() != other.index())
{
return index() < other.index();
}
return lessSeq(other, std::make_index_sequence<sizeof...(T)>());
}

Expand Down Expand Up @@ -478,7 +508,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
void visit(F&& fun, R& returnValue)
{
if (I != m_data.index())
{
return;
}
if constexpr (std::is_same_v<R, std::nullptr_t>)
{
std::forward<F>(fun)(get<INDEX(I)>());
Expand All @@ -493,7 +525,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
void visit(F&& fun, R& returnValue) const
{
if (I != m_data.index())
{
return;
}
if constexpr (std::is_same_v<R, std::nullptr_t>)
{
std::forward<F>(fun)(get<INDEX(I)>());
Expand All @@ -514,7 +548,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
bool equal(const BasicVariant& other) const
{
if (I != m_data.index())
{
return true;
}
return get<INDEX(I)>() == other.get<INDEX(I)>();
}

Expand All @@ -528,7 +564,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
bool less(const BasicVariant& other) const
{
if (I != m_data.index())
{
return true;
}
return get<INDEX(I)>() < other.get<INDEX(I)>();
}

Expand Down Expand Up @@ -583,7 +621,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
void copy(const BasicVariant& other)
{
if (I != other.m_data.index())
{
return;
}
emplace<INDEX(I)>(other.get<INDEX(I)>());
}

Expand All @@ -604,7 +644,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
void move(BasicVariant&& other)
{
if (I != other.m_data.index())
{
return;
}
if constexpr (detail::is_heap_allocated_v<I, T...>)
{
auto& ptr = std::get<I>(other.m_data);
Expand Down Expand Up @@ -632,7 +674,9 @@ class BasicVariant : public AllocatorHolder<ALLOC>
void clear()
{
if (I != m_data.index())
{
return;
}
if constexpr (detail::is_heap_allocated_v<I, T...>)
{
destroyValue(std::get<I>(m_data));
Expand Down
Loading

0 comments on commit ae051d1

Please sign in to comment.