From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by sourceware.org (Postfix) with ESMTPS id D9F11385783F for ; Wed, 26 Aug 2020 14:49:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D9F11385783F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wr1-x432.google.com with SMTP id r15so2061359wrp.13 for ; Wed, 26 Aug 2020 07:49:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZPUHtvswI5QMzpFm88RiQI7Jq5yA9OLvhGHSvEfBz+A=; b=gI77yLD5qiTkwfMTUee3fgFhtKNJjeaxyVIkNOUNH/mPSUnABkTJ+VlA1J7nBF/AVQ ftlqgfT6TSJsDmBVT8AX2PJ23Sej2jIvl/YrtBfkH8V3/Y+v20x+AshBJDu+AgSZd7Ar 8TZlbiVoTf4s+3y1ROXtg3Pj+N/0Vjc5LrfZjgARjW+jIje0MG42x2qvohQlP7BsHP2b GNNpKY7G3OTDTkdHA0dxyeploFvLbnHGuifcuVp1zSFDZCEF91Qf8XlRJorEvRWX6hPJ FVVYMFgJ9Fxey5ri8FFaR9vG2EOee6b465dAIEAA19mvJc2bEkiMhtwxDcfcdNMTYsdr vBiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZPUHtvswI5QMzpFm88RiQI7Jq5yA9OLvhGHSvEfBz+A=; b=N+lJ3WECkyQM1g7OSb4EHAO1JA2uNSZZlxW3DCHkfXoqTzJsRAFJiQyfEyNTXahKUc 5suoxpdtF22PSpE5U2J3VS/G80dVhQAxpZPKU87xlc/rLk43Ps9qaUIrUviX3shWn7r+ C5ig6jRSPzzd2FxPEjEdLKAYlILnLs3J5FNUMBeiXzvbe8vvxu9onF9ZJZIc7tLTnxeF yAmiP8EziAekW6i6dHckm+VLP+sapI+03hWabb3b8ogvDk3H10AjxI6C82pUK8rBEgvd Z25/bx279iP6ibvVSZR/W+yTjJgrFKl9hzg3KVOeDsj+JKaOHzcvPINFGEgeEL0DgUdP EjVQ== X-Gm-Message-State: AOAM531IaUCnsSP+rPREFFEatTgpY+oI/bDiAmdasbGv4SnIl9Lzr4BP 4VB1kvx3l21TSllqfNyhGs2vGaX/y3LEpw== X-Google-Smtp-Source: ABdhPJyZfmqPEBQAuJKUgrupgDxshvBhoeAou0ihLpA/SR8JmH9mt8wg870ncHLYWsp9jqK5uTBZLQ== X-Received: by 2002:adf:fac7:: with SMTP id a7mr3044362wrs.240.1598453366660; Wed, 26 Aug 2020 07:49:26 -0700 (PDT) Received: from localhost (host109-148-134-218.range109-148.btcentralplus.com. [109.148.134.218]) by smtp.gmail.com with ESMTPSA id e2sm7113848wrt.66.2020.08.26.07.49.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2020 07:49:26 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Subject: [PATCHv2 01/10] Rewrite valid-expr.h's internals in terms of the detection idiom (C++17/N4502) Date: Wed, 26 Aug 2020 15:49:08 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Aug 2020 14:49:29 -0000 From: Pedro Alves An earlier attempt at doing this had failed (wouldn't work in GCCs around 4.8, IIRC), but now that I try again, it works. I suspect that my previous attempt did not use the pre C++14-safe void_t (in traits.h). I want to switch to this model because: - It's the standard detection idiom that folks will learn starting with C++17. - In the enum_flags unit tests, I have a static_assert that triggers a warning (resulting in build error), which GCC does not suppress because the warning is not being triggered in the SFINAE context. Switching to the detection idiom fixes that. Alternatively, switching to the C++03-style expression-validity checking with a varargs overload would allow addressing that, but I think that would be going backwards idiomatically speaking. - While this patch shows a net increase of lines of code, the magic being added to traits.h can be removed in a few years when we start requiring C++17. gdbsupport/ChangeLog: * traits.h (struct nonesuch, struct detector, detected_or) (detected_or_t, is_detected, detected_t, detected_or) (detected_or_t, is_detected_exact, is_detected_convertible): New. * valid-expr.h (CHECK_VALID_EXPR_INT): Use gdb::is_detected_exact. --- gdbsupport/traits.h | 67 +++++++++++++++++++++++++++++++++++++++++ gdbsupport/valid-expr.h | 20 ++---------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/gdbsupport/traits.h b/gdbsupport/traits.h index 2a6f00654c7..93b609ac109 100644 --- a/gdbsupport/traits.h +++ b/gdbsupport/traits.h @@ -52,6 +52,73 @@ struct make_void { typedef void type; }; template using void_t = typename make_void::type; +/* Implementation of the detection idiom: + + - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf + - http://en.cppreference.com/w/cpp/experimental/is_detected + +*/ + +struct nonesuch +{ + nonesuch () = delete; + ~nonesuch () = delete; + nonesuch (const nonesuch &) = delete; + void operator= (const nonesuch &) = delete; +}; + +namespace detection_detail { +/* Implementation of the detection idiom (negative case). */ +template class Op, typename... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +/* Implementation of the detection idiom (positive case). */ +template class Op, typename... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +/* Detect whether Op is a valid type, use Default if not. */ +template class Op, + typename... Args> +using detected_or = detector; + +/* Op if that is a valid type, otherwise Default. */ +template class Op, + typename... Args> +using detected_or_t + = typename detected_or::type; + +} /* detection_detail */ + +template class Op, typename... Args> +using is_detected + = typename detection_detail::detector::value_t; + +template class Op, typename... Args> +using detected_t + = typename detection_detail::detector::type; + +template class Op, typename... Args> +using detected_or = detection_detail::detected_or; + +template class Op, typename... Args> +using detected_or_t = typename detected_or::type; + +template class Op, typename... Args> +using is_detected_exact = std::is_same>; + +template class Op, typename... Args> +using is_detected_convertible + = std::is_convertible, To>; + /* A few trait helpers, mainly stolen from libstdc++. Uppercase because "and/or", etc. are reserved keywords. */ diff --git a/gdbsupport/valid-expr.h b/gdbsupport/valid-expr.h index b1c84468147..a22fa61134f 100644 --- a/gdbsupport/valid-expr.h +++ b/gdbsupport/valid-expr.h @@ -58,26 +58,12 @@ #define CHECK_VALID_EXPR_INT(TYPENAMES, TYPES, VALID, EXPR_TYPE, EXPR) \ namespace CONCAT (check_valid_expr, __LINE__) { \ \ - template \ - struct is_valid_expression \ - : std::false_type {}; \ - \ template \ - struct is_valid_expression> \ - : std::true_type {}; \ + using archetype = decltype (EXPR); \ \ - static_assert (is_valid_expression::value == VALID, \ + static_assert (gdb::is_detected_exact::value == VALID, \ ""); \ - \ - template \ - struct is_same_type \ - : std::is_same {}; \ - \ - template \ - struct is_same_type> \ - : std::is_same {}; \ - \ - static_assert (is_same_type::value, ""); \ } /* namespace */ /* A few convenience macros that support expressions involving a -- 2.25.4