gtest: Update to 1.8.0.
[mesa.git] / src / gtest / include / gtest / internal / gtest-tuple.h.pump
1 $$ -*- mode: c++; -*-
2 $var n = 10 $$ Maximum number of tuple fields we want to support.
3 $$ This meta comment fixes auto-indentation in Emacs. }}
4 // Copyright 2009 Google Inc.
5 // All Rights Reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Author: wan@google.com (Zhanyong Wan)
34
35 // Implements a subset of TR1 tuple needed by Google Test and Google Mock.
36
37 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
38 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
39
40 #include <utility> // For ::std::pair.
41
42 // The compiler used in Symbian has a bug that prevents us from declaring the
43 // tuple template as a friend (it complains that tuple is redefined). This
44 // hack bypasses the bug by declaring the members that should otherwise be
45 // private as public.
46 // Sun Studio versions < 12 also have the above bug.
47 #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
48 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
49 #else
50 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
51 template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
52 private:
53 #endif
54
55 // Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
56 // with our own definitions. Therefore using our own tuple does not work on
57 // those compilers.
58 #if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
59 # error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
60 GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
61 #endif
62
63
64 $range i 0..n-1
65 $range j 0..n
66 $range k 1..n
67 // GTEST_n_TUPLE_(T) is the type of an n-tuple.
68 #define GTEST_0_TUPLE_(T) tuple<>
69
70 $for k [[
71 $range m 0..k-1
72 $range m2 k..n-1
73 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
74
75 ]]
76
77 // GTEST_n_TYPENAMES_(T) declares a list of n typenames.
78
79 $for j [[
80 $range m 0..j-1
81 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
82
83
84 ]]
85
86 // In theory, defining stuff in the ::std namespace is undefined
87 // behavior. We can do this as we are playing the role of a standard
88 // library vendor.
89 namespace std {
90 namespace tr1 {
91
92 template <$for i, [[typename T$i = void]]>
93 class tuple;
94
95 // Anything in namespace gtest_internal is Google Test's INTERNAL
96 // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
97 namespace gtest_internal {
98
99 // ByRef<T>::type is T if T is a reference; otherwise it's const T&.
100 template <typename T>
101 struct ByRef { typedef const T& type; }; // NOLINT
102 template <typename T>
103 struct ByRef<T&> { typedef T& type; }; // NOLINT
104
105 // A handy wrapper for ByRef.
106 #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
107
108 // AddRef<T>::type is T if T is a reference; otherwise it's T&. This
109 // is the same as tr1::add_reference<T>::type.
110 template <typename T>
111 struct AddRef { typedef T& type; }; // NOLINT
112 template <typename T>
113 struct AddRef<T&> { typedef T& type; }; // NOLINT
114
115 // A handy wrapper for AddRef.
116 #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
117
118 // A helper for implementing get<k>().
119 template <int k> class Get;
120
121 // A helper for implementing tuple_element<k, T>. kIndexValid is true
122 // iff k < the number of fields in tuple type T.
123 template <bool kIndexValid, int kIndex, class Tuple>
124 struct TupleElement;
125
126
127 $for i [[
128 template <GTEST_$(n)_TYPENAMES_(T)>
129 struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
130 typedef T$i type;
131 };
132
133
134 ]]
135 } // namespace gtest_internal
136
137 template <>
138 class tuple<> {
139 public:
140 tuple() {}
141 tuple(const tuple& /* t */) {}
142 tuple& operator=(const tuple& /* t */) { return *this; }
143 };
144
145
146 $for k [[
147 $range m 0..k-1
148 template <GTEST_$(k)_TYPENAMES_(T)>
149 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
150 public:
151 template <int k> friend class gtest_internal::Get;
152
153 tuple() : $for m, [[f$(m)_()]] {}
154
155 explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
156 $for m, [[f$(m)_(f$m)]] {}
157
158 tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
159
160 template <GTEST_$(k)_TYPENAMES_(U)>
161 tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
162
163 $if k == 2 [[
164 template <typename U0, typename U1>
165 tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
166
167 ]]
168
169 tuple& operator=(const tuple& t) { return CopyFrom(t); }
170
171 template <GTEST_$(k)_TYPENAMES_(U)>
172 tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
173 return CopyFrom(t);
174 }
175
176 $if k == 2 [[
177 template <typename U0, typename U1>
178 tuple& operator=(const ::std::pair<U0, U1>& p) {
179 f0_ = p.first;
180 f1_ = p.second;
181 return *this;
182 }
183
184 ]]
185
186 GTEST_DECLARE_TUPLE_AS_FRIEND_
187
188 template <GTEST_$(k)_TYPENAMES_(U)>
189 tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
190
191 $for m [[
192 f$(m)_ = t.f$(m)_;
193
194 ]]
195 return *this;
196 }
197
198
199 $for m [[
200 T$m f$(m)_;
201
202 ]]
203 };
204
205
206 ]]
207 // 6.1.3.2 Tuple creation functions.
208
209 // Known limitations: we don't support passing an
210 // std::tr1::reference_wrapper<T> to make_tuple(). And we don't
211 // implement tie().
212
213 inline tuple<> make_tuple() { return tuple<>(); }
214
215 $for k [[
216 $range m 0..k-1
217
218 template <GTEST_$(k)_TYPENAMES_(T)>
219 inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
220 return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
221 }
222
223 ]]
224
225 // 6.1.3.3 Tuple helper classes.
226
227 template <typename Tuple> struct tuple_size;
228
229
230 $for j [[
231 template <GTEST_$(j)_TYPENAMES_(T)>
232 struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
233 static const int value = $j;
234 };
235
236
237 ]]
238 template <int k, class Tuple>
239 struct tuple_element {
240 typedef typename gtest_internal::TupleElement<
241 k < (tuple_size<Tuple>::value), k, Tuple>::type type;
242 };
243
244 #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
245
246 // 6.1.3.4 Element access.
247
248 namespace gtest_internal {
249
250
251 $for i [[
252 template <>
253 class Get<$i> {
254 public:
255 template <class Tuple>
256 static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
257 Field(Tuple& t) { return t.f$(i)_; } // NOLINT
258
259 template <class Tuple>
260 static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
261 ConstField(const Tuple& t) { return t.f$(i)_; }
262 };
263
264
265 ]]
266 } // namespace gtest_internal
267
268 template <int k, GTEST_$(n)_TYPENAMES_(T)>
269 GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
270 get(GTEST_$(n)_TUPLE_(T)& t) {
271 return gtest_internal::Get<k>::Field(t);
272 }
273
274 template <int k, GTEST_$(n)_TYPENAMES_(T)>
275 GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
276 get(const GTEST_$(n)_TUPLE_(T)& t) {
277 return gtest_internal::Get<k>::ConstField(t);
278 }
279
280 // 6.1.3.5 Relational operators
281
282 // We only implement == and !=, as we don't have a need for the rest yet.
283
284 namespace gtest_internal {
285
286 // SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
287 // first k fields of t1 equals the first k fields of t2.
288 // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
289 // k1 != k2.
290 template <int kSize1, int kSize2>
291 struct SameSizeTuplePrefixComparator;
292
293 template <>
294 struct SameSizeTuplePrefixComparator<0, 0> {
295 template <class Tuple1, class Tuple2>
296 static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
297 return true;
298 }
299 };
300
301 template <int k>
302 struct SameSizeTuplePrefixComparator<k, k> {
303 template <class Tuple1, class Tuple2>
304 static bool Eq(const Tuple1& t1, const Tuple2& t2) {
305 return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
306 ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
307 }
308 };
309
310 } // namespace gtest_internal
311
312 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
313 inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
314 const GTEST_$(n)_TUPLE_(U)& u) {
315 return gtest_internal::SameSizeTuplePrefixComparator<
316 tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
317 tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
318 }
319
320 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
321 inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
322 const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
323
324 // 6.1.4 Pairs.
325 // Unimplemented.
326
327 } // namespace tr1
328 } // namespace std
329
330
331 $for j [[
332 #undef GTEST_$(j)_TUPLE_
333
334 ]]
335
336
337 $for j [[
338 #undef GTEST_$(j)_TYPENAMES_
339
340 ]]
341
342 #undef GTEST_DECLARE_TUPLE_AS_FRIEND_
343 #undef GTEST_BY_REF_
344 #undef GTEST_ADD_REF_
345 #undef GTEST_TUPLE_ELEMENT_
346
347 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_