brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 75d50f4 Raw
275 lines · cpp
1//===- llvm/unittest/ADT/StringSwitchTest.cpp - StringSwitch unit tests ---===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/StringSwitch.h"10#include "gtest/gtest.h"11 12using namespace llvm;13 14TEST(StringSwitchTest, Case) {15  auto Translate = [](StringRef S) {16    return llvm::StringSwitch<int>(S)17        .Case("0", 0)18        .Case("1", 1)19        .Case("2", 2)20        .Case("3", 3)21        .Case("4", 4)22        .Case("5", 5)23        .Case("6", 6)24        .Case("7", 7)25        .Case("8", 8)26        .Case("9", 9)27        .Case("A", 10)28        .Case("B", 11)29        .Case("C", 12)30        .Case("D", 13)31        .Case("E", 14)32        .Case("F", 15)33        .Default(-1);34  };35  EXPECT_EQ(1, Translate("1"));36  EXPECT_EQ(2, Translate("2"));37  EXPECT_EQ(11, Translate("B"));38  EXPECT_EQ(-1, Translate("b"));39  EXPECT_EQ(-1, Translate(""));40  EXPECT_EQ(-1, Translate("Test"));41}42 43TEST(StringSwitchTest, CaseLower) {44  auto Translate = [](StringRef S) {45    return llvm::StringSwitch<int>(S)46        .Case("0", 0)47        .Case("1", 1)48        .Case("2", 2)49        .Case("3", 3)50        .Case("4", 4)51        .Case("5", 5)52        .Case("6", 6)53        .Case("7", 7)54        .Case("8", 8)55        .Case("9", 9)56        .CaseLower("A", 10)57        .CaseLower("B", 11)58        .CaseLower("C", 12)59        .CaseLower("D", 13)60        .CaseLower("E", 14)61        .CaseLower("F", 15)62        .Default(-1);63  };64  EXPECT_EQ(1, Translate("1"));65  EXPECT_EQ(2, Translate("2"));66  EXPECT_EQ(11, Translate("B"));67  EXPECT_EQ(11, Translate("b"));68 69  EXPECT_EQ(-1, Translate(""));70  EXPECT_EQ(-1, Translate("Test"));71}72 73TEST(StringSwitchTest, StartsWith) {74  auto Translate = [](StringRef S) {75    return llvm::StringSwitch<std::function<int(int, int)>>(S)76        .StartsWith("add", [](int X, int Y) { return X + Y; })77        .StartsWith("sub", [](int X, int Y) { return X - Y; })78        .StartsWith("mul", [](int X, int Y) { return X * Y; })79        .StartsWith("div", [](int X, int Y) { return X / Y; })80        .Default([](int X, int Y) { return 0; });81  };82 83  EXPECT_EQ(15, Translate("adder")(10, 5));84  EXPECT_EQ(5, Translate("subtracter")(10, 5));85  EXPECT_EQ(50, Translate("multiplier")(10, 5));86  EXPECT_EQ(2, Translate("divider")(10, 5));87 88  EXPECT_EQ(0, Translate("nothing")(10, 5));89  EXPECT_EQ(0, Translate("ADDER")(10, 5));90}91 92TEST(StringSwitchTest, StartsWithLower) {93  auto Translate = [](StringRef S) {94    return llvm::StringSwitch<std::function<int(int, int)>>(S)95        .StartsWithLower("add", [](int X, int Y) { return X + Y; })96        .StartsWithLower("sub", [](int X, int Y) { return X - Y; })97        .StartsWithLower("mul", [](int X, int Y) { return X * Y; })98        .StartsWithLower("div", [](int X, int Y) { return X / Y; })99        .Default([](int X, int Y) { return 0; });100  };101 102  EXPECT_EQ(15, Translate("adder")(10, 5));103  EXPECT_EQ(5, Translate("subtracter")(10, 5));104  EXPECT_EQ(50, Translate("multiplier")(10, 5));105  EXPECT_EQ(2, Translate("divider")(10, 5));106 107  EXPECT_EQ(15, Translate("AdDeR")(10, 5));108  EXPECT_EQ(5, Translate("SuBtRaCtEr")(10, 5));109  EXPECT_EQ(50, Translate("MuLtIpLiEr")(10, 5));110  EXPECT_EQ(2, Translate("DiViDeR")(10, 5));111 112  EXPECT_EQ(0, Translate("nothing")(10, 5));113}114 115TEST(StringSwitchTest, EndsWith) {116  enum class Suffix { Possible, PastTense, Process, InProgressAction, Unknown };117 118  auto Translate = [](StringRef S) {119    return llvm::StringSwitch<Suffix>(S)120        .EndsWith("able", Suffix::Possible)121        .EndsWith("ed", Suffix::PastTense)122        .EndsWith("ation", Suffix::Process)123        .EndsWith("ing", Suffix::InProgressAction)124        .Default(Suffix::Unknown);125  };126 127  EXPECT_EQ(Suffix::Possible, Translate("optimizable"));128  EXPECT_EQ(Suffix::PastTense, Translate("optimized"));129  EXPECT_EQ(Suffix::Process, Translate("optimization"));130  EXPECT_EQ(Suffix::InProgressAction, Translate("optimizing"));131  EXPECT_EQ(Suffix::Unknown, Translate("optimizer"));132  EXPECT_EQ(Suffix::Unknown, Translate("OPTIMIZABLE"));133}134 135TEST(StringSwitchTest, EndsWithLower) {136  enum class Suffix { Possible, PastTense, Process, InProgressAction, Unknown };137 138  auto Translate = [](StringRef S) {139    return llvm::StringSwitch<Suffix>(S)140        .EndsWithLower("able", Suffix::Possible)141        .EndsWithLower("ed", Suffix::PastTense)142        .EndsWithLower("ation", Suffix::Process)143        .EndsWithLower("ing", Suffix::InProgressAction)144        .Default(Suffix::Unknown);145  };146 147  EXPECT_EQ(Suffix::Possible, Translate("optimizable"));148  EXPECT_EQ(Suffix::Possible, Translate("OPTIMIZABLE"));149  EXPECT_EQ(Suffix::PastTense, Translate("optimized"));150  EXPECT_EQ(Suffix::Process, Translate("optimization"));151  EXPECT_EQ(Suffix::InProgressAction, Translate("optimizing"));152  EXPECT_EQ(Suffix::Unknown, Translate("optimizer"));153}154 155TEST(StringSwitchTest, Cases) {156  enum class OSType { Windows, Linux, MacOS, Unknown };157 158  auto Translate = [](StringRef S) {159    return llvm::StringSwitch<OSType>(S)160        .Cases({StringLiteral::withInnerNUL("wind\0ws"), "win32", "winnt"},161               OSType::Windows)162        .Cases({"linux", "unix", "*nix", "posix"}, OSType::Linux)163        .Cases({"macos", "osx"}, OSType::MacOS)164        .Default(OSType::Unknown);165  };166 167  EXPECT_EQ(OSType::Windows, Translate(llvm::StringRef("wind\0ws", 7)));168  EXPECT_EQ(OSType::Windows, Translate("win32"));169  EXPECT_EQ(OSType::Windows, Translate("winnt"));170 171  EXPECT_EQ(OSType::Linux, Translate("linux"));172  EXPECT_EQ(OSType::Linux, Translate("unix"));173  EXPECT_EQ(OSType::Linux, Translate("*nix"));174  EXPECT_EQ(OSType::Linux, Translate("posix"));175 176  EXPECT_EQ(OSType::MacOS, Translate("macos"));177  EXPECT_EQ(OSType::MacOS, Translate("osx"));178 179  // Note that the whole null-terminator embedded string is required for the180  // case to match.181  EXPECT_EQ(OSType::Unknown, Translate("wind"));182  EXPECT_EQ(OSType::Unknown, Translate("Windows"));183  EXPECT_EQ(OSType::Unknown, Translate("MacOS"));184  EXPECT_EQ(OSType::Unknown, Translate(""));185}186 187TEST(StringSwitchTest, CasesLower) {188  enum class OSType { Windows, Linux, MacOS, Unknown };189 190  auto Translate = [](StringRef S) {191    return llvm::StringSwitch<OSType>(S)192        .CasesLower({StringLiteral::withInnerNUL("wind\0ws"), "win32", "winnt"},193                    OSType::Windows)194        .CasesLower({"linux", "unix", "*nix", "posix"}, OSType::Linux)195        .CasesLower({"macos", "osx"}, OSType::MacOS)196        .Default(OSType::Unknown);197  };198 199  EXPECT_EQ(OSType::Windows, Translate(llvm::StringRef("WIND\0WS", 7)));200  EXPECT_EQ(OSType::Windows, Translate("WIN32"));201  EXPECT_EQ(OSType::Windows, Translate("WINNT"));202 203  EXPECT_EQ(OSType::Linux, Translate("LINUX"));204  EXPECT_EQ(OSType::Linux, Translate("UNIX"));205  EXPECT_EQ(OSType::Linux, Translate("*NIX"));206  EXPECT_EQ(OSType::Linux, Translate("POSIX"));207 208  EXPECT_EQ(OSType::Windows, Translate(llvm::StringRef("wind\0ws", 7)));209  EXPECT_EQ(OSType::Linux, Translate("linux"));210 211  EXPECT_EQ(OSType::MacOS, Translate("macOS"));212  EXPECT_EQ(OSType::MacOS, Translate("OSX"));213 214  EXPECT_EQ(OSType::Unknown, Translate("wind"));215  EXPECT_EQ(OSType::Unknown, Translate(""));216}217 218TEST(StringSwitchTest, CasesCopies) {219  struct Copyable {220    unsigned &NumCopies;221    Copyable(unsigned &Value) : NumCopies(Value) {}222    Copyable(const Copyable &Other) : NumCopies(Other.NumCopies) {223      ++NumCopies;224    }225    Copyable &operator=(const Copyable &Other) {226      ++NumCopies;227      return *this;228    }229  };230 231  // Check that evaluating multiple cases does not cause unnecessary copies.232  unsigned NumCopies = 0;233  llvm::StringSwitch<Copyable, void>("baz").Cases({"foo", "bar", "baz", "qux"},234                                                  Copyable{NumCopies});235  EXPECT_EQ(NumCopies, 1u);236 237  NumCopies = 0;238  llvm::StringSwitch<Copyable, void>("baz").CasesLower(239      {"Foo", "Bar", "Baz", "Qux"}, Copyable{NumCopies});240  EXPECT_EQ(NumCopies, 1u);241}242 243TEST(StringSwitchTest, StringSwitchMultipleMatches) {244  auto Translate = [](StringRef S) {245    return llvm::StringSwitch<int>(S)246        .CaseLower("A", 0)247        .Case("b", 1)248        .Case("a", 2)249        .CasesLower({"a", "b"}, 3)250        .DefaultUnreachable();251  };252 253  // Check that the value of the first match is returned.254  EXPECT_EQ(0, Translate("A"));255  EXPECT_EQ(0, Translate("a"));256  EXPECT_EQ(3, Translate("B"));257  EXPECT_EQ(1, Translate("b"));258}259 260TEST(StringSwitchTest, DefaultUnreachable) {261  auto Translate = [](StringRef S) {262    return llvm::StringSwitch<int>(S)263        .Case("A", 0)264        .Case("B", 1)265        .DefaultUnreachable("Unhandled case");266  };267 268  EXPECT_EQ(0, Translate("A"));269  EXPECT_EQ(1, Translate("B"));270 271#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)272  EXPECT_DEATH((void)Translate("C"), "Unhandled case");273#endif274}275