blob: 00f1d7d4a116df97e5324ccdf0ab65183553b9c5 [file] [log] [blame]
wu@webrtc.org5c9dd592013-10-25 21:18:33 +00001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef TALK_BASE_TEMPLATE_UTIL_H_
6#define TALK_BASE_TEMPLATE_UTIL_H_
7
pbos@webrtc.orgb9518272014-03-07 15:22:04 +00008#include <stddef.h> // For size_t.
wu@webrtc.org5c9dd592013-10-25 21:18:33 +00009
10namespace talk_base {
11
12// template definitions from tr1
13
14template<class T, T v>
15struct integral_constant {
16 static const T value = v;
17 typedef T value_type;
18 typedef integral_constant<T, v> type;
19};
20
21template <class T, T v> const T integral_constant<T, v>::value;
22
23typedef integral_constant<bool, true> true_type;
24typedef integral_constant<bool, false> false_type;
25
26template <class T> struct is_pointer : false_type {};
27template <class T> struct is_pointer<T*> : true_type {};
28
29template <class T, class U> struct is_same : public false_type {};
30template <class T> struct is_same<T,T> : true_type {};
31
32template<class> struct is_array : public false_type {};
33template<class T, size_t n> struct is_array<T[n]> : public true_type {};
34template<class T> struct is_array<T[]> : public true_type {};
35
36template <class T> struct is_non_const_reference : false_type {};
37template <class T> struct is_non_const_reference<T&> : true_type {};
38template <class T> struct is_non_const_reference<const T&> : false_type {};
39
40template <class T> struct is_void : false_type {};
41template <> struct is_void<void> : true_type {};
42
43namespace internal {
44
45// Types YesType and NoType are guaranteed such that sizeof(YesType) <
46// sizeof(NoType).
47typedef char YesType;
48
49struct NoType {
50 YesType dummy[2];
51};
52
53// This class is an implementation detail for is_convertible, and you
54// don't need to know how it works to use is_convertible. For those
55// who care: we declare two different functions, one whose argument is
56// of type To and one with a variadic argument list. We give them
57// return types of different size, so we can use sizeof to trick the
58// compiler into telling us which function it would have chosen if we
59// had called it with an argument of type From. See Alexandrescu's
60// _Modern C++ Design_ for more details on this sort of trick.
61
62struct ConvertHelper {
63 template <typename To>
64 static YesType Test(To);
65
66 template <typename To>
67 static NoType Test(...);
68
69 template <typename From>
70 static From& Create();
71};
72
73// Used to determine if a type is a struct/union/class. Inspired by Boost's
74// is_class type_trait implementation.
75struct IsClassHelper {
76 template <typename C>
77 static YesType Test(void(C::*)(void));
78
79 template <typename C>
80 static NoType Test(...);
81};
82
83} // namespace internal
84
85// Inherits from true_type if From is convertible to To, false_type otherwise.
86//
87// Note that if the type is convertible, this will be a true_type REGARDLESS
88// of whether or not the conversion would emit a warning.
89template <typename From, typename To>
90struct is_convertible
91 : integral_constant<bool,
92 sizeof(internal::ConvertHelper::Test<To>(
93 internal::ConvertHelper::Create<From>())) ==
94 sizeof(internal::YesType)> {
95};
96
97template <typename T>
98struct is_class
99 : integral_constant<bool,
100 sizeof(internal::IsClassHelper::Test<T>(0)) ==
101 sizeof(internal::YesType)> {
102};
103
104} // namespace talk_base
105
106#endif // TALK_BASE_TEMPLATE_UTIL_H_