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.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
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
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.
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.
33 // Author: wan@google.com (Zhanyong Wan)
35 // Implements a subset of TR1 tuple needed by Google Test and Google Mock.
37 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
38 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
40 #include <utility> // For ::std::pair.
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
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:
50 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
51 template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
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
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."
67 // GTEST_n_TUPLE_(T) is the type of an n-tuple.
68 #define GTEST_0_TUPLE_(T) tuple<>
73 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
77 // GTEST_n_TYPENAMES_(T) declares a list of n typenames.
81 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
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
92 template <$for i, [[typename T$i = void]]>
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 {
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
105 // A handy wrapper for ByRef.
106 #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
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
115 // A handy wrapper for AddRef.
116 #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
118 // A helper for implementing get<k>().
119 template <int k> class Get;
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>
128 template <GTEST_$(n)_TYPENAMES_(T)>
129 struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
135 } // namespace gtest_internal
141 tuple(const tuple& /* t */) {}
142 tuple& operator=(const tuple& /* t */) { return *this; }
148 template <GTEST_$(k)_TYPENAMES_(T)>
149 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
151 template <int k> friend class gtest_internal::Get;
153 tuple() : $for m, [[f$(m)_()]] {}
155 explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
156 $for m, [[f$(m)_(f$m)]] {}
158 tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
160 template <GTEST_$(k)_TYPENAMES_(U)>
161 tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
164 template <typename U0, typename U1>
165 tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
169 tuple& operator=(const tuple& t) { return CopyFrom(t); }
171 template <GTEST_$(k)_TYPENAMES_(U)>
172 tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
177 template <typename U0, typename U1>
178 tuple& operator=(const ::std::pair<U0, U1>& p) {
186 GTEST_DECLARE_TUPLE_AS_FRIEND_
188 template <GTEST_$(k)_TYPENAMES_(U)>
189 tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
207 // 6.1.3.2 Tuple creation functions.
209 // Known limitations: we don't support passing an
210 // std::tr1::reference_wrapper<T> to make_tuple(). And we don't
213 inline tuple<> make_tuple() { return tuple<>(); }
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]]);
225 // 6.1.3.3 Tuple helper classes.
227 template <typename Tuple> struct tuple_size;
231 template <GTEST_$(j)_TYPENAMES_(T)>
232 struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
233 static const int value = $j;
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;
244 #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
246 // 6.1.3.4 Element access.
248 namespace gtest_internal {
255 template <class Tuple>
256 static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
257 Field(Tuple& t) { return t.f$(i)_; } // NOLINT
259 template <class Tuple>
260 static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
261 ConstField(const Tuple& t) { return t.f$(i)_; }
266 } // namespace gtest_internal
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);
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);
280 // 6.1.3.5 Relational operators
282 // We only implement == and !=, as we don't have a need for the rest yet.
284 namespace gtest_internal {
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
290 template <int kSize1, int kSize2>
291 struct SameSizeTuplePrefixComparator;
294 struct SameSizeTuplePrefixComparator<0, 0> {
295 template <class Tuple1, class Tuple2>
296 static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
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);
310 } // namespace gtest_internal
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);
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); }
332 #undef GTEST_$(j)_TUPLE_
338 #undef GTEST_$(j)_TYPENAMES_
342 #undef GTEST_DECLARE_TUPLE_AS_FRIEND_
344 #undef GTEST_ADD_REF_
345 #undef GTEST_TUPLE_ELEMENT_
347 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_