From 469218a3f9b8f72b38d82dd978ec231ab3de14ef Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 2 Oct 2018 15:00:50 +0100 Subject: [PATCH] Avoid redundant runtime checks in std::visit Calling std::get will check some static assertions and also do a runtime check for a valid index before calling __detail::__variant::__get. The std::visit function already handles the case where any variant has an invalid index, so __get can be used directly in __visit_invoke. * include/std/variant (__gen_vtable_impl::__visit_invoke): Call __get directly instead of get, as caller ensures correct index is used. (holds_alternative, get, get_if): Remove redundant inline specifiers. (_VARIANT_RELATION_FUNCTION_TEMPLATE): Likewise. From-SVN: r264786 --- libstdc++-v3/ChangeLog | 7 +++++++ libstdc++-v3/include/std/variant | 34 +++++++++++++++----------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c51355182b0..388ae9d9069 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2018-10-02 Jonathan Wakely + + * include/std/variant (__gen_vtable_impl::__visit_invoke): Call __get + directly instead of get, as caller ensures correct index is used. + (holds_alternative, get, get_if): Remove redundant inline specifiers. + (_VARIANT_RELATION_FUNCTION_TEMPLATE): Likewise. + 2018-10-02 Joseph Myers * testsuite/lib/libstdc++.exp (libstdc++_init): Use diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 9289eef28cf..ff340cfc897 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -811,9 +811,8 @@ namespace __variant { using _Alternative = variant_alternative_t<__index, _Next>; __element = __gen_vtable_impl< - remove_reference_t< - decltype(__element)>, tuple<_Variants...>, - std::index_sequence<__indices..., __index>>::_S_apply(); + remove_reference_t, tuple<_Variants...>, + std::index_sequence<__indices..., __index>>::_S_apply(); } }; @@ -826,11 +825,11 @@ namespace __variant using _Array_type = _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>; - decltype(auto) - static constexpr __visit_invoke(_Visitor&& __visitor, _Variants... __vars) + static constexpr decltype(auto) + __visit_invoke(_Visitor&& __visitor, _Variants... __vars) { return std::__invoke(std::forward<_Visitor>(__visitor), - std::get<__indices>(std::forward<_Variants>(__vars))...); + __variant::__get<__indices>(std::forward<_Variants>(__vars))...); } static constexpr auto @@ -871,8 +870,8 @@ namespace __variant } // namespace __detail template - inline constexpr bool holds_alternative(const variant<_Types...>& __v) - noexcept + constexpr bool + holds_alternative(const variant<_Types...>& __v) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); @@ -880,7 +879,7 @@ namespace __variant } template - constexpr inline _Tp& get(variant<_Types...>& __v) + constexpr _Tp& get(variant<_Types...>& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); @@ -889,7 +888,7 @@ namespace __variant } template - constexpr inline _Tp&& get(variant<_Types...>&& __v) + constexpr _Tp&& get(variant<_Types...>&& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); @@ -899,7 +898,7 @@ namespace __variant } template - constexpr inline const _Tp& get(const variant<_Types...>& __v) + constexpr const _Tp& get(const variant<_Types...>& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); @@ -908,7 +907,7 @@ namespace __variant } template - constexpr inline const _Tp&& get(const variant<_Types...>&& __v) + constexpr const _Tp&& get(const variant<_Types...>&& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); @@ -918,8 +917,7 @@ namespace __variant } template - constexpr inline - add_pointer_t>> + constexpr add_pointer_t>> get_if(variant<_Types...>* __ptr) noexcept { using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; @@ -932,7 +930,7 @@ namespace __variant } template - constexpr inline + constexpr add_pointer_t>> get_if(const variant<_Types...>* __ptr) noexcept { @@ -946,7 +944,7 @@ namespace __variant } template - constexpr inline add_pointer_t<_Tp> + constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __ptr) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, @@ -957,7 +955,7 @@ namespace __variant } template - constexpr inline add_pointer_t + constexpr add_pointer_t get_if(const variant<_Types...>* __ptr) noexcept { @@ -1277,7 +1275,7 @@ namespace __variant { &__detail::__variant::__erased_##__NAME< \ const variant&, __indices>... }; \ template \ - constexpr inline bool \ + constexpr bool \ _M_##__NAME(const variant& __rhs, \ std::index_sequence<__indices...>) const \ { \ -- 2.30.2