1// Copyright (c) 2006, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// ----
31// Author: Matt Austern
32
33#include <google/protobuf/stubs/type_traits.h>
34
35#include <stdlib.h>   // for exit()
36#include <stdio.h>
37#include <string>
38#include <vector>
39
40#include <google/protobuf/testing/googletest.h>
41#include <gtest/gtest.h>
42
43typedef int int32;
44// IBM AIX typedefs `int64` in `sys/inttypes.h`, included transitively above.
45#ifndef _AIX
46typedef long int64;
47#endif
48
49using std::string;
50using std::vector;
51using std::pair;
52
53
54// This assertion produces errors like "error: invalid use of
55// incomplete type 'struct <unnamed>::AssertTypesEq<const int, int>'"
56// when it fails.
57template<typename T, typename U> struct AssertTypesEq;
58template<typename T> struct AssertTypesEq<T, T> {};
59#define COMPILE_ASSERT_TYPES_EQ(T, U) static_cast<void>(AssertTypesEq<T, U>())
60
61// A user-defined POD type.
62struct A {
63  int n_;
64};
65
66// A user-defined non-POD type with a trivial copy constructor.
67class B {
68 public:
69  explicit B(int n) : n_(n) { }
70 private:
71  int n_;
72};
73
74// Another user-defined non-POD type with a trivial copy constructor.
75// We will explicitly declare C to have a trivial copy constructor
76// by specializing has_trivial_copy.
77class C {
78 public:
79  explicit C(int n) : n_(n) { }
80 private:
81  int n_;
82};
83
84namespace google {
85namespace protobuf {
86namespace internal {
87template<> struct has_trivial_copy<C> : true_type { };
88}  // namespace internal
89}  // namespace protobuf
90}  // namespace google
91
92// Another user-defined non-POD type with a trivial assignment operator.
93// We will explicitly declare C to have a trivial assignment operator
94// by specializing has_trivial_assign.
95class D {
96 public:
97  explicit D(int n) : n_(n) { }
98 private:
99  int n_;
100};
101
102namespace google {
103namespace protobuf {
104namespace internal {
105template<> struct has_trivial_assign<D> : true_type { };
106}  // namespace internal
107}  // namespace protobuf
108}  // namespace google
109
110// Another user-defined non-POD type with a trivial constructor.
111// We will explicitly declare E to have a trivial constructor
112// by specializing has_trivial_constructor.
113class E {
114 public:
115  int n_;
116};
117
118namespace google {
119namespace protobuf {
120namespace internal {
121template<> struct has_trivial_constructor<E> : true_type { };
122}  // namespace internal
123}  // namespace protobuf
124}  // namespace google
125
126// Another user-defined non-POD type with a trivial destructor.
127// We will explicitly declare E to have a trivial destructor
128// by specializing has_trivial_destructor.
129class F {
130 public:
131  explicit F(int n) : n_(n) { }
132 private:
133  int n_;
134};
135
136namespace google {
137namespace protobuf {
138namespace internal {
139template<> struct has_trivial_destructor<F> : true_type { };
140}  // namespace internal
141}  // namespace protobuf
142}  // namespace google
143
144enum G {};
145
146union H {};
147
148class I {
149 public:
150  operator int() const;
151};
152
153class J {
154 private:
155  operator int() const;
156};
157
158namespace google {
159namespace protobuf {
160namespace internal {
161namespace {
162
163// A base class and a derived class that inherits from it, used for
164// testing conversion type traits.
165class Base {
166 public:
167  virtual ~Base() { }
168};
169
170class Derived : public Base {
171};
172
173TEST(TypeTraitsTest, TestIsInteger) {
174  // Verify that is_integral is true for all integer types.
175  EXPECT_TRUE(is_integral<bool>::value);
176  EXPECT_TRUE(is_integral<char>::value);
177  EXPECT_TRUE(is_integral<unsigned char>::value);
178  EXPECT_TRUE(is_integral<signed char>::value);
179  EXPECT_TRUE(is_integral<wchar_t>::value);
180  EXPECT_TRUE(is_integral<int>::value);
181  EXPECT_TRUE(is_integral<unsigned int>::value);
182  EXPECT_TRUE(is_integral<short>::value);
183  EXPECT_TRUE(is_integral<unsigned short>::value);
184  EXPECT_TRUE(is_integral<long>::value);
185  EXPECT_TRUE(is_integral<unsigned long>::value);
186
187  // Verify that is_integral is false for a few non-integer types.
188  EXPECT_FALSE(is_integral<void>::value);
189  EXPECT_FALSE(is_integral<float>::value);
190  EXPECT_FALSE(is_integral<string>::value);
191  EXPECT_FALSE(is_integral<int*>::value);
192  EXPECT_FALSE(is_integral<A>::value);
193  EXPECT_FALSE((is_integral<pair<int, int> >::value));
194
195  // Verify that cv-qualified integral types are still integral, and
196  // cv-qualified non-integral types are still non-integral.
197  EXPECT_TRUE(is_integral<const char>::value);
198  EXPECT_TRUE(is_integral<volatile bool>::value);
199  EXPECT_TRUE(is_integral<const volatile unsigned int>::value);
200  EXPECT_FALSE(is_integral<const float>::value);
201  EXPECT_FALSE(is_integral<int* volatile>::value);
202  EXPECT_FALSE(is_integral<const volatile string>::value);
203}
204
205TEST(TypeTraitsTest, TestIsFloating) {
206  // Verify that is_floating_point is true for all floating-point types.
207  EXPECT_TRUE(is_floating_point<float>::value);
208  EXPECT_TRUE(is_floating_point<double>::value);
209  EXPECT_TRUE(is_floating_point<long double>::value);
210
211  // Verify that is_floating_point is false for a few non-float types.
212  EXPECT_FALSE(is_floating_point<void>::value);
213  EXPECT_FALSE(is_floating_point<long>::value);
214  EXPECT_FALSE(is_floating_point<string>::value);
215  EXPECT_FALSE(is_floating_point<float*>::value);
216  EXPECT_FALSE(is_floating_point<A>::value);
217  EXPECT_FALSE((is_floating_point<pair<int, int> >::value));
218
219  // Verify that cv-qualified floating point types are still floating, and
220  // cv-qualified non-floating types are still non-floating.
221  EXPECT_TRUE(is_floating_point<const float>::value);
222  EXPECT_TRUE(is_floating_point<volatile double>::value);
223  EXPECT_TRUE(is_floating_point<const volatile long double>::value);
224  EXPECT_FALSE(is_floating_point<const int>::value);
225  EXPECT_FALSE(is_floating_point<volatile string>::value);
226  EXPECT_FALSE(is_floating_point<const volatile char>::value);
227}
228
229TEST(TypeTraitsTest, TestIsPointer) {
230  // Verify that is_pointer is true for some pointer types.
231  EXPECT_TRUE(is_pointer<int*>::value);
232  EXPECT_TRUE(is_pointer<void*>::value);
233  EXPECT_TRUE(is_pointer<string*>::value);
234  EXPECT_TRUE(is_pointer<const void*>::value);
235  EXPECT_TRUE(is_pointer<volatile float* const*>::value);
236
237  // Verify that is_pointer is false for some non-pointer types.
238  EXPECT_FALSE(is_pointer<void>::value);
239  EXPECT_FALSE(is_pointer<float&>::value);
240  EXPECT_FALSE(is_pointer<long>::value);
241  EXPECT_FALSE(is_pointer<vector<int*> >::value);
242  EXPECT_FALSE(is_pointer<int[5]>::value);
243
244  // A function pointer is a pointer, but a function type, or a function
245  // reference type, is not.
246  EXPECT_TRUE(is_pointer<int (*)(int x)>::value);
247  EXPECT_FALSE(is_pointer<void(char x)>::value);
248  EXPECT_FALSE(is_pointer<double (&)(string x)>::value);
249
250  // Verify that is_pointer<T> is true for some cv-qualified pointer types,
251  // and false for some cv-qualified non-pointer types.
252  EXPECT_TRUE(is_pointer<int* const>::value);
253  EXPECT_TRUE(is_pointer<const void* volatile>::value);
254  EXPECT_TRUE(is_pointer<char** const volatile>::value);
255  EXPECT_FALSE(is_pointer<const int>::value);
256  EXPECT_FALSE(is_pointer<volatile vector<int*> >::value);
257  EXPECT_FALSE(is_pointer<const volatile double>::value);
258}
259
260TEST(TypeTraitsTest, TestIsEnum) {
261// is_enum isn't supported on MSVC or gcc 3.x
262#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
263  // Verify that is_enum is true for enum types.
264  EXPECT_TRUE(is_enum<G>::value);
265  EXPECT_TRUE(is_enum<const G>::value);
266  EXPECT_TRUE(is_enum<volatile G>::value);
267  EXPECT_TRUE(is_enum<const volatile G>::value);
268
269  // Verify that is_enum is false for a few non-enum types.
270  EXPECT_FALSE(is_enum<void>::value);
271  EXPECT_FALSE(is_enum<G&>::value);
272  EXPECT_FALSE(is_enum<G[1]>::value);
273  EXPECT_FALSE(is_enum<const G[1]>::value);
274  EXPECT_FALSE(is_enum<G[]>::value);
275  EXPECT_FALSE(is_enum<int>::value);
276  EXPECT_FALSE(is_enum<float>::value);
277  EXPECT_FALSE(is_enum<A>::value);
278  EXPECT_FALSE(is_enum<A*>::value);
279  EXPECT_FALSE(is_enum<const A>::value);
280  EXPECT_FALSE(is_enum<H>::value);
281  EXPECT_FALSE(is_enum<I>::value);
282  EXPECT_FALSE(is_enum<J>::value);
283  EXPECT_FALSE(is_enum<void()>::value);
284  EXPECT_FALSE(is_enum<void(*)()>::value);
285  EXPECT_FALSE(is_enum<int A::*>::value);
286  EXPECT_FALSE(is_enum<void (A::*)()>::value);
287#endif
288}
289
290TEST(TypeTraitsTest, TestIsReference) {
291  // Verifies that is_reference is true for all reference types.
292  typedef float& RefFloat;
293  EXPECT_TRUE(is_reference<float&>::value);
294  EXPECT_TRUE(is_reference<const int&>::value);
295  EXPECT_TRUE(is_reference<const int*&>::value);
296  EXPECT_TRUE(is_reference<int (&)(bool)>::value);
297  EXPECT_TRUE(is_reference<RefFloat>::value);
298  EXPECT_TRUE(is_reference<const RefFloat>::value);
299  EXPECT_TRUE(is_reference<volatile RefFloat>::value);
300  EXPECT_TRUE(is_reference<const volatile RefFloat>::value);
301
302
303  // Verifies that is_reference is false for all non-reference types.
304  EXPECT_FALSE(is_reference<float>::value);
305  EXPECT_FALSE(is_reference<const float>::value);
306  EXPECT_FALSE(is_reference<volatile float>::value);
307  EXPECT_FALSE(is_reference<const volatile float>::value);
308  EXPECT_FALSE(is_reference<const int*>::value);
309  EXPECT_FALSE(is_reference<int()>::value);
310  EXPECT_FALSE(is_reference<void(*)(const char&)>::value);
311}
312
313TEST(TypeTraitsTest, TestAddReference) {
314  COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int>::type);
315  COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int>::type);
316  COMPILE_ASSERT_TYPES_EQ(volatile int&,
317                          add_reference<volatile int>::type);
318  COMPILE_ASSERT_TYPES_EQ(const volatile int&,
319                          add_reference<const volatile int>::type);
320  COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int&>::type);
321  COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int&>::type);
322  COMPILE_ASSERT_TYPES_EQ(volatile int&,
323                          add_reference<volatile int&>::type);
324  COMPILE_ASSERT_TYPES_EQ(const volatile int&,
325                          add_reference<const volatile int&>::type);
326}
327
328TEST(TypeTraitsTest, TestIsPod) {
329  // Verify that arithmetic types and pointers are marked as PODs.
330  EXPECT_TRUE(is_pod<bool>::value);
331  EXPECT_TRUE(is_pod<char>::value);
332  EXPECT_TRUE(is_pod<unsigned char>::value);
333  EXPECT_TRUE(is_pod<signed char>::value);
334  EXPECT_TRUE(is_pod<wchar_t>::value);
335  EXPECT_TRUE(is_pod<int>::value);
336  EXPECT_TRUE(is_pod<unsigned int>::value);
337  EXPECT_TRUE(is_pod<short>::value);
338  EXPECT_TRUE(is_pod<unsigned short>::value);
339  EXPECT_TRUE(is_pod<long>::value);
340  EXPECT_TRUE(is_pod<unsigned long>::value);
341  EXPECT_TRUE(is_pod<float>::value);
342  EXPECT_TRUE(is_pod<double>::value);
343  EXPECT_TRUE(is_pod<long double>::value);
344  EXPECT_TRUE(is_pod<string*>::value);
345  EXPECT_TRUE(is_pod<A*>::value);
346  EXPECT_TRUE(is_pod<const B*>::value);
347  EXPECT_TRUE(is_pod<C**>::value);
348  EXPECT_TRUE(is_pod<const int>::value);
349  EXPECT_TRUE(is_pod<char* volatile>::value);
350  EXPECT_TRUE(is_pod<const volatile double>::value);
351#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
352  EXPECT_TRUE(is_pod<G>::value);
353  EXPECT_TRUE(is_pod<const G>::value);
354  EXPECT_TRUE(is_pod<volatile G>::value);
355  EXPECT_TRUE(is_pod<const volatile G>::value);
356#endif
357
358  // Verify that some non-POD types are not marked as PODs.
359  EXPECT_FALSE(is_pod<void>::value);
360  EXPECT_FALSE(is_pod<string>::value);
361  EXPECT_FALSE((is_pod<pair<int, int> >::value));
362  EXPECT_FALSE(is_pod<A>::value);
363  EXPECT_FALSE(is_pod<B>::value);
364  EXPECT_FALSE(is_pod<C>::value);
365  EXPECT_FALSE(is_pod<const string>::value);
366  EXPECT_FALSE(is_pod<volatile A>::value);
367  EXPECT_FALSE(is_pod<const volatile B>::value);
368}
369
370TEST(TypeTraitsTest, TestHasTrivialConstructor) {
371  // Verify that arithmetic types and pointers have trivial constructors.
372  EXPECT_TRUE(has_trivial_constructor<bool>::value);
373  EXPECT_TRUE(has_trivial_constructor<char>::value);
374  EXPECT_TRUE(has_trivial_constructor<unsigned char>::value);
375  EXPECT_TRUE(has_trivial_constructor<signed char>::value);
376  EXPECT_TRUE(has_trivial_constructor<wchar_t>::value);
377  EXPECT_TRUE(has_trivial_constructor<int>::value);
378  EXPECT_TRUE(has_trivial_constructor<unsigned int>::value);
379  EXPECT_TRUE(has_trivial_constructor<short>::value);
380  EXPECT_TRUE(has_trivial_constructor<unsigned short>::value);
381  EXPECT_TRUE(has_trivial_constructor<long>::value);
382  EXPECT_TRUE(has_trivial_constructor<unsigned long>::value);
383  EXPECT_TRUE(has_trivial_constructor<float>::value);
384  EXPECT_TRUE(has_trivial_constructor<double>::value);
385  EXPECT_TRUE(has_trivial_constructor<long double>::value);
386  EXPECT_TRUE(has_trivial_constructor<string*>::value);
387  EXPECT_TRUE(has_trivial_constructor<A*>::value);
388  EXPECT_TRUE(has_trivial_constructor<const B*>::value);
389  EXPECT_TRUE(has_trivial_constructor<C**>::value);
390
391  // Verify that pairs and arrays of such types have trivial
392  // constructors.
393  typedef int int10[10];
394  EXPECT_TRUE((has_trivial_constructor<pair<int, char*> >::value));
395  EXPECT_TRUE(has_trivial_constructor<int10>::value);
396
397  // Verify that pairs of types without trivial constructors
398  // are not marked as trivial.
399  EXPECT_FALSE((has_trivial_constructor<pair<int, string> >::value));
400  EXPECT_FALSE((has_trivial_constructor<pair<string, int> >::value));
401
402  // Verify that types without trivial constructors are
403  // correctly marked as such.
404  EXPECT_FALSE(has_trivial_constructor<string>::value);
405  EXPECT_FALSE(has_trivial_constructor<vector<int> >::value);
406
407  // Verify that E, which we have declared to have a trivial
408  // constructor, is correctly marked as such.
409  EXPECT_TRUE(has_trivial_constructor<E>::value);
410}
411
412TEST(TypeTraitsTest, TestHasTrivialCopy) {
413  // Verify that arithmetic types and pointers have trivial copy
414  // constructors.
415  EXPECT_TRUE(has_trivial_copy<bool>::value);
416  EXPECT_TRUE(has_trivial_copy<char>::value);
417  EXPECT_TRUE(has_trivial_copy<unsigned char>::value);
418  EXPECT_TRUE(has_trivial_copy<signed char>::value);
419  EXPECT_TRUE(has_trivial_copy<wchar_t>::value);
420  EXPECT_TRUE(has_trivial_copy<int>::value);
421  EXPECT_TRUE(has_trivial_copy<unsigned int>::value);
422  EXPECT_TRUE(has_trivial_copy<short>::value);
423  EXPECT_TRUE(has_trivial_copy<unsigned short>::value);
424  EXPECT_TRUE(has_trivial_copy<long>::value);
425  EXPECT_TRUE(has_trivial_copy<unsigned long>::value);
426  EXPECT_TRUE(has_trivial_copy<float>::value);
427  EXPECT_TRUE(has_trivial_copy<double>::value);
428  EXPECT_TRUE(has_trivial_copy<long double>::value);
429  EXPECT_TRUE(has_trivial_copy<string*>::value);
430  EXPECT_TRUE(has_trivial_copy<A*>::value);
431  EXPECT_TRUE(has_trivial_copy<const B*>::value);
432  EXPECT_TRUE(has_trivial_copy<C**>::value);
433
434  // Verify that pairs and arrays of such types have trivial
435  // copy constructors.
436  typedef int int10[10];
437  EXPECT_TRUE((has_trivial_copy<pair<int, char*> >::value));
438  EXPECT_TRUE(has_trivial_copy<int10>::value);
439
440  // Verify that pairs of types without trivial copy constructors
441  // are not marked as trivial.
442  EXPECT_FALSE((has_trivial_copy<pair<int, string> >::value));
443  EXPECT_FALSE((has_trivial_copy<pair<string, int> >::value));
444
445  // Verify that types without trivial copy constructors are
446  // correctly marked as such.
447  EXPECT_FALSE(has_trivial_copy<string>::value);
448  EXPECT_FALSE(has_trivial_copy<vector<int> >::value);
449
450  // Verify that C, which we have declared to have a trivial
451  // copy constructor, is correctly marked as such.
452  EXPECT_TRUE(has_trivial_copy<C>::value);
453}
454
455TEST(TypeTraitsTest, TestHasTrivialAssign) {
456  // Verify that arithmetic types and pointers have trivial assignment
457  // operators.
458  EXPECT_TRUE(has_trivial_assign<bool>::value);
459  EXPECT_TRUE(has_trivial_assign<char>::value);
460  EXPECT_TRUE(has_trivial_assign<unsigned char>::value);
461  EXPECT_TRUE(has_trivial_assign<signed char>::value);
462  EXPECT_TRUE(has_trivial_assign<wchar_t>::value);
463  EXPECT_TRUE(has_trivial_assign<int>::value);
464  EXPECT_TRUE(has_trivial_assign<unsigned int>::value);
465  EXPECT_TRUE(has_trivial_assign<short>::value);
466  EXPECT_TRUE(has_trivial_assign<unsigned short>::value);
467  EXPECT_TRUE(has_trivial_assign<long>::value);
468  EXPECT_TRUE(has_trivial_assign<unsigned long>::value);
469  EXPECT_TRUE(has_trivial_assign<float>::value);
470  EXPECT_TRUE(has_trivial_assign<double>::value);
471  EXPECT_TRUE(has_trivial_assign<long double>::value);
472  EXPECT_TRUE(has_trivial_assign<string*>::value);
473  EXPECT_TRUE(has_trivial_assign<A*>::value);
474  EXPECT_TRUE(has_trivial_assign<const B*>::value);
475  EXPECT_TRUE(has_trivial_assign<C**>::value);
476
477  // Verify that pairs and arrays of such types have trivial
478  // assignment operators.
479  typedef int int10[10];
480  EXPECT_TRUE((has_trivial_assign<pair<int, char*> >::value));
481  EXPECT_TRUE(has_trivial_assign<int10>::value);
482
483  // Verify that pairs of types without trivial assignment operators
484  // are not marked as trivial.
485  EXPECT_FALSE((has_trivial_assign<pair<int, string> >::value));
486  EXPECT_FALSE((has_trivial_assign<pair<string, int> >::value));
487
488  // Verify that types without trivial assignment operators are
489  // correctly marked as such.
490  EXPECT_FALSE(has_trivial_assign<string>::value);
491  EXPECT_FALSE(has_trivial_assign<vector<int> >::value);
492
493  // Verify that D, which we have declared to have a trivial
494  // assignment operator, is correctly marked as such.
495  EXPECT_TRUE(has_trivial_assign<D>::value);
496}
497
498TEST(TypeTraitsTest, TestHasTrivialDestructor) {
499  // Verify that arithmetic types and pointers have trivial destructors.
500  EXPECT_TRUE(has_trivial_destructor<bool>::value);
501  EXPECT_TRUE(has_trivial_destructor<char>::value);
502  EXPECT_TRUE(has_trivial_destructor<unsigned char>::value);
503  EXPECT_TRUE(has_trivial_destructor<signed char>::value);
504  EXPECT_TRUE(has_trivial_destructor<wchar_t>::value);
505  EXPECT_TRUE(has_trivial_destructor<int>::value);
506  EXPECT_TRUE(has_trivial_destructor<unsigned int>::value);
507  EXPECT_TRUE(has_trivial_destructor<short>::value);
508  EXPECT_TRUE(has_trivial_destructor<unsigned short>::value);
509  EXPECT_TRUE(has_trivial_destructor<long>::value);
510  EXPECT_TRUE(has_trivial_destructor<unsigned long>::value);
511  EXPECT_TRUE(has_trivial_destructor<float>::value);
512  EXPECT_TRUE(has_trivial_destructor<double>::value);
513  EXPECT_TRUE(has_trivial_destructor<long double>::value);
514  EXPECT_TRUE(has_trivial_destructor<string*>::value);
515  EXPECT_TRUE(has_trivial_destructor<A*>::value);
516  EXPECT_TRUE(has_trivial_destructor<const B*>::value);
517  EXPECT_TRUE(has_trivial_destructor<C**>::value);
518
519  // Verify that pairs and arrays of such types have trivial
520  // destructors.
521  typedef int int10[10];
522  EXPECT_TRUE((has_trivial_destructor<pair<int, char*> >::value));
523  EXPECT_TRUE(has_trivial_destructor<int10>::value);
524
525  // Verify that pairs of types without trivial destructors
526  // are not marked as trivial.
527  EXPECT_FALSE((has_trivial_destructor<pair<int, string> >::value));
528  EXPECT_FALSE((has_trivial_destructor<pair<string, int> >::value));
529
530  // Verify that types without trivial destructors are
531  // correctly marked as such.
532  EXPECT_FALSE(has_trivial_destructor<string>::value);
533  EXPECT_FALSE(has_trivial_destructor<vector<int> >::value);
534
535  // Verify that F, which we have declared to have a trivial
536  // destructor, is correctly marked as such.
537  EXPECT_TRUE(has_trivial_destructor<F>::value);
538}
539
540// Tests remove_pointer.
541TEST(TypeTraitsTest, TestRemovePointer) {
542  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int>::type);
543  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int*>::type);
544  COMPILE_ASSERT_TYPES_EQ(const int, remove_pointer<const int*>::type);
545  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* const>::type);
546  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* volatile>::type);
547}
548
549TEST(TypeTraitsTest, TestRemoveConst) {
550  COMPILE_ASSERT_TYPES_EQ(int, remove_const<int>::type);
551  COMPILE_ASSERT_TYPES_EQ(int, remove_const<const int>::type);
552  COMPILE_ASSERT_TYPES_EQ(int *, remove_const<int * const>::type);
553  // TR1 examples.
554  COMPILE_ASSERT_TYPES_EQ(const int *, remove_const<const int *>::type);
555  COMPILE_ASSERT_TYPES_EQ(volatile int,
556                          remove_const<const volatile int>::type);
557}
558
559TEST(TypeTraitsTest, TestRemoveVolatile) {
560  COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<int>::type);
561  COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<volatile int>::type);
562  COMPILE_ASSERT_TYPES_EQ(int *, remove_volatile<int * volatile>::type);
563  // TR1 examples.
564  COMPILE_ASSERT_TYPES_EQ(volatile int *,
565                          remove_volatile<volatile int *>::type);
566  COMPILE_ASSERT_TYPES_EQ(const int,
567                          remove_volatile<const volatile int>::type);
568}
569
570TEST(TypeTraitsTest, TestRemoveCV) {
571  COMPILE_ASSERT_TYPES_EQ(int, remove_cv<int>::type);
572  COMPILE_ASSERT_TYPES_EQ(int, remove_cv<volatile int>::type);
573  COMPILE_ASSERT_TYPES_EQ(int, remove_cv<const int>::type);
574  COMPILE_ASSERT_TYPES_EQ(int *, remove_cv<int * const volatile>::type);
575  // TR1 examples.
576  COMPILE_ASSERT_TYPES_EQ(const volatile int *,
577                          remove_cv<const volatile int *>::type);
578  COMPILE_ASSERT_TYPES_EQ(int,
579                          remove_cv<const volatile int>::type);
580}
581
582TEST(TypeTraitsTest, TestRemoveReference) {
583  COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int>::type);
584  COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int&>::type);
585  COMPILE_ASSERT_TYPES_EQ(const int, remove_reference<const int&>::type);
586  COMPILE_ASSERT_TYPES_EQ(int*, remove_reference<int * &>::type);
587}
588
589TEST(TypeTraitsTest, TestIsSame) {
590  EXPECT_TRUE((is_same<int32, int32>::value));
591  EXPECT_FALSE((is_same<int32, int64>::value));
592  EXPECT_FALSE((is_same<int64, int32>::value));
593  EXPECT_FALSE((is_same<int, const int>::value));
594
595  EXPECT_TRUE((is_same<void, void>::value));
596  EXPECT_FALSE((is_same<void, int>::value));
597  EXPECT_FALSE((is_same<int, void>::value));
598
599  EXPECT_TRUE((is_same<int*, int*>::value));
600  EXPECT_TRUE((is_same<void*, void*>::value));
601  EXPECT_FALSE((is_same<int*, void*>::value));
602  EXPECT_FALSE((is_same<void*, int*>::value));
603  EXPECT_FALSE((is_same<void*, const void*>::value));
604  EXPECT_FALSE((is_same<void*, void* const>::value));
605
606  EXPECT_TRUE((is_same<Base*, Base*>::value));
607  EXPECT_TRUE((is_same<Derived*, Derived*>::value));
608  EXPECT_FALSE((is_same<Base*, Derived*>::value));
609  EXPECT_FALSE((is_same<Derived*, Base*>::value));
610}
611
612TEST(TypeTraitsTest, TestConvertible) {
613#if !(defined(__GNUC__) && __GNUC__ <= 3)
614  EXPECT_TRUE((is_convertible<int, int>::value));
615  EXPECT_TRUE((is_convertible<int, long>::value));
616  EXPECT_TRUE((is_convertible<long, int>::value));
617
618  EXPECT_TRUE((is_convertible<int*, void*>::value));
619  EXPECT_FALSE((is_convertible<void*, int*>::value));
620
621  EXPECT_TRUE((is_convertible<Derived*, Base*>::value));
622  EXPECT_FALSE((is_convertible<Base*, Derived*>::value));
623  EXPECT_TRUE((is_convertible<Derived*, const Base*>::value));
624  EXPECT_FALSE((is_convertible<const Derived*, Base*>::value));
625#endif
626}
627
628}  // anonymous namespace
629}  // namespace internal
630}  // namespace protobuf
631}  // namespace google
632