[PATCH] Changes to std::variant to reduce code size
Jonathan Wakely
jwakely@redhat.com
Thu May 16 11:29:00 GMT 2019
These two changes both result in smaller code for std::variant.
The first one means smaller tables of function pointers, because we
don't generate an instantiation for the valueless state. Instead we do
a runtime branch, marked [[unlikely]] to make _M_reset() a no-op if
it's already valueless. In a microbenchmark I couldn't measure any
performance difference due to the extra branch, so the code size
reduction seems worthwhile.
The second one removes a branch from the index() member by relying on
unsigned arithmetic. That also results in smaller code and I can't see
any downside.
* include/std/variant (_Variant_storage<false, _Types...>::_M_reset):
Replace raw visitation with a runtime check for the valueless state
and a non-raw visitor.
(_Variant_storage<false, _Types...>::_M_reset_impl): Remove.
(variant::index()): Remove branch.
Tested powerpc64le-linux, any objections?
-------------- next part --------------
commit a36ecd71f2e7ce95b479d4c06597f2ee0dfe27b1
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed May 15 22:33:31 2019 +0100
Changes to std::variant to reduce code size
* include/std/variant (_Variant_storage<false, _Types...>::_M_reset):
Replace raw visitation with a runtime check for the valueless state
and a non-raw visitor.
(_Variant_storage<false, _Types...>::_M_reset_impl): Remove.
(variant::index()): Remove branch.
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 8c710c30de5..8844c54913f 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -396,19 +396,16 @@ namespace __variant
_M_index(_Np)
{ }
- constexpr void _M_reset_impl()
- {
- __variant::__raw_visit([](auto&& __this_mem) mutable
- {
- if constexpr (!is_same_v<remove_reference_t<decltype(__this_mem)>,
- __variant_cookie>)
- std::_Destroy(std::__addressof(__this_mem));
- }, __variant_cast<_Types...>(*this));
- }
-
void _M_reset()
{
- _M_reset_impl();
+ if (!_M_valid()) [[unlikely]]
+ return;
+
+ std::__do_visit<void>([](auto&& __this_mem) mutable
+ {
+ std::_Destroy(std::__addressof(__this_mem));
+ }, __variant_cast<_Types...>(*this));
+
_M_index = variant_npos;
}
@@ -1485,12 +1482,7 @@ namespace __variant
{ return !this->_M_valid(); }
constexpr size_t index() const noexcept
- {
- if (this->_M_index ==
- typename _Base::__index_type(variant_npos))
- return variant_npos;
- return this->_M_index;
- }
+ { return size_t(typename _Base::__index_type(this->_M_index + 1)) - 1; }
void
swap(variant& __rhs)
More information about the Gcc-patches
mailing list