clingo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
tests.hh
Go to the documentation of this file.
1 // {{{ GPL License
2 
3 // This file is part of gringo - a grounder for logic programs.
4 // Copyright (C) 2013 Roland Kaminski
5 
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 // }}}
20 
21 #ifndef _GRINGO_TEST_TESTS_HH
22 #define _GRINGO_TEST_TESTS_HH
23 
24 #include <cppunit/TestFixture.h>
25 #include <cppunit/TestAssert.h>
26 #include <cppunit/extensions/HelperMacros.h>
27 #include "gringo/utility.hh"
28 #include "gringo/logger.hh"
29 #include <algorithm>
30 #include <unordered_map>
31 
32 namespace Gringo {
33 
34 // {{{ declaration of helpers to print containers
35 
36 namespace IO {
37 
38 template <class T>
39 std::ostream &operator<<(std::ostream &out, std::unique_ptr<T> const &x);
40 template <class... T>
41 std::ostream &operator<<(std::ostream &out, std::vector<T...> const &x);
42 template <class... T>
43 std::ostream &operator<<(std::ostream &out, std::set<T...> const &x);
44 template <class T, class U>
45 std::ostream &operator<<(std::ostream &out, std::pair<T, U> const &x);
46 template <class... T>
47 std::ostream &operator<<(std::ostream &out, std::tuple<T...> const &x);
48 template <class... T>
49 std::ostream &operator<<(std::ostream &out, std::map<T...> const &x);
50 template <class... T>
51 std::ostream &operator<<(std::ostream &out, std::unordered_map<T...> const &x);
52 template <class T>
53 std::string to_string(T const &x);
54 
55 } // namespace IO
56 
57 // }}}
58 
59 // {{{ definition of helpers to print containers
60 
61 namespace IO {
62 
63 template <class T>
64 std::ostream &operator<<(std::ostream &out, std::unique_ptr<T> const &x) {
65  out << *x;
66  return out;
67 }
68 
69 template <class T, class U>
70 std::ostream &operator<<(std::ostream &out, std::pair<T, U> const &x) {
71  out << "(" << x.first << "," << x.second << ")";
72  return out;
73 }
74 
75 template <class... T>
76 std::ostream &operator<<(std::ostream &out, std::vector<T...> const &vec) {
77  out << "[";
78  auto it(vec.begin()), end(vec.end());
79  if (it != end) {
80  out << *it;
81  for (++it; it != end; ++it) { out << "," << *it; }
82  }
83  out << "]";
84  return out;
85 }
86 
87 template <class... T>
88 std::ostream &operator<<(std::ostream &out, std::set<T...> const &x) {
89  out << "{";
90  auto it(x.begin()), end(x.end());
91  if (it != end) {
92  out << *it;
93  for (++it; it != end; ++it) { out << "," << *it; }
94  }
95  out << "}";
96  return out;
97 }
98 
99 
100 namespace detail {
101  template <int N>
102  struct print {
103  template <class... T>
104  void operator()(std::ostream &out, std::tuple<T...> const &x) const {
105  out << std::get<sizeof...(T) - N>(x) << ",";
106  print<N-1>()(out, x);
107  }
108  };
109  template <>
110  struct print<1> {
111  template <class... T>
112  void operator()(std::ostream &out, std::tuple<T...> const &x) const {
113  out << std::get<sizeof...(T) - 1>(x);
114  }
115  };
116  template <>
117  struct print<0> {
118  template <class... T>
119  void operator()(std::ostream &, std::tuple<T...> const &) const { }
120  };
121 }
122 
123 template <class... T>
124 std::ostream &operator<<(std::ostream &out, std::tuple<T...> const &x) {
125  out << "(";
126  detail::print<sizeof...(T)>()(out, x);
127  out << ")";
128  return out;
129 }
130 
131 template <class... T>
132 std::ostream &operator<<(std::ostream &out, std::unordered_map<T...> const &x) {
133  std::vector<std::pair<std::string, std::string>> vals;
134  for (auto const &y : x) { vals.emplace_back(to_string(y.first), to_string(y.second)); }
135  std::sort(vals.begin(), vals.end());
136  out << "{";
137  auto it = vals.begin(), end = vals.end();
138  if (it != end) {
139  out << it->first << ":" << it->second;
140  for (++it; it != end; ++it) { out << "," << it->first << ":" << it->second; }
141  }
142  out << "}";
143  return out;
144 }
145 
146 template <class... T>
147 std::ostream &operator<<(std::ostream &out, std::map<T...> const &x) {
148  out << "{";
149  auto it = x.begin(), end = x.end();
150  if (it != end) {
151  out << it->first << ":" << it->second;
152  for (++it; it != end; ++it) { out << "," << it->first << ":" << it->second; }
153  }
154  out << "}";
155  return out;
156 }
157 
158 template <class T>
159 std::string to_string(T const &x) {
160  std::stringstream ss;
161  ss << x;
162  return ss.str();
163 }
164 
165 } // namesapce IO
166 
167 // }}}
168 
169 inline std::string &replace_all(std::string &haystack, std::string const &needle, std::string const &replace) {
170  size_t index = 0;
171  while (true) {
172  index = haystack.find(needle, index);
173  if (index == std::string::npos) break;
174  haystack.replace(index, needle.length(), replace);
175  index += replace.length();
176  }
177  return haystack;
178 }
179 
180 inline std::string replace_all(std::string &&haystack, std::string const &needle, std::string const &replace) {
181  replace_all(haystack, needle, replace);
182  return std::move(haystack);
183 }
184 
185 }
186 
187 namespace Gringo { namespace Test {
188 
189 // {{{ definition of helpers to initialize vectors
190 
191 namespace Detail {
192 
193 template <int, class, int, class...>
194 struct walker;
195 
196 template <class, int, int, int, class...>
197 struct emplacer;
198 
199 template <class V, int S1, int S2, int S3, class A, class... T>
200 struct emplacer<V, S1, S2, S3, A, T...> {
201  void operator()(V& v, A&& a, T&&... args) const {
202  // reverse
203  emplacer<V, S1-1, S2, S3, T..., A>()(v, std::forward<T>(args)..., std::forward<A>(a));
204  }
205 };
206 
207 template <class V, int S2, int S3, class A, class... T>
208 struct emplacer<V, 0, S2, S3, A, T...> {
209  void operator()(V& v, A&&, T&&... args) const {
210  // drop
211  emplacer<V, 0, S2-1, S3, T...>()(v, std::forward<T>(args)...);
212  }
213 };
214 
215 template <class V, int S3, class A, class... T>
216 struct emplacer<V, 0, 0, S3, A, T...> {
217  void operator()(V& v, A&& a, T&&... args) const {
218  // reverse
219  emplacer<V, 0, 0, S3-1, T..., A>()(v, std::forward<T>(args)..., std::forward<A>(a));
220  }
221 };
222 
223 template <class V, class A, class... T>
224 struct emplacer<V, 0, 0, 0, A, T...> {
225  void operator()(V &v, A&& a, T&&... args) const {
226  v.emplace_back(std::forward<A>(a), std::forward<T>(args)...);
227  }
228 };
229 
230 template <int N, class V, int I, class A, class... T>
231 struct walker<N, V, I, A, T...> {
232  void operator()(V& v, A&&, T&&... args) const {
233  walker<N, V, I-1, T...>()(v, std::forward<T>(args)...);
234  }
235 };
236 
237 template <int N, class V, class A, class... T>
238 struct walker<N, V, 0, A, T...> {
239  void operator()(V& v, A&& a, T&&... args) const {
240  emplacer<V, N, sizeof...(T)+1-N, N, A, T...>()(v, std::forward<A>(a), std::forward<T>(args)...);
241  walker<N, V, N-1, T...>()(v, std::forward<T>(args)...);
242  }
243 };
244 
245 // Note: optimization for N=1
246 template <class V, class A, class... T>
247 struct walker<1, V, 0, A, T...> {
248  void operator()(V& v, A&& a, T&&... args) const {
249  v.emplace_back(std::forward<A>(a));
250  walker<1, V, 0, T...>()(v, std::forward<T>(args)...);
251  }
252 };
253 
254 template <int N, class V, int I>
255 struct walker<N, V, I> {
256  static_assert(N > 0, "think - makes no sense!");
257  void operator()(V&) const { }
258 };
259 
260 } // namespace Detail
261 
262 template <class V, class... T>
263 V init(T&&... args) {
264  V v;
265  Detail::walker<1, V, 0, T...>()(v, std::forward<T>(args)...);
266  return std::move(v);
267 }
268 
269 template <int N, class V, class... T>
270 V init(T&&... args) {
271  static_assert(N > 0, "think - makes no sense!");
272  V v;
273  Detail::walker<N, V, 0, T...>()(v, std::forward<T>(args)...);
274  return std::move(v);
275 }
276 
277 // }}}
278 // {{{ defintion of TestMessagePrinter
279 
281  TestMessagePrinter(std::vector<std::string> &messages)
282  : messages_(messages) { }
283  virtual bool check(Errors) { error_ = true; return true; }
284  virtual bool check(Warnings) { return true; }
285  virtual bool hasError() const { return error_; }
286  virtual void enable(Warnings) { }
287  virtual void disable(Warnings) { }
288  virtual void print(std::string const &msg) { messages_.emplace_back(msg); }
289  virtual ~TestMessagePrinter() { }
290 private:
291  std::vector<std::string> &messages_;
292  bool error_ = false;
293 };
294 
295 struct Messages {
297  : oldPrinter(std::move(message_printer())) {
298  message_printer() = make_unique<Gringo::Test::TestMessagePrinter>(messages);
299  }
300  void clear() { messages.clear(); }
302  message_printer() = std::move(oldPrinter);
303  }
304  std::vector<std::string> messages;
305 private:
306  std::unique_ptr<MessagePrinter> oldPrinter;
307 };
308 
309 inline std::ostream &operator<<(std::ostream &out, Messages const &x) {
310  out << IO::to_string(x.messages);
311  return out;
312 }
313 
314 // }}}
315 
316 } } // namespace Test Gringo
317 
318 #endif // _GRINGO_TEST_TESTS_HH
void operator()(std::ostream &out, std::tuple< T...> const &x) const
Definition: tests.hh:104
Definition: logger.hh:51
std::ostream & operator<<(std::ostream &out, std::unique_ptr< T > const &x)
Definition: tests.hh:64
std::ostream & operator<<(std::ostream &out, TestFlyweight::Dummy const &dummy)
Definition: flyweight.cc:216
std::string to_string(T const &x)
Definition: tests.hh:159
V init(T &&...args)
Definition: tests.hh:263
virtual void print(std::string const &msg)
Definition: tests.hh:288
Definition: tests.hh:197
tuple a
Definition: pyclingo.py:6
void operator()(V &v, A &&a, T &&...args) const
Definition: tests.hh:225
virtual bool hasError() const
Definition: tests.hh:285
Warnings
Definition: logger.hh:36
Definition: tests.hh:295
virtual ~TestMessagePrinter()
Definition: tests.hh:289
virtual bool check(Warnings)
Definition: tests.hh:284
virtual void disable(Warnings)
Definition: tests.hh:287
void clear()
Definition: tests.hh:300
TestMessagePrinter(std::vector< std::string > &messages)
Definition: tests.hh:281
std::unique_ptr< MessagePrinter > & message_printer()
Definition: logger.hh:78
Messages()
Definition: tests.hh:296
void operator()(V &v, A &&a, T &&...args) const
Definition: tests.hh:201
~Messages()
Definition: tests.hh:301
Definition: tests.hh:102
void operator()(V &v, A &&a, T &&...args) const
Definition: tests.hh:248
#define static_assert(x, message)
Definition: platform.h:127
std::string & replace_all(std::string &haystack, std::string const &needle, std::string const &replace)
Definition: tests.hh:169
void operator()(std::ostream &, std::tuple< T...> const &) const
Definition: tests.hh:119
void operator()(V &) const
Definition: tests.hh:257
void operator()(std::ostream &out, std::tuple< T...> const &x) const
Definition: tests.hh:112
Definition: tests.hh:194
void operator()(V &v, A &&a, T &&...args) const
Definition: tests.hh:239
int x
Definition: utility.cc:65
uint32 index(Var v)
Returns the index of variable v.
Definition: literal.h:173
Definition: tests.hh:280
Errors
Definition: logger.hh:46
virtual bool check(Errors)
Definition: tests.hh:283
std::vector< std::string > messages
Definition: tests.hh:304
void operator()(V &v, A &&, T &&...args) const
Definition: tests.hh:209
void operator()(V &v, A &&, T &&...args) const
Definition: tests.hh:232
LparseOutputter & out
Definition: output.cc:685
virtual void enable(Warnings)
Definition: tests.hh:286
void operator()(V &v, A &&a, T &&...args) const
Definition: tests.hh:217
int end
Definition: literals.cc:62