teak-llvm/llvm/unittests/ADT/VariadicFunctionTest.cpp
Chandler Carruth 1d47523a8e 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
2011-12-16 08:58:59 +00:00

111 lines
3.4 KiB
C++

//===----------- 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