diff --git a/llvm/include/llvm/ADT/Visitor.h b/llvm/include/llvm/ADT/Visitor.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/ADT/Visitor.h @@ -0,0 +1,53 @@ +//===- llvm/ADT/Visitor.h - Visitors constructed from lambdas. --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the Visitor class, which is a utility that constructs +// visitors from lambdas. Can be used for e.g. visiting PointerUnion. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_VISITOR_H +#define LLVM_ADT_VISITOR_H + +namespace llvm { + +namespace visitor_detail { + +template struct Visitor; + +template +struct Visitor : Head, Visitor { + explicit Visitor(Head head, Tail... tail) + : Head(head), Visitor(tail...) {} + + using Head::operator(); + using Visitor::operator(); +}; + +template struct Visitor : Head { + explicit Visitor(Head head) : Head(head) {} + + using Head::operator(); +}; + +} // namespace visitor_detail + +/// Utility to construct visitors from lambdas. +/// +/// auto visitor = makeVisitor( +/// [](int i) { return "int"; }, +/// [](std::string s) { return "str"; }); +/// auto a = visitor(42); // `a` is now "int". +/// auto b = visitor("foo"); // `b` is now "str". +template auto makeVisitor(Lambdas... lambdas) { + return visitor_detail::Visitor(lambdas...); +} + +} // namespace llvm + +#endif diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt --- a/llvm/unittests/ADT/CMakeLists.txt +++ b/llvm/unittests/ADT/CMakeLists.txt @@ -77,6 +77,7 @@ TwineTest.cpp TypeSwitchTest.cpp TypeTraitsTest.cpp + VariantTest.cpp WaymarkingTest.cpp ) diff --git a/llvm/unittests/ADT/VisitorTest.cpp b/llvm/unittests/ADT/VisitorTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/ADT/VisitorTest.cpp @@ -0,0 +1,26 @@ +//===- VisitorTest.cpp - Unit tests for a sequence abstraciton -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/Visitor.h" +#include "gtest/gtest.h" + +#include + +using namespace llvm; + +namespace { + +TEST(VisitorTest, Basic) { + auto visitor = llvm::makeVisitor([](int a) { return "int"; }, + [](std::string a) { return "str"; }); + + EXPECT_EQ("int", visitor(42)); + EXPECT_EQ("str", visitor("foo")); +} + +} // anonymous namespace