From patchwork Tue Oct 2 14:00:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 977859 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-486784-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Snn5dWgu"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42PgmW1r0Jz9t5H for ; Wed, 3 Oct 2018 00:01:13 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=o2SP1k4XmdvEfhymkGsdTDf+nPraud4T1Y7T9BB9M4xzl3w9W61nh Wj7N0uUzYkOrU9+nSzLVIp3orPTOp9iVPAdu+urFh/CJW2a/7Bu+tJcA1QRZ/oNG rhLVxJih6iCUzERMwS8n3Hqj1eJ0XrE9JAR2oltGhpDYh3I8Chz4Uw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=OBHKyD66UsL/ZLedGkvhCb8nPlM=; b=Snn5dWgujUPRz+Rv08gn GSqZyx+miCoTukSkonQOobC2DVNLURYdhnuhG7W8QhTVuyiB0NgXao0lKT+9StPd kMUbXYn+kXdLUGkvWutx1TuWEL22sznCZq7N55Y7uUuAImoVexrv3YFlsBMW+aMK dYKP2gKFXoJiMXYf2EL10BA= Received: (qmail 53551 invoked by alias); 2 Oct 2018 14:00:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 53278 invoked by uid 89); 2 Oct 2018 14:00:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sk:jwakely, visit X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 02 Oct 2018 14:00:25 +0000 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B85CA8F226; Tue, 2 Oct 2018 14:00:06 +0000 (UTC) Received: from localhost (unknown [10.33.36.76]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5A465308BDA2; Tue, 2 Oct 2018 14:00:06 +0000 (UTC) Date: Tue, 2 Oct 2018 15:00:05 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] Avoid redundant runtime checks in std::visit Message-ID: <20181002140005.GA22216@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.9.2 (2017-12-15) 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. Tested x86_64-linux, committed to trunk. commit 79a88f5377344677fae1a21028293e8943eea209 Author: Jonathan Wakely Date: Tue Oct 2 14:12:20 2018 +0100 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. 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 \ { \