blob: 3c04a860d8f0bea74e3c042af663c12c9075787a [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
kwiberg@webrtc.orgaf9d56f2015-01-13 20:32:04 +00002 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg@webrtc.orgaf9d56f2015-01-13 20:32:04 +000011// Borrowed from Chromium's src/base/template_util.h.
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#ifndef RTC_BASE_TEMPLATE_UTIL_H_
14#define RTC_BASE_TEMPLATE_UTIL_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020016#include <stddef.h> // For size_t.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020018namespace rtc {
19
20// Template definitions from tr1.
21
Yves Gerey665174f2018-06-19 15:03:05 +020022template <class T, T v>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020023struct integral_constant {
24 static const T value = v;
25 typedef T value_type;
26 typedef integral_constant<T, v> type;
27};
28
Yves Gerey665174f2018-06-19 15:03:05 +020029template <class T, T v>
30const T integral_constant<T, v>::value;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020031
32typedef integral_constant<bool, true> true_type;
33typedef integral_constant<bool, false> false_type;
34
Yves Gerey665174f2018-06-19 15:03:05 +020035template <class T>
36struct is_pointer : false_type {};
37template <class T>
38struct is_pointer<T*> : true_type {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020039
Yves Gerey665174f2018-06-19 15:03:05 +020040template <class T, class U>
41struct is_same : public false_type {};
42template <class T>
43struct is_same<T, T> : true_type {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020044
Yves Gerey665174f2018-06-19 15:03:05 +020045template <class>
46struct is_array : public false_type {};
47template <class T, size_t n>
48struct is_array<T[n]> : public true_type {};
49template <class T>
50struct is_array<T[]> : public true_type {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020051
Yves Gerey665174f2018-06-19 15:03:05 +020052template <class T>
53struct is_non_const_reference : false_type {};
54template <class T>
55struct is_non_const_reference<T&> : true_type {};
56template <class T>
57struct is_non_const_reference<const T&> : false_type {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020058
Yves Gerey665174f2018-06-19 15:03:05 +020059template <class T>
60struct is_void : false_type {};
61template <>
62struct is_void<void> : true_type {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020063
64// Helper useful for converting a tuple to variadic template function
65// arguments.
66//
67// sequence_generator<3>::type will be sequence<0, 1, 2>.
68template <int...>
69struct sequence {};
70template <int N, int... S>
71struct sequence_generator : sequence_generator<N - 1, N - 1, S...> {};
72template <int... S>
73struct sequence_generator<0, S...> {
74 typedef sequence<S...> type;
75};
76
77namespace internal {
78
79// Types YesType and NoType are guaranteed such that sizeof(YesType) <
80// sizeof(NoType).
81typedef char YesType;
82
83struct NoType {
84 YesType dummy[2];
85};
86
87// This class is an implementation detail for is_convertible, and you
88// don't need to know how it works to use is_convertible. For those
89// who care: we declare two different functions, one whose argument is
90// of type To and one with a variadic argument list. We give them
91// return types of different size, so we can use sizeof to trick the
92// compiler into telling us which function it would have chosen if we
93// had called it with an argument of type From. See Alexandrescu's
94// _Modern C++ Design_ for more details on this sort of trick.
95
96struct ConvertHelper {
97 template <typename To>
98 static YesType Test(To);
99
100 template <typename To>
101 static NoType Test(...);
102
103 template <typename From>
104 static From& Create();
105};
106
107// Used to determine if a type is a struct/union/class. Inspired by Boost's
108// is_class type_trait implementation.
109struct IsClassHelper {
110 template <typename C>
Yves Gerey665174f2018-06-19 15:03:05 +0200111 static YesType Test(void (C::*)(void));
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200112
113 template <typename C>
114 static NoType Test(...);
115};
116
117} // namespace internal
118
119// Inherits from true_type if From is convertible to To, false_type otherwise.
120//
121// Note that if the type is convertible, this will be a true_type REGARDLESS
122// of whether or not the conversion would emit a warning.
123template <typename From, typename To>
124struct is_convertible
125 : integral_constant<bool,
126 sizeof(internal::ConvertHelper::Test<To>(
Yves Gerey665174f2018-06-19 15:03:05 +0200127 internal::ConvertHelper::Create<From>())) ==
128 sizeof(internal::YesType)> {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200129
130template <typename T>
131struct is_class
132 : integral_constant<bool,
133 sizeof(internal::IsClassHelper::Test<T>(0)) ==
Yves Gerey665174f2018-06-19 15:03:05 +0200134 sizeof(internal::YesType)> {};
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200135
136} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000137
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200138#endif // RTC_BASE_TEMPLATE_UTIL_H_