1221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org/*
2221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *
4221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org */
10221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
11221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// Borrowed from Chromium's src/base/template_util.h.
12221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
13221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
14221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
15221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
16bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org#include <stddef.h>  // For size_t.
17221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
18221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgnamespace webrtc {
19221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
20221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// Template definitions from tr1.
21221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
22221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate<class T, T v>
23221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgstruct integral_constant {
24221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  static const T value = v;
25221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  typedef T value_type;
26221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  typedef integral_constant<T, v> type;
27221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org};
28221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
29221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T, T v> const T integral_constant<T, v>::value;
30221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
31221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtypedef integral_constant<bool, true> true_type;
32221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtypedef integral_constant<bool, false> false_type;
33221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
34221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_pointer : false_type {};
35221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_pointer<T*> : true_type {};
36221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
37221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T, class U> struct is_same : public false_type {};
38221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_same<T, T> : true_type {};
39221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
40221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate<class> struct is_array : public false_type {};
41221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate<class T, size_t n> struct is_array<T[n]> : public true_type {};
42221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate<class T> struct is_array<T[]> : public true_type {};
43221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
44221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_non_const_reference : false_type {};
45221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_non_const_reference<T&> : true_type {};
46221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_non_const_reference<const T&> : false_type {};
47221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
48221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <class T> struct is_void : false_type {};
49221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <> struct is_void<void> : true_type {};
50221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
51221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgnamespace internal {
52221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
53221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// Types YesType and NoType are guaranteed such that sizeof(YesType) <
54221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// sizeof(NoType).
55221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtypedef char YesType;
56221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
57221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgstruct NoType {
58221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  YesType dummy[2];
59221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org};
60221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
61221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// This class is an implementation detail for is_convertible, and you
62221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// don't need to know how it works to use is_convertible. For those
63221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// who care: we declare two different functions, one whose argument is
64221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// of type To and one with a variadic argument list. We give them
65221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// return types of different size, so we can use sizeof to trick the
66221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// compiler into telling us which function it would have chosen if we
67221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// had called it with an argument of type From.  See Alexandrescu's
68221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// _Modern C++ Design_ for more details on this sort of trick.
69221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
70221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgstruct ConvertHelper {
71221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  template <typename To>
72221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  static YesType Test(To);
73221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
74221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  template <typename To>
75221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  static NoType Test(...);
76221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
77221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  template <typename From>
78221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  static From& Create();
79221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org};
80221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
81221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// Used to determine if a type is a struct/union/class. Inspired by Boost's
82221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// is_class type_trait implementation.
83221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgstruct IsClassHelper {
84221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  template <typename C>
85221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  static YesType Test(void(C::*)(void));
86221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
87221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  template <typename C>
88221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org  static NoType Test(...);
89221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org};
90221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
91221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org}  // namespace internal
92221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
93221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// Inherits from true_type if From is convertible to To, false_type otherwise.
94221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org//
95221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// Note that if the type is convertible, this will be a true_type REGARDLESS
96221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org// of whether or not the conversion would emit a warning.
97221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <typename From, typename To>
98221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgstruct is_convertible
99221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org    : integral_constant<bool,
100221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org                        sizeof(internal::ConvertHelper::Test<To>(
101221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org                                   internal::ConvertHelper::Create<From>())) ==
102221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org                        sizeof(internal::YesType)> {
103221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org};
104221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
105221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgtemplate <typename T>
106221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.orgstruct is_class
107221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org    : integral_constant<bool,
108221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org                        sizeof(internal::IsClassHelper::Test<T>(0)) ==
109221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org                            sizeof(internal::YesType)> {
110221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org};
111221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
112221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org}  // namespace webrtc
113221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org
114221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
115