Optimize std::variant::index()

Jonathan Wakely jwakely@redhat.com
Wed Apr 24 00:04:00 GMT 2019


The variant::index() function doesn't know that some variants are
never valueless, meaning index() can never return variant_npos. By
reusing the Base::_M_valid() function we can avoid a branch for the
never-valueless types, because for those types _M_valid() just returns
true:

       constexpr size_t index() const noexcept
       {
-       if (this->_M_index ==
-           typename _Base::__index_type(variant_npos))
-         return variant_npos;
-       return this->_M_index;
+       if (this->_M_valid()) [[likely]]
+         return this->_M_index;
+       return variant_npos;
       }

This also avoids repeating the conversion to __index_type, which is
already done inside _M_valid().


Alternatively, we can just avoid a branch for all cases:

       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; }


The first option is more readable, but the second produces smaller
code. I think this can wait for stage 1 though.




More information about the Libstdc++ mailing list