diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-12-16 08:58:59 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-12-16 08:58:59 +0000 |
commit | d916ce3c8e1c88352703db12b47862b1794c7dad (patch) | |
tree | 6e47e776607739e93b30c452d06cc2afda2d22ac /unittests | |
parent | 9646acfccfae3e5dd4fc18bbb14b0a5c9cc9563e (diff) |
Add a generic collection of class templates to ADT for building
variadic-like functions in C++98. See the comments in the header file
for a more detailed description of how these work. We plan to use these
extensively in the AST matching library. This code and idea were
originally authored by Zhanyong Wan. I've condensed it using macros
to reduce repeatition and adjusted it to fit better with LLVM's ADT.
Thanks to both David Blaikie and Doug Gregor for the review!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146729 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ADT/VariadicFunctionTest.cpp | 110 | ||||
-rw-r--r-- | unittests/CMakeLists.txt | 1 |
2 files changed, 111 insertions, 0 deletions
diff --git a/unittests/ADT/VariadicFunctionTest.cpp b/unittests/ADT/VariadicFunctionTest.cpp new file mode 100644 index 0000000000..8e6f5b48cb --- /dev/null +++ b/unittests/ADT/VariadicFunctionTest.cpp @@ -0,0 +1,110 @@ +//===----------- VariadicFunctionTest.cpp - VariadicFunction unit tests ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/VariadicFunction.h" + +using namespace llvm; +namespace { + +// Defines a variadic function StringCat() to join strings. +// StringCat()'s arguments and return value have class types. +std::string StringCatImpl(ArrayRef<const std::string*> Args) { + std::string S; + for (unsigned i = 0, e = Args.size(); i < e; ++i) + S += *Args[i]; + return S; +} +const VariadicFunction<std::string, std::string, StringCatImpl> StringCat; + +TEST(VariadicFunctionTest, WorksForClassTypes) { + EXPECT_EQ("", StringCat()); + EXPECT_EQ("a", StringCat("a")); + EXPECT_EQ("abc", StringCat("a", "bc")); + EXPECT_EQ("0123456789abcdefghijklmnopqrstuv", + StringCat("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", + "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", + "u", "v")); +} + +// Defines a variadic function Sum(), whose arguments and return value +// have primitive types. +// The return type of SumImp() is deliberately different from its +// argument type, as we want to test that this works. +long SumImpl(ArrayRef<const int*> Args) { + long Result = 0; + for (unsigned i = 0, e = Args.size(); i < e; ++i) + Result += *Args[i]; + return Result; +} +const VariadicFunction<long, int, SumImpl> Sum; + +TEST(VariadicFunctionTest, WorksForPrimitiveTypes) { + EXPECT_EQ(0, Sum()); + EXPECT_EQ(1, Sum(1)); + EXPECT_EQ(12, Sum(10, 2)); + EXPECT_EQ(1234567, Sum(1000000, 200000, 30000, 4000, 500, 60, 7)); +} + +// Appends an array of strings to dest and returns the number of +// characters appended. +int StringAppendImpl(std::string* Dest, ArrayRef<const std::string*> Args) { + int Chars = 0; + for (unsigned i = 0, e = Args.size(); i < e; ++i) { + Chars += Args[i]->size(); + *Dest += *Args[i]; + } + return Chars; +} +const VariadicFunction1<int, std::string*, std::string, + StringAppendImpl> StringAppend; + +TEST(VariadicFunction1Test, Works) { + std::string S0("hi"); + EXPECT_EQ(0, StringAppend(&S0)); + EXPECT_EQ("hi", S0); + + std::string S1("bin"); + EXPECT_EQ(2, StringAppend(&S1, "go")); + EXPECT_EQ("bingo", S1); + + std::string S4("Fab4"); + EXPECT_EQ(4 + 4 + 6 + 5, + StringAppend(&S4, "John", "Paul", "George", "Ringo")); + EXPECT_EQ("Fab4JohnPaulGeorgeRingo", S4); +} + +// Counts how many optional arguments fall in the given range. +// Returns the result in *num_in_range. We make the return type void +// as we want to test that VariadicFunction* can handle it. +void CountInRangeImpl(int* NumInRange, int Low, int High, + ArrayRef<const int*> Args) { + *NumInRange = 0; + for (unsigned i = 0, e = Args.size(); i < e; ++i) + if (Low <= *Args[i] && *Args[i] <= High) + ++(*NumInRange); +} +const VariadicFunction3<void, int*, int, int, int, + CountInRangeImpl> CountInRange; + +TEST(VariadicFunction3Test, Works) { + int N = -1; + CountInRange(&N, -100, 100); + EXPECT_EQ(0, N); + + CountInRange(&N, -100, 100, 42); + EXPECT_EQ(1, N); + + CountInRange(&N, -100, 100, 1, 999, -200, 42); + EXPECT_EQ(2, N); +} + +} // namespace diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 15423dce46..0fabf71066 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -73,6 +73,7 @@ add_llvm_unittest(ADT ADT/StringRefTest.cpp ADT/TripleTest.cpp ADT/TwineTest.cpp + ADT/VariadicFunctionTest.cpp ) add_llvm_unittest(Analysis |