gtest-tuple.h.pump 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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. // Implements a subset of TR1 tuple needed by Google Test and Google Mock.
  35. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
  36. #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
  37. #include <utility> // For ::std::pair.
  38. // The compiler used in Symbian has a bug that prevents us from declaring the
  39. // tuple template as a friend (it complains that tuple is redefined). This
  40. // hack bypasses the bug by declaring the members that should otherwise be
  41. // private as public.
  42. // Sun Studio versions < 12 also have the above bug.
  43. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
  44. # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
  45. #else
  46. # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
  47. template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
  48. private:
  49. #endif
  50. $range i 0..n-1
  51. $range j 0..n
  52. $range k 1..n
  53. // GTEST_n_TUPLE_(T) is the type of an n-tuple.
  54. #define GTEST_0_TUPLE_(T) tuple<>
  55. $for k [[
  56. $range m 0..k-1
  57. $range m2 k..n-1
  58. #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
  59. ]]
  60. // GTEST_n_TYPENAMES_(T) declares a list of n typenames.
  61. $for j [[
  62. $range m 0..j-1
  63. #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
  64. ]]
  65. // In theory, defining stuff in the ::std namespace is undefined
  66. // behavior. We can do this as we are playing the role of a standard
  67. // library vendor.
  68. namespace std {
  69. namespace tr1 {
  70. template <$for i, [[typename T$i = void]]>
  71. class tuple;
  72. // Anything in namespace gtest_internal is Google Test's INTERNAL
  73. // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
  74. namespace gtest_internal {
  75. // ByRef<T>::type is T if T is a reference; otherwise it's const T&.
  76. template <typename T>
  77. struct ByRef { typedef const T& type; }; // NOLINT
  78. template <typename T>
  79. struct ByRef<T&> { typedef T& type; }; // NOLINT
  80. // A handy wrapper for ByRef.
  81. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
  82. // AddRef<T>::type is T if T is a reference; otherwise it's T&. This
  83. // is the same as tr1::add_reference<T>::type.
  84. template <typename T>
  85. struct AddRef { typedef T& type; }; // NOLINT
  86. template <typename T>
  87. struct AddRef<T&> { typedef T& type; }; // NOLINT
  88. // A handy wrapper for AddRef.
  89. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
  90. // A helper for implementing get<k>().
  91. template <int k> class Get;
  92. // A helper for implementing tuple_element<k, T>. kIndexValid is true
  93. // iff k < the number of fields in tuple type T.
  94. template <bool kIndexValid, int kIndex, class Tuple>
  95. struct TupleElement;
  96. $for i [[
  97. template <GTEST_$(n)_TYPENAMES_(T)>
  98. struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
  99. typedef T$i type;
  100. };
  101. ]]
  102. } // namespace gtest_internal
  103. template <>
  104. class tuple<> {
  105. public:
  106. tuple() {}
  107. tuple(const tuple& /* t */) {}
  108. tuple& operator=(const tuple& /* t */) { return *this; }
  109. };
  110. $for k [[
  111. $range m 0..k-1
  112. template <GTEST_$(k)_TYPENAMES_(T)>
  113. class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
  114. public:
  115. template <int k> friend class gtest_internal::Get;
  116. tuple() : $for m, [[f$(m)_()]] {}
  117. explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
  118. $for m, [[f$(m)_(f$m)]] {}
  119. tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
  120. template <GTEST_$(k)_TYPENAMES_(U)>
  121. tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
  122. $if k == 2 [[
  123. template <typename U0, typename U1>
  124. tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
  125. ]]
  126. tuple& operator=(const tuple& t) { return CopyFrom(t); }
  127. template <GTEST_$(k)_TYPENAMES_(U)>
  128. tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
  129. return CopyFrom(t);
  130. }
  131. $if k == 2 [[
  132. template <typename U0, typename U1>
  133. tuple& operator=(const ::std::pair<U0, U1>& p) {
  134. f0_ = p.first;
  135. f1_ = p.second;
  136. return *this;
  137. }
  138. ]]
  139. GTEST_DECLARE_TUPLE_AS_FRIEND_
  140. template <GTEST_$(k)_TYPENAMES_(U)>
  141. tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
  142. $for m [[
  143. f$(m)_ = t.f$(m)_;
  144. ]]
  145. return *this;
  146. }
  147. $for m [[
  148. T$m f$(m)_;
  149. ]]
  150. };
  151. ]]
  152. // 6.1.3.2 Tuple creation functions.
  153. // Known limitations: we don't support passing an
  154. // std::tr1::reference_wrapper<T> to make_tuple(). And we don't
  155. // implement tie().
  156. inline tuple<> make_tuple() { return tuple<>(); }
  157. $for k [[
  158. $range m 0..k-1
  159. template <GTEST_$(k)_TYPENAMES_(T)>
  160. inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
  161. return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
  162. }
  163. ]]
  164. // 6.1.3.3 Tuple helper classes.
  165. template <typename Tuple> struct tuple_size;
  166. $for j [[
  167. template <GTEST_$(j)_TYPENAMES_(T)>
  168. struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
  169. static const int value = $j;
  170. };
  171. ]]
  172. template <int k, class Tuple>
  173. struct tuple_element {
  174. typedef typename gtest_internal::TupleElement<
  175. k < (tuple_size<Tuple>::value), k, Tuple>::type type;
  176. };
  177. #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
  178. // 6.1.3.4 Element access.
  179. namespace gtest_internal {
  180. $for i [[
  181. template <>
  182. class Get<$i> {
  183. public:
  184. template <class Tuple>
  185. static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
  186. Field(Tuple& t) { return t.f$(i)_; } // NOLINT
  187. template <class Tuple>
  188. static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
  189. ConstField(const Tuple& t) { return t.f$(i)_; }
  190. };
  191. ]]
  192. } // namespace gtest_internal
  193. template <int k, GTEST_$(n)_TYPENAMES_(T)>
  194. GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
  195. get(GTEST_$(n)_TUPLE_(T)& t) {
  196. return gtest_internal::Get<k>::Field(t);
  197. }
  198. template <int k, GTEST_$(n)_TYPENAMES_(T)>
  199. GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
  200. get(const GTEST_$(n)_TUPLE_(T)& t) {
  201. return gtest_internal::Get<k>::ConstField(t);
  202. }
  203. // 6.1.3.5 Relational operators
  204. // We only implement == and !=, as we don't have a need for the rest yet.
  205. namespace gtest_internal {
  206. // SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
  207. // first k fields of t1 equals the first k fields of t2.
  208. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
  209. // k1 != k2.
  210. template <int kSize1, int kSize2>
  211. struct SameSizeTuplePrefixComparator;
  212. template <>
  213. struct SameSizeTuplePrefixComparator<0, 0> {
  214. template <class Tuple1, class Tuple2>
  215. static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
  216. return true;
  217. }
  218. };
  219. template <int k>
  220. struct SameSizeTuplePrefixComparator<k, k> {
  221. template <class Tuple1, class Tuple2>
  222. static bool Eq(const Tuple1& t1, const Tuple2& t2) {
  223. return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
  224. ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
  225. }
  226. };
  227. } // namespace gtest_internal
  228. template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
  229. inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
  230. const GTEST_$(n)_TUPLE_(U)& u) {
  231. return gtest_internal::SameSizeTuplePrefixComparator<
  232. tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
  233. tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
  234. }
  235. template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
  236. inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
  237. const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
  238. // 6.1.4 Pairs.
  239. // Unimplemented.
  240. } // namespace tr1
  241. } // namespace std
  242. $for j [[
  243. #undef GTEST_$(j)_TUPLE_
  244. ]]
  245. $for j [[
  246. #undef GTEST_$(j)_TYPENAMES_
  247. ]]
  248. #undef GTEST_DECLARE_TUPLE_AS_FRIEND_
  249. #undef GTEST_BY_REF_
  250. #undef GTEST_ADD_REF_
  251. #undef GTEST_TUPLE_ELEMENT_
  252. #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_