Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | 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 | } // namespace gtest_internal |
||
127 | |||
128 | template <> |
||
129 | class tuple<> { |
||
130 | public: |
||
131 | tuple() {} |
||
132 | tuple(const tuple& /* t */) {} |
||
133 | tuple& operator=(const tuple& /* t */) { return *this; } |
||
134 | }; |
||
135 | |||
136 | |||
137 | $for k [[ |
||
138 | $range m 0..k-1 |
||
139 | template |
||
140 | class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { |
||
141 | public: |
||
142 | template |
||
143 | |||
144 | tuple() : $for m, [[f$(m)_()]] {} |
||
145 | |||
146 | explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] |
||
147 | $for m, [[f$(m)_(f$m)]] {} |
||
148 | |||
149 | tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} |
||
150 | |||
151 | template |
||
152 | tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} |
||
153 | |||
154 | $if k == 2 [[ |
||
155 | template |
||
156 | tuple(const ::std::pair |
||
157 | |||
158 | ]] |
||
159 | |||
160 | tuple& operator=(const tuple& t) { return CopyFrom(t); } |
||
161 | |||
162 | template |
||
163 | tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { |
||
164 | return CopyFrom(t); |
||
165 | } |
||
166 | |||
167 | $if k == 2 [[ |
||
168 | template |
||
169 | tuple& operator=(const ::std::pair |
||
170 | f0_ = p.first; |
||
171 | f1_ = p.second; |
||
172 | return *this; |
||
173 | } |
||
174 | |||
175 | ]] |
||
176 | |||
177 | GTEST_DECLARE_TUPLE_AS_FRIEND_ |
||
178 | |||
179 | template |
||
180 | tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { |
||
181 | |||
182 | $for m [[ |
||
183 | f$(m)_ = t.f$(m)_; |
||
184 | |||
185 | ]] |
||
186 | return *this; |
||
187 | } |
||
188 | |||
189 | |||
190 | $for m [[ |
||
191 | T$m f$(m)_; |
||
192 | |||
193 | ]] |
||
194 | }; |
||
195 | |||
196 | |||
197 | ]] |
||
198 | // 6.1.3.2 Tuple creation functions. |
||
199 | |||
200 | // Known limitations: we don't support passing an |
||
201 | // std::tr1::reference_wrapper |
||
202 | // implement tie(). |
||
203 | |||
204 | inline tuple<> make_tuple() { return tuple<>(); } |
||
205 | |||
206 | $for k [[ |
||
207 | $range m 0..k-1 |
||
208 | |||
209 | template |
||
210 | inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { |
||
211 | return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); |
||
212 | } |
||
213 | |||
214 | ]] |
||
215 | |||
216 | // 6.1.3.3 Tuple helper classes. |
||
217 | |||
218 | template |
||
219 | |||
220 | |||
221 | $for j [[ |
||
222 | template |
||
223 | struct tuple_size |
||
224 | |||
225 | |||
226 | ]] |
||
227 | template |
||
228 | struct tuple_element { |
||
229 | typedef typename gtest_internal::TupleElement< |
||
230 | k < (tuple_size |
||
231 | }; |
||
232 | |||
233 | #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element |
||
234 | |||
235 | // 6.1.3.4 Element access. |
||
236 | |||
237 | namespace gtest_internal { |
||
238 | |||
239 | |||
240 | $for i [[ |
||
241 | template <> |
||
242 | class Get<$i> { |
||
243 | public: |
||
244 | template |
||
245 | static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) |
||
246 | Field(Tuple& t) { return t.f$(i)_; } // NOLINT |
||
247 | |||
248 | template |
||
249 | static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) |
||
250 | ConstField(const Tuple& t) { return t.f$(i)_; } |
||
251 | }; |
||
252 | |||
253 | |||
254 | ]] |
||
255 | } // namespace gtest_internal |
||
256 | |||
257 | template |
||
258 | GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) |
||
259 | get(GTEST_$(n)_TUPLE_(T)& t) { |
||
260 | return gtest_internal::Get |
||
261 | } |
||
262 | |||
263 | template |
||
264 | GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) |
||
265 | get(const GTEST_$(n)_TUPLE_(T)& t) { |
||
266 | return gtest_internal::Get |
||
267 | } |
||
268 | |||
269 | // 6.1.3.5 Relational operators |
||
270 | |||
271 | // We only implement == and !=, as we don't have a need for the rest yet. |
||
272 | |||
273 | namespace gtest_internal { |
||
274 | |||
275 | // SameSizeTuplePrefixComparator |
||
276 | // first k fields of t1 equals the first k fields of t2. |
||
277 | // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if |
||
278 | // k1 != k2. |
||
279 | template |
||
280 | struct SameSizeTuplePrefixComparator; |
||
281 | |||
282 | template <> |
||
283 | struct SameSizeTuplePrefixComparator<0, 0> { |
||
284 | template |
||
285 | static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { |
||
286 | return true; |
||
287 | } |
||
288 | }; |
||
289 | |||
290 | template |
||
291 | struct SameSizeTuplePrefixComparator |
||
292 | template |
||
293 | static bool Eq(const Tuple1& t1, const Tuple2& t2) { |
||
294 | return SameSizeTuplePrefixComparator |
||
295 | ::std::tr1::get |
||
296 | } |
||
297 | }; |
||
298 | |||
299 | } // namespace gtest_internal |
||
300 | |||
301 | template |
||
302 | inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, |
||
303 | const GTEST_$(n)_TUPLE_(U)& u) { |
||
304 | return gtest_internal::SameSizeTuplePrefixComparator< |
||
305 | tuple_size |
||
306 | tuple_size |
||
307 | } |
||
308 | |||
309 | template |
||
310 | inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, |
||
311 | const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } |
||
312 | |||
313 | // 6.1.4 Pairs. |
||
314 | // Unimplemented. |
||
315 | |||
316 | } // namespace tr1 |
||
317 | } // namespace std |
||
318 | |||
319 | |||
320 | $for j [[ |
||
321 | #undef GTEST_$(j)_TUPLE_ |
||
322 | |||
323 | ]] |
||
324 | |||
325 | |||
326 | $for j [[ |
||
327 | #undef GTEST_$(j)_TYPENAMES_ |
||
328 | |||
329 | ]] |
||
330 | |||
331 | #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ |
||
332 | #undef GTEST_BY_REF_ |
||
333 | #undef GTEST_ADD_REF_ |
||
334 | #undef GTEST_TUPLE_ELEMENT_ |
||
335 | |||
336 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ |