Skip to content

Commit

Permalink
Revert "[ADT] Add makeVisitor to STLExtras.h"
Browse files Browse the repository at this point in the history
This reverts commit 14a8aa6.

Mistakenly landed this before a patch it should depend on was accepted.
  • Loading branch information
slinder1 committed Jun 28, 2021
1 parent 1d85d08 commit 61242c0
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 199 deletions.
52 changes: 0 additions & 52 deletions llvm/include/llvm/ADT/STLExtras.h
Expand Up @@ -1299,58 +1299,6 @@ using is_one_of = disjunction<std::is_same<T, Ts>...>;
template <typename T, typename... Ts>
using are_base_of = conjunction<std::is_base_of<T, Ts>...>;

namespace detail {
template <typename... Ts> struct Visitor;

template <typename HeadT, typename... TailTs>
struct Visitor<HeadT, TailTs...> : remove_cvref_t<HeadT>, Visitor<TailTs...> {
explicit constexpr Visitor(HeadT &&Head, TailTs &&...Tail)
: remove_cvref_t<HeadT>(std::forward<HeadT>(Head)),
Visitor<TailTs...>(std::forward<TailTs>(Tail)...) {}
using remove_cvref_t<HeadT>::operator();
using Visitor<TailTs...>::operator();
};

template <typename HeadT> struct Visitor<HeadT> : remove_cvref_t<HeadT> {
explicit constexpr Visitor(HeadT &&Head)
: remove_cvref_t<HeadT>(std::forward<HeadT>(Head)) {}
using remove_cvref_t<HeadT>::operator();
};
} // namespace detail

/// Returns an opaquely-typed Callable object whose operator() overload set is
/// the sum of the operator() overload sets of each CallableT in CallableTs.
///
/// The type of the returned object derives from each CallableT in CallableTs.
/// The returned object is constructed by invoking the appropriate copy or move
/// constructor of each CallableT, as selected by overload resolution on the
/// corresponding argument to makeVisitor.
///
/// Example:
///
/// \code
/// auto visitor = makeVisitor([](auto) { return "unhandled type"; },
/// [](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".
/// auto c = visitor(3.14f); // `c` is now "unhandled type".
/// \endcode
///
/// Example of making a visitor with a lambda which captures a move-only type:
///
/// \code
/// std::unique_ptr<FooHandler> FH = /* ... */;
/// auto visitor = makeVisitor(
/// [FH{std::move(FH)}](Foo F) { return FH->handle(F); },
/// [](int i) { return i; },
/// [](std::string s) { return atoi(s); });
/// \endcode
template <typename... CallableTs>
constexpr decltype(auto) makeVisitor(CallableTs &&...Callables) {
return detail::Visitor<CallableTs...>(std::forward<CallableTs>(Callables)...);
}

//===----------------------------------------------------------------------===//
// Extra additions for arrays
//===----------------------------------------------------------------------===//
Expand Down
147 changes: 0 additions & 147 deletions llvm/unittests/ADT/STLExtrasTest.cpp
Expand Up @@ -764,151 +764,4 @@ TEST(STLExtras, Unique) {
EXPECT_EQ(3, V[3]);
}

TEST(STLExtrasTest, TypesAreDistinct) {
EXPECT_TRUE((llvm::TypesAreDistinct<>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int>::value));
EXPECT_FALSE((llvm::TypesAreDistinct<int, int>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int, float>::value));
EXPECT_FALSE((llvm::TypesAreDistinct<int, float, int>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int, float, double>::value));
EXPECT_FALSE((llvm::TypesAreDistinct<int, float, double, float>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int, int *>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int, int &>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int, int &&>::value));
EXPECT_TRUE((llvm::TypesAreDistinct<int, const int>::value));
}

TEST(STLExtrasTest, FirstIndexOfType) {
EXPECT_EQ((llvm::FirstIndexOfType<int, int>::value), 0u);
EXPECT_EQ((llvm::FirstIndexOfType<int, int, int>::value), 0u);
EXPECT_EQ((llvm::FirstIndexOfType<int, float, int>::value), 1u);
EXPECT_EQ((llvm::FirstIndexOfType<int const *, float, int, int const *,
const int>::value),
2u);
}

TEST(STLExtrasTest, TypeAtIndex) {
EXPECT_TRUE((std::is_same<int, llvm::TypeAtIndex<0, int>>::value));
EXPECT_TRUE((std::is_same<int, llvm::TypeAtIndex<0, int, float>>::value));
EXPECT_TRUE((std::is_same<float, llvm::TypeAtIndex<1, int, float>>::value));
EXPECT_TRUE(
(std::is_same<float, llvm::TypeAtIndex<1, int, float, double>>::value));
EXPECT_TRUE(
(std::is_same<float, llvm::TypeAtIndex<1, int, float, double>>::value));
EXPECT_TRUE(
(std::is_same<double, llvm::TypeAtIndex<2, int, float, double>>::value));
}

TEST(STLExtrasTest, MakeVisitorOneCallable) {
auto IdentityLambda = [](auto X) { return X; };
auto IdentityVisitor = makeVisitor(IdentityLambda);
EXPECT_EQ(IdentityLambda(1), IdentityVisitor(1));
EXPECT_EQ(IdentityLambda(2.0f), IdentityVisitor(2.0f));
EXPECT_TRUE((std::is_same<decltype(IdentityLambda(IdentityLambda)),
decltype(IdentityLambda)>::value));
EXPECT_TRUE((std::is_same<decltype(IdentityVisitor(IdentityVisitor)),
decltype(IdentityVisitor)>::value));
}

TEST(STLExtrasTest, MakeVisitorTwoCallables) {
auto Visitor =
makeVisitor([](int) { return "int"; }, [](std::string) { return "str"; });
EXPECT_EQ(Visitor(42), "int");
EXPECT_EQ(Visitor("foo"), "str");
}

TEST(STLExtrasTest, MakeVisitorCallableMultipleOperands) {
auto Second = makeVisitor([](int I, float F) { return F; },
[](float F, int I) { return I; });
EXPECT_EQ(Second(1.f, 1), 1);
EXPECT_EQ(Second(1, 1.f), 1.f);
}

TEST(STLExtrasTest, MakeVisitorDefaultCase) {
{
auto Visitor = makeVisitor([](int I) { return I + 100; },
[](float F) { return F * 2; },
[](auto) { return "unhandled type"; });
EXPECT_EQ(Visitor(24), 124);
EXPECT_EQ(Visitor(2.f), 4.f);
EXPECT_EQ(Visitor(2.), "unhandled type");
EXPECT_EQ(Visitor(Visitor), "unhandled type");
}
{
auto Visitor = makeVisitor([](auto) { return "unhandled type"; },
[](int I) { return I + 100; },
[](float F) { return F * 2; });
EXPECT_EQ(Visitor(24), 124);
EXPECT_EQ(Visitor(2.f), 4.f);
EXPECT_EQ(Visitor(2.), "unhandled type");
EXPECT_EQ(Visitor(Visitor), "unhandled type");
}
}

template <bool Moveable, bool Copyable>
struct Functor : Counted<Moveable, Copyable> {
using Counted<Moveable, Copyable>::Counted;
void operator()() {}
};

TEST(STLExtrasTest, MakeVisitorLifetimeSemanticsPRValue) {
int Copies = 0;
int Moves = 0;
int Destructors = 0;
{
auto V = makeVisitor(Functor<true, false>(Copies, Moves, Destructors));
(void)V;
EXPECT_EQ(0, Copies);
EXPECT_EQ(1, Moves);
EXPECT_EQ(1, Destructors);
}
EXPECT_EQ(0, Copies);
EXPECT_EQ(1, Moves);
EXPECT_EQ(2, Destructors);
}

TEST(STLExtrasTest, MakeVisitorLifetimeSemanticsRValue) {
int Copies = 0;
int Moves = 0;
int Destructors = 0;
{
Functor<true, false> F(Copies, Moves, Destructors);
{
auto V = makeVisitor(std::move(F));
(void)V;
EXPECT_EQ(0, Copies);
EXPECT_EQ(1, Moves);
EXPECT_EQ(0, Destructors);
}
EXPECT_EQ(0, Copies);
EXPECT_EQ(1, Moves);
EXPECT_EQ(1, Destructors);
}
EXPECT_EQ(0, Copies);
EXPECT_EQ(1, Moves);
EXPECT_EQ(2, Destructors);
}

TEST(STLExtrasTest, MakeVisitorLifetimeSemanticsLValue) {
int Copies = 0;
int Moves = 0;
int Destructors = 0;
{
Functor<true, true> F(Copies, Moves, Destructors);
{
auto V = makeVisitor(F);
(void)V;
EXPECT_EQ(1, Copies);
EXPECT_EQ(0, Moves);
EXPECT_EQ(0, Destructors);
}
EXPECT_EQ(1, Copies);
EXPECT_EQ(0, Moves);
EXPECT_EQ(1, Destructors);
}
EXPECT_EQ(1, Copies);
EXPECT_EQ(0, Moves);
EXPECT_EQ(2, Destructors);
}

} // namespace

0 comments on commit 61242c0

Please sign in to comment.