c7d9e039b1f31981ff683e2e4803129a012caedb
[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
56 $range i 0..n-1
57 $range j 0..n
58 $range k 1..n
59 // GTEST_n_TUPLE_(T) is the type of an n-tuple.
60 #define GTEST_0_TUPLE_(T) tuple<>
61
62 $for k [[
63 $range m 0..k-1
64 $range m2 k..n-1
65 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
66
67 ]]
68
69 // GTEST_n_TYPENAMES_(T) declares a list of n typenames.
70
71 $for j [[
72 $range m 0..j-1
73 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
74
75
76 ]]
77
78 // In theory, defining stuff in the ::std namespace is undefined
79 // behavior. We can do this as we are playing the role of a standard
80 // library vendor.
81 namespace std {
82 namespace tr1 {
83
84 template <$for i, [[typename T$i = void]]>
85 class tuple;
86
87 // Anything in namespace gtest_internal is Google Test's INTERNAL
88 // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
89 namespace gtest_internal {
90
91 // ByRef<T>::type is T if T is a reference; otherwise it's const T&.
92 template <typename T>
93 struct ByRef { typedef const T& type; }; // NOLINT
94 template <typename T>
95 struct ByRef<T&> { typedef T& type; }; // NOLINT
96
97 // A handy wrapper for ByRef.
98 #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
99
100 // AddRef<T>::type is T if T is a reference; otherwise it's T&. This
101 // is the same as tr1::add_reference<T>::type.
102 template <typename T>
103 struct AddRef { typedef T& type; }; // NOLINT
104 template <typename T>
105 struct AddRef<T&> { typedef T& type; }; // NOLINT
106
107 // A handy wrapper for AddRef.
108 #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
109
110 // A helper for implementing get<k>().
111 template <int k> class Get;
112
113 // A helper for implementing tuple_element<k, T>. kIndexValid is true
114 // iff k < the number of fields in tuple type T.
115 template <bool kIndexValid, int kIndex, class Tuple>
116 struct TupleElement;
117
118
119 $for i [[
120 template <GTEST_$(n)_TYPENAMES_(T)>
121 struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
122 typedef T$i type;
123 };
124
125
126 ]]
127 } // namespace gtest_internal
128
129 template <>
130 class tuple<> {
131 public:
132 tuple() {}
133 tuple(const tuple& /* t */) {}
134 tuple& operator=(const tuple& /* t */) { return *this; }
135 };
136
137
138 $for k [[
139 $range m 0..k-1
140 template <GTEST_$(k)_TYPENAMES_(T)>
141 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
142 public:
143 template <int k> friend class gtest_internal::Get;
144
145 tuple() : $for m, [[f$(m)_()]] {}
146
147 explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
148 $for m, [[f$(m)_(f$m)]] {}
149
150 tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
151
152 template <GTEST_$(k)_TYPENAMES_(U)>
153 tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
154
155 $if k == 2 [[
156 template <typename U0, typename U1>
157 tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
158
159 ]]
160
161 tuple& operator=(const tuple& t) { return CopyFrom(t); }
162
163 template <GTEST_$(k)_TYPENAMES_(U)>
164 tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
165 return CopyFrom(t);
166 }
167
168 $if k == 2 [[
169 template <typename U0, typename U1>
170 tuple& operator=(const ::std::pair<U0, U1>& p) {
171 f0_ = p.first;
172 f1_ = p.second;
173 return *this;
174 }
175
176 ]]
177
178 GTEST_DECLARE_TUPLE_AS_FRIEND_
179
180 template <GTEST_$(k)_TYPENAMES_(U)>
181 tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
182
183 $for m [[
184 f$(m)_ = t.f$(m)_;
185
186 ]]
187 return *this;
188 }
189
190
191 $for m [[
192 T$m f$(m)_;
193
194 ]]
195 };
196
197
198 ]]
199 // 6.1.3.2 Tuple creation functions.
200
201 // Known limitations: we don't support passing an
202 // std::tr1::reference_wrapper<T> to make_tuple(). And we don't
203 // implement tie().
204
205 inline tuple<> make_tuple() { return tuple<>(); }
206
207 $for k [[
208 $range m 0..k-1
209
210 template <GTEST_$(k)_TYPENAMES_(T)>
211 inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
212 return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
213 }
214
215 ]]
216
217 // 6.1.3.3 Tuple helper classes.
218
219 template <typename Tuple> struct tuple_size;
220
221
222 $for j [[
223 template <GTEST_$(j)_TYPENAMES_(T)>
224 struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
225 static const int value = $j;
226 };
227
228
229 ]]
230 template <int k, class Tuple>
231 struct tuple_element {
232 typedef typename gtest_internal::TupleElement<
233 k < (tuple_size<Tuple>::value), k, Tuple>::type type;
234 };
235
236 #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
237
238 // 6.1.3.4 Element access.
239
240 namespace gtest_internal {
241
242
243 $for i [[
244 template <>
245 class Get<$i> {
246 public:
247 template <class Tuple>
248 static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
249 Field(Tuple& t) { return t.f$(i)_; } // NOLINT
250
251 template <class Tuple>
252 static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
253 ConstField(const Tuple& t) { return t.f$(i)_; }
254 };
255
256
257 ]]
258 } // namespace gtest_internal
259
260 template <int k, GTEST_$(n)_TYPENAMES_(T)>
261 GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
262 get(GTEST_$(n)_TUPLE_(T)& t) {
263 return gtest_internal::Get<k>::Field(t);
264 }
265
266 template <int k, GTEST_$(n)_TYPENAMES_(T)>
267 GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
268 get(const GTEST_$(n)_TUPLE_(T)& t) {
269 return gtest_internal::Get<k>::ConstField(t);
270 }
271
272 // 6.1.3.5 Relational operators
273
274 // We only implement == and !=, as we don't have a need for the rest yet.
275
276 namespace gtest_internal {
277
278 // SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
279 // first k fields of t1 equals the first k fields of t2.
280 // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
281 // k1 != k2.
282 template <int kSize1, int kSize2>
283 struct SameSizeTuplePrefixComparator;
284
285 template <>
286 struct SameSizeTuplePrefixComparator<0, 0> {
287 template <class Tuple1, class Tuple2>
288 static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
289 return true;
290 }
291 };
292
293 template <int k>
294 struct SameSizeTuplePrefixComparator<k, k> {
295 template <class Tuple1, class Tuple2>
296 static bool Eq(const Tuple1& t1, const Tuple2& t2) {
297 return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
298 ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
299 }
300 };
301
302 } // namespace gtest_internal
303
304 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
305 inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
306 const GTEST_$(n)_TUPLE_(U)& u) {
307 return gtest_internal::SameSizeTuplePrefixComparator<
308 tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
309 tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
310 }
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) { return !(t == u); }
315
316 // 6.1.4 Pairs.
317 // Unimplemented.
318
319 } // namespace tr1
320 } // namespace std
321
322
323 $for j [[
324 #undef GTEST_$(j)_TUPLE_
325
326 ]]
327
328
329 $for j [[
330 #undef GTEST_$(j)_TYPENAMES_
331
332 ]]
333
334 #undef GTEST_DECLARE_TUPLE_AS_FRIEND_
335 #undef GTEST_BY_REF_
336 #undef GTEST_ADD_REF_
337 #undef GTEST_TUPLE_ELEMENT_
338
339 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_