1d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth//===----------- VariadicFunctionTest.cpp - VariadicFunction unit tests ---===//
2d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth//
3d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth//                     The LLVM Compiler Infrastructure
4d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth//
5d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// This file is distributed under the University of Illinois Open Source
6d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// License. See LICENSE.TXT for details.
7d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth//
8d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth//===----------------------------------------------------------------------===//
9d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
10d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth#include "gtest/gtest.h"
11d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth#include "llvm/ADT/ArrayRef.h"
12d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth#include "llvm/ADT/VariadicFunction.h"
13d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
14d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruthusing namespace llvm;
15d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruthnamespace {
16d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
17d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// Defines a variadic function StringCat() to join strings.
18d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// StringCat()'s arguments and return value have class types.
19db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruthstd::string StringCatImpl(ArrayRef<const std::string *> Args) {
20d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  std::string S;
21d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  for (unsigned i = 0, e = Args.size(); i < e; ++i)
22d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth    S += *Args[i];
23d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  return S;
24d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
251243cdda6330139c55e8ecc033fcb559581e6870Chandler Carruthconst VariadicFunction<std::string, std::string, StringCatImpl> StringCat = {};
26d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
27d916ce3c8e1c88352703db12b47862b1794c7dadChandler CarruthTEST(VariadicFunctionTest, WorksForClassTypes) {
28d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("", StringCat());
29d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("a", StringCat("a"));
30d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("abc", StringCat("a", "bc"));
31d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("0123456789abcdefghijklmnopqrstuv",
32d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth            StringCat("0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
33d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth                      "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
34d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth                      "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
35d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth                      "u", "v"));
36d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
37d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
38d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// Defines a variadic function Sum(), whose arguments and return value
39d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// have primitive types.
40d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// The return type of SumImp() is deliberately different from its
41d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// argument type, as we want to test that this works.
42db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruthlong SumImpl(ArrayRef<const int *> Args) {
43d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  long Result = 0;
44d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  for (unsigned i = 0, e = Args.size(); i < e; ++i)
45d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth    Result += *Args[i];
46d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  return Result;
47d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
481243cdda6330139c55e8ecc033fcb559581e6870Chandler Carruthconst VariadicFunction<long, int, SumImpl> Sum = {};
49d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
50d916ce3c8e1c88352703db12b47862b1794c7dadChandler CarruthTEST(VariadicFunctionTest, WorksForPrimitiveTypes) {
51d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(0, Sum());
52d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(1, Sum(1));
53d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(12, Sum(10, 2));
54d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(1234567, Sum(1000000, 200000, 30000, 4000, 500, 60, 7));
55d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
56d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
57d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// Appends an array of strings to dest and returns the number of
58d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// characters appended.
59db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruthint StringAppendImpl(std::string *Dest, ArrayRef<const std::string *> Args) {
60d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  int Chars = 0;
61d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  for (unsigned i = 0, e = Args.size(); i < e; ++i) {
62d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth    Chars += Args[i]->size();
63d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth    *Dest += *Args[i];
64d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  }
65d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  return Chars;
66d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
67db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruthconst VariadicFunction1<int, std::string *, std::string,
681243cdda6330139c55e8ecc033fcb559581e6870Chandler Carruth                        StringAppendImpl> StringAppend = {};
69d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
70d916ce3c8e1c88352703db12b47862b1794c7dadChandler CarruthTEST(VariadicFunction1Test, Works) {
71d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  std::string S0("hi");
72d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(0, StringAppend(&S0));
73d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("hi", S0);
74d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
75d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  std::string S1("bin");
76d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(2, StringAppend(&S1, "go"));
77d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("bingo", S1);
78d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
79d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  std::string S4("Fab4");
80d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(4 + 4 + 6 + 5,
81d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth            StringAppend(&S4, "John", "Paul", "George", "Ringo"));
82d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ("Fab4JohnPaulGeorgeRingo", S4);
83d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
84d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
85d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// Counts how many optional arguments fall in the given range.
86d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// Returns the result in *num_in_range.  We make the return type void
87d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth// as we want to test that VariadicFunction* can handle it.
88db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruthvoid CountInRangeImpl(int *NumInRange, int Low, int High,
89db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruth                      ArrayRef<const int *> Args) {
90d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  *NumInRange = 0;
91d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  for (unsigned i = 0, e = Args.size(); i < e; ++i)
92d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth    if (Low <= *Args[i] && *Args[i] <= High)
93d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth      ++(*NumInRange);
94d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
95db21f4c187816b03d7b30d0d238f71cbd8a0a9a7Chandler Carruthconst VariadicFunction3<void, int *, int, int, int,
961243cdda6330139c55e8ecc033fcb559581e6870Chandler Carruth                        CountInRangeImpl> CountInRange = {};
97d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
98d916ce3c8e1c88352703db12b47862b1794c7dadChandler CarruthTEST(VariadicFunction3Test, Works) {
99d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  int N = -1;
100d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  CountInRange(&N, -100, 100);
101d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(0, N);
102d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
103d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  CountInRange(&N, -100, 100, 42);
104d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(1, N);
105d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
106d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  CountInRange(&N, -100, 100, 1, 999, -200, 42);
107d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth  EXPECT_EQ(2, N);
108d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}
109d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth
110d916ce3c8e1c88352703db12b47862b1794c7dadChandler Carruth}  // namespace
111