Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 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 |
||
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 |
||
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 |
||
92 | template |
||
93 | struct ByRef { typedef const T& type; }; // NOLINT |
||
94 | template |
||
95 | struct ByRef |
||
96 | |||
97 | // A handy wrapper for ByRef. |
||
98 | #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef |
||
99 | |||
100 | // AddRef |
||
101 | // is the same as tr1::add_reference |
||
102 | template |
||
103 | struct AddRef { typedef T& type; }; // NOLINT |
||
104 | template |
||
105 | struct AddRef |
||
106 | |||
107 | // A handy wrapper for AddRef. |
||
108 | #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef |
||
109 | |||
110 | // A helper for implementing get |
||
111 | template |
||
112 | |||
113 | // A helper for implementing tuple_element |
||
114 | // iff k < the number of fields in tuple type T. |
||
115 | template |
||
116 | struct TupleElement; |
||
117 | |||
118 | |||
119 | $for i [[ |
||
120 | template |
||
121 | struct TupleElement |
||
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 |
||
141 | class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { |
||
142 | public: |
||
143 | template |
||
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 |
||
153 | tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} |
||
154 | |||
155 | $if k == 2 [[ |
||
156 | template |
||
157 | tuple(const ::std::pair |
||
158 | |||
159 | ]] |
||
160 | |||
161 | tuple& operator=(const tuple& t) { return CopyFrom(t); } |
||
162 | |||
163 | template |
||
164 | tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { |
||
165 | return CopyFrom(t); |
||
166 | } |
||
167 | |||
168 | $if k == 2 [[ |
||
169 | template |
||
170 | tuple& operator=(const ::std::pair |
||
171 | f0_ = p.first; |
||
172 | f1_ = p.second; |
||
173 | return *this; |
||
174 | } |
||
175 | |||
176 | ]] |
||
177 | |||
178 | GTEST_DECLARE_TUPLE_AS_FRIEND_ |
||
179 | |||
180 | template |
||
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 |
||
203 | // implement tie(). |
||
204 | |||
205 | inline tuple<> make_tuple() { return tuple<>(); } |
||
206 | |||
207 | $for k [[ |
||
208 | $range m 0..k-1 |
||
209 | |||
210 | template |
||
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 |
||
220 | |||
221 | |||
222 | $for j [[ |
||
223 | template |
||
224 | struct tuple_size |
||
225 | static const int value = $j; |
||
226 | }; |
||
227 | |||
228 | |||
229 | ]] |
||
230 | template |
||
231 | struct tuple_element { |
||
232 | typedef typename gtest_internal::TupleElement< |
||
233 | k < (tuple_size |
||
234 | }; |
||
235 | |||
236 | #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element |
||
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 |
||
248 | static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) |
||
249 | Field(Tuple& t) { return t.f$(i)_; } // NOLINT |
||
250 | |||
251 | template |
||
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 |
||
261 | GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) |
||
262 | get(GTEST_$(n)_TUPLE_(T)& t) { |
||
263 | return gtest_internal::Get |
||
264 | } |
||
265 | |||
266 | template |
||
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 |
||
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 |
||
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 |
||
283 | struct SameSizeTuplePrefixComparator; |
||
284 | |||
285 | template <> |
||
286 | struct SameSizeTuplePrefixComparator<0, 0> { |
||
287 | template |
||
288 | static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { |
||
289 | return true; |
||
290 | } |
||
291 | }; |
||
292 | |||
293 | template |
||
294 | struct SameSizeTuplePrefixComparator |
||
295 | template |
||
296 | static bool Eq(const Tuple1& t1, const Tuple2& t2) { |
||
297 | return SameSizeTuplePrefixComparator |
||
298 | ::std::tr1::get |
||
299 | } |
||
300 | }; |
||
301 | |||
302 | } // namespace gtest_internal |
||
303 | |||
304 | template |
||
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 |
||
309 | tuple_size |
||
310 | } |
||
311 | |||
312 | template |
||
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_ |