forked from recolic/2017aut-quest2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_utils.hpp
213 lines (187 loc) · 5.85 KB
/
test_utils.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
//////////////////////////////////////////////////BEGIN RLIB
#ifndef R_PRINT_HPP
#define R_PRINT_HPP
#include <iostream>
namespace rlib {
template<typename PrintFinalT>
void print(PrintFinalT reqArg)
{
::std::cout << reqArg;
return;
}
template<typename Required, typename... Optional>
void print(Required reqArgs, Optional... optiArgs)
{
::std::cout << reqArgs << ' ';
print(optiArgs ...);
return;
}
template<typename... Optional>
void println(Optional... optiArgs)
{
print(optiArgs ...);
::std::cout << ::std::endl;
return;
}
template<typename Iterable, typename Printable>
void print_iter(Iterable arg, Printable spliter)
{
for(const auto & i : arg)
::std::cout << i << spliter;
return;
}
template<typename Iterable, typename Printable>
void println_iter(Iterable arg, Printable spliter)
{
print_iter(arg, spliter);
::std::cout << ::std::endl;
return;
}
template<typename Iterable>
void print_iter(Iterable arg)
{
for(const auto & i : arg)
::std::cout << i << ' ';
return;
}
template<typename Iterable>
void println_iter(Iterable arg)
{
print_iter(arg);
::std::cout << ::std::endl;
return;
}
}
#endif
#ifndef RLIB_ADV_CALLABLE
#define RLIB_ADV_CALLABLE
#include <type_traits>
namespace rlib {
template<typename T>
struct is_callable_helper {
private:
typedef char(&yes)[1];
typedef char(&no)[2];
struct Fallback { void operator()(); };
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
template<typename>
static yes test(...);
template<typename C>
static no test(Check<void (Fallback::*)(), &C::operator()>*);
public:
static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
};
template<typename T>
struct is_callable
: std::conditional<
std::is_class<T>::value,
is_callable_helper<T>,
std::is_function<T>>::type
{};
}
#endif
////////////////////////////////////////////////////
#include <cstdlib>
#define dynamic_assert(cond, message) do { \
if(!cond) { \
rlib::println("dynamic assertion failed:", message); \
std::exit(2); \
} \
} while(false)
// -- operation must be a templated callable object, usually templated lambda.
// NEW: operation must fuck two buf at same time.
#define ASSERT_EQUIVALENCE(bufA, bufB, operation, equal_checker) \
do { \
static_assert(std::is_same<rlib::is_callable<decltype(equal_checker<double>)>::type, \
std::true_type>::value, \
"equal_checker is not callable"); \
dynamic_assert(equal_checker(bufA, bufB), "given buf is not equal."); \
operation(bufA, bufB); \
dynamic_assert(equal_checker(bufA, bufB), "operation failed."); \
} while(false)
//iterable equal template
template<class bufa_t, class bufb_t>
bool iterable_equal(const bufa_t &bufa, const bufb_t &bufb)
{
if(bufa.size() != bufb.size()) return false;
bufa_t &fake_bufa = const_cast<bufa_t &>(bufa); //For fucking api.
for(auto ia = fake_bufa.begin(), ib = bufb.begin();
ia != fake_bufa.end() && ib != bufb.end();
++ia, ++ib)
{
if(*ia != *ib) return false;
}
return true;
}
//vector
#include "lab_vector.hpp"
#include <vector>
template<typename data_t>
inline bool vector_equal(const Lab::vector<data_t> &bufa, const std::vector<data_t> &bufb)
{
return iterable_equal(bufa, bufb);
}
#define VECTOR_ASSERT_EQUIVALENCE(bufA, bufB, operation) ASSERT_EQUIVALENCE(bufA, bufB, operation, vector_equal)
//list
#include "lab_list.hpp"
#include <list>
template<typename data_t>
inline bool list_equal(const Lab::list<data_t> &bufa, const std::list<data_t> &bufb)
{
return iterable_equal(bufa, bufb);
}
#define LIST_ASSERT_EQUIVALENCE(bufA, bufB, operation) ASSERT_EQUIVALENCE(bufA, bufB, operation, list_equal)
//set
#include "lab_set.hpp"
#include <set>
template<typename data_t>
inline bool set_equal(const Lab::set<data_t> &bufa, const std::set<data_t> &bufb)
{
return iterable_equal(bufa, bufb);
}
#define SET_ASSERT_EQUIVALENCE(bufA, bufB, operation) ASSERT_EQUIVALENCE(bufA, bufB, operation, set_equal)
//priority_queue
#include "lab_priority_queue.hpp"
#include <queue>
template<typename data_t>
bool priority_queue_equal(const Lab::priority_queue<data_t> &bufa, const std::priority_queue<data_t> &bufb)
{
return true;
}
#define PRIORITY_QUEUE_ASSERT_EQUIVALENCE(bufA, bufB, operation) ASSERT_EQUIVALENCE(bufA, bufB, operation, priority_queue_equal)
template<typename data_t>
bool priority_queue_destroy_and_check(Lab::priority_queue<data_t> &bufa, std::priority_queue<data_t> &bufb)
{
if(bufa.size() != bufb.size()) return false;
while(bufb.size())
{
if(bufa.top() != bufb.top()) return false;
bufa.pop();
bufb.pop();
}
return true;
}
//unordered_map
#include "lab_unordered_map.hpp"
#include <unordered_map>
template<typename key_t, typename data_t>
bool unordered_map_equal(const Lab::unordered_map<key_t, data_t> &bufa, const std::unordered_map<key_t, data_t> &bufb)
{
if(bufa.size() != bufb.size()) return false;
Lab::unordered_map<key_t, data_t> &fake_bufa = const_cast<Lab::unordered_map<key_t, data_t> &>(bufa);
for(auto ia = fake_bufa.begin(), ib = bufb.begin();
ia != fake_bufa.end() && ib != bufb.end();
++ia, ++ib)
{
if(*ia != *ib) return false;
if(fake_bufa.find((*ib).first) != ia) return false;
}
return true;
}
template<typename key_data_t>
bool _unordered_map_equal(const Lab::unordered_map<key_data_t, key_data_t> &bufa, const std::unordered_map<key_data_t, key_data_t> &bufb)
{
return unordered_map_equal(bufa, bufb);
}
#define UNORDERED_MAP_ASSERT_EQUIVALENCE(bufA, bufB, operation) ASSERT_EQUIVALENCE(bufA, bufB, operation, _unordered_map_equal)