1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
11// Borrowed from Chromium's src/base/macros.h.
12
13#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
14#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
15
16// The COMPILE_ASSERT macro can be used to verify that a compile time
17// expression is true. For example, you could use it to verify the
18// size of a static array:
19//
20//   COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES,
21//                  content_type_names_incorrect_size);
22//
23// or to make sure a struct is smaller than a certain size:
24//
25//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
26//
27// The second argument to the macro is the name of the variable. If
28// the expression is false, most compilers will issue a warning/error
29// containing the name of the variable.
30
31// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
32// libjingle are merged.
33#if !defined(COMPILE_ASSERT)
34#if __cplusplus >= 201103L
35// Under C++11, just use static_assert.
36#define COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
37
38#else
39template <bool>
40struct CompileAssert {
41};
42
43#define COMPILE_ASSERT(expr, msg) \
44  typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
45
46#endif  //  __cplusplus >= 201103L
47#endif  //  !defined(COMPILE_ASSERT)
48
49// Implementation details of COMPILE_ASSERT:
50//
51// - COMPILE_ASSERT works by defining an array type that has -1
52//   elements (and thus is invalid) when the expression is false.
53//
54// - The simpler definition
55//
56//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
57//
58//   does not work, as gcc supports variable-length arrays whose sizes
59//   are determined at run-time (this is gcc's extension and not part
60//   of the C++ standard).  As a result, gcc fails to reject the
61//   following code with the simple definition:
62//
63//     int foo;
64//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
65//                               // not a compile-time constant.
66//
67// - By using the type CompileAssert<(bool(expr))>, we ensures that
68//   expr is a compile-time constant.  (Template arguments must be
69//   determined at compile-time.)
70//
71// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
72//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
73//
74//     CompileAssert<bool(expr)>
75//
76//   instead, these compilers will refuse to compile
77//
78//     COMPILE_ASSERT(5 > 0, some_message);
79//
80//   (They seem to think the ">" in "5 > 0" marks the end of the
81//   template argument list.)
82//
83// - The array size is (bool(expr) ? 1 : -1), instead of simply
84//
85//     ((expr) ? 1 : -1).
86//
87//   This is to avoid running into a bug in MS VC 7.1, which
88//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
89
90#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
91