]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
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_ |