From 1d47523a8e4bdfbd3bd8e785550a47036cda4f4b Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Fri, 16 Dec 2011 08:58:59 +0000 Subject: 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! llvm-svn: 146729 --- llvm/unittests/ADT/VariadicFunctionTest.cpp | 110 ++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 llvm/unittests/ADT/VariadicFunctionTest.cpp (limited to 'llvm/unittests/ADT/VariadicFunctionTest.cpp') diff --git a/llvm/unittests/ADT/VariadicFunctionTest.cpp b/llvm/unittests/ADT/VariadicFunctionTest.cpp new file mode 100644 index 0000000..8e6f5b48 --- /dev/null +++ b/llvm/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 Args) { + std::string S; + for (unsigned i = 0, e = Args.size(); i < e; ++i) + S += *Args[i]; + return S; +} +const VariadicFunction 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 Args) { + long Result = 0; + for (unsigned i = 0, e = Args.size(); i < e; ++i) + Result += *Args[i]; + return Result; +} +const VariadicFunction 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 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 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 Args) { + *NumInRange = 0; + for (unsigned i = 0, e = Args.size(); i < e; ++i) + if (Low <= *Args[i] && *Args[i] <= High) + ++(*NumInRange); +} +const VariadicFunction3 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 -- cgit v1.1