From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by sourceware.org (Postfix) with ESMTPS id AB12A38493D4 for ; Tue, 21 Feb 2023 12:04:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB12A38493D4 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x435.google.com with SMTP id r7so3992084wrz.6 for ; Tue, 21 Feb 2023 04:04:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=eQjqnCabeSQGQ4Q9UTx1rnkZ8Ka6kmB8wDytSJyo+3w=; b=CsJ3R3oLpAuzo4/QAUFEhSX8SuacaEVyHcS1qaywHIAnnlLoG3K+I/kvt59hXj0X59 q1YZPfRng/RzDwseirTun0dIvQVzo7Bo47S4sRY3ctAU0cK1MFab6pdmx8idwI86xNxY qIkDREPH5csP6AdlqID3xlHnbTLjxr8fMMA5a1bQ+jmeCf0/6R965K+5C9hJ2u0r1z5u +fpLVmHjDd+uGiCk7j6clliecWF3E8vw/wiSl9N/n4j216miyFq9dCt4kWxmdOsk5PYB GAlunffNCGfwHaWqsXurjh5m/hKX+L6MerlcLfGsxamZKhWL+xTtglDv6EfAsD2pzA3r aoBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=eQjqnCabeSQGQ4Q9UTx1rnkZ8Ka6kmB8wDytSJyo+3w=; b=WP0deW366wh5wTsyVijsuyurEThnHg7UDXq6IIU1BPWW0SW385oFK7v106hWKHjsW8 VoADUrI5+1U1Yanp0gydEV8LhESTEc4qY7sgdVd0rRNrCow25X7P7Ff1odUW4QqQx+S5 QaAODGgclgAMStxgEa9P74jZy2mSBo/tGqSdZOQ3jvoN/QFqGUnFoVgCzEto0G+jevSp sGfwlQRC4mrKbxAQf75v0oKePD/yeoUHyVSuPPE9asdHjDjjE5JDimvMFtx4GBxEZy39 g35I+IWDJUKPkQLa/kTWXP5gCTpUo0bZmFjiDD/1grkmWXBzGnTr6eCKn40p1sWYp4s4 GJ6Q== X-Gm-Message-State: AO0yUKXFBZDUEViHaZSbTeakHVmrJcPd7mJ0Lh2+qo0u+lR205r3SLR1 6fEJVGdB35g7zwObMmXhveHAF1P8jeBrPxiKiw== X-Google-Smtp-Source: AK7set+24sFKkw673n408oqSvaP5sz6eFq7U2yOkMCY55Xjv/4lRv40Fm9scqwbSv4EodZKMMseOqg== X-Received: by 2002:adf:e184:0:b0:2c5:5ec7:43bc with SMTP id az4-20020adfe184000000b002c55ec743bcmr2422655wrb.18.1676981047586; Tue, 21 Feb 2023 04:04:07 -0800 (PST) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id c15-20020adffb4f000000b002c55b0e6ef1sm5013811wrs.4.2023.02.21.04.04.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 04:04:07 -0800 (PST) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, YizhePKU Subject: [committed 055/103] gccrs: Implement the inline visitor Date: Tue, 21 Feb 2023 13:01:45 +0100 Message-Id: <20230221120230.596966-56-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230221120230.596966-1-arthur.cohen@embecosm.com> References: <20230221120230.596966-1-arthur.cohen@embecosm.com> Reply-To: arthur.cohen@embecosm.com MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: YizhePKU gcc/rust/ChangeLog: * util/rust-inline-visitor.h: New file. --- gcc/rust/util/rust-inline-visitor.h | 95 +++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 gcc/rust/util/rust-inline-visitor.h diff --git a/gcc/rust/util/rust-inline-visitor.h b/gcc/rust/util/rust-inline-visitor.h new file mode 100644 index 00000000000..18920d9f93a --- /dev/null +++ b/gcc/rust/util/rust-inline-visitor.h @@ -0,0 +1,95 @@ +// Copyright (C) 2021-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +// An improved implementation of the inline visitor. +// Original idea from https://members.accu.org/index.php/articles/2021 + +#ifndef RUST_INLINE_VISITOR +#define RUST_INLINE_VISITOR + +#include +#include + +namespace Rust { + +// Wrapper for the target Visitor we're matching against. +// Consumes the final nullptr of the _args linked list. +template struct EmptyVisitor : TargetVisitor +{ + EmptyVisitor (std::nullptr_t ptr) {} + + using TargetVisitor::visit; +}; + +// Wrapper for a (possibly incomplete) Visitor. +template struct VisitorWrapper +{ + // Lambdas are stored in _args as a linked list and passed to the actual + // visitor when end_visitor() is called. + Args _args; + + // The actual visitor being created. + // Each visitor inherits from the last one and implements one more visit(). + template struct Visitor : BaseVisitor + { + F _f; + + Visitor (std::pair &&args) + : BaseVisitor (std::move (args.second)), _f (std::move (args.first)) + {} + + using BaseVisitor::visit; + virtual void visit (T &t) final override { _f (t); } + }; + + VisitorWrapper (Args &&args) : _args (std::move (args)) {} + + // Add another visit() method to the visitor. + // _args will be moved over, so don't keep the old wrapper around. + template + VisitorWrapper, std::pair> on (F &&f) + { + return VisitorWrapper, std::pair> ( + std::make_pair (std::move (f), std::move (_args))); + } + + // Returns the finished visitor. + // NOTE: The reference implementation has a bug that exposes this method even + // when BaseVisitor is still an abstract class. The C++11 standard states that + // "An abstract class shall not be used [...] as a function return type". GCC + // rejects the buggy code as expected, but Clang accepts the code as long as + // the method is not actually called. Maybe this is a bug in Clang? + template + typename std::enable_if::value, T>::type + end_visitor () + { + return T (std::move (_args)); + } +}; + +// The entry point. +template +VisitorWrapper, std::nullptr_t> +begin_visitor () +{ + return VisitorWrapper, std::nullptr_t> (nullptr); +} + +} // namespace Rust + +#endif -- 2.39.1