template_util.h revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2010 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 BASE_TEMPLATE_UTIL_H_
6#define BASE_TEMPLATE_UTIL_H_
7#pragma once
8
9#include "build/build_config.h"
10
11namespace base {
12
13// template definitions from tr1
14
15template<class T, T v>
16struct integral_constant {
17  static const T value = v;
18  typedef T value_type;
19  typedef integral_constant<T, v> type;
20};
21
22template <class T, T v> const T integral_constant<T, v>::value;
23
24typedef integral_constant<bool, true> true_type;
25typedef integral_constant<bool, false> false_type;
26
27template <class T> struct is_pointer : false_type {};
28template <class T> struct is_pointer<T*> : true_type {};
29
30namespace internal {
31
32// Types small_ and big_ are guaranteed such that sizeof(small_) <
33// sizeof(big_)
34typedef char small_;
35
36struct big_ {
37  small_ dummy[2];
38};
39
40#if !defined(OS_WIN)
41
42// This class is an implementation detail for is_convertible, and you
43// don't need to know how it works to use is_convertible. For those
44// who care: we declare two different functions, one whose argument is
45// of type To and one with a variadic argument list. We give them
46// return types of different size, so we can use sizeof to trick the
47// compiler into telling us which function it would have chosen if we
48// had called it with an argument of type From.  See Alexandrescu's
49// _Modern C++ Design_ for more details on this sort of trick.
50
51template <typename From, typename To>
52struct ConvertHelper {
53  static small_ Test(To);
54  static big_ Test(...);
55  static From Create();
56};
57
58#endif  // !defined(OS_WIN)
59
60}  // namespace internal
61
62#if !defined(OS_WIN)
63
64// Inherits from true_type if From is convertible to To, false_type otherwise.
65template <typename From, typename To>
66struct is_convertible
67    : integral_constant<bool,
68                        sizeof(internal::ConvertHelper<From, To>::Test(
69                                  internal::ConvertHelper<From, To>::Create()))
70                        == sizeof(internal::small_)> {
71};
72
73#endif  // !defined(OS_WIN)
74
75}  // namespace base
76
77#endif  // BASE_TEMPLATE_UTIL_H_
78