blob: cdeaa5676bb5c1815b14959d2ad67d1d5b41cdb7 [file] [log] [blame]
tommi@webrtc.org98ad0ff2012-04-10 11:53:07 +00001/*
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
andrew@webrtc.org31628aa2013-10-22 12:50:00 +000011// Borrowed from Chromium's src/base/basictypes.h.
12
tommi@webrtc.org98ad0ff2012-04-10 11:53:07 +000013#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
14#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
15
andrew@webrtc.org31628aa2013-10-22 12:50:00 +000016// 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
andrew@webrtc.orgd1bcf112013-10-23 19:11:32 +000031// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
32// libjingle are merged.
33#if !defined(COMPILE_ASSERT)
andrew@webrtc.org31628aa2013-10-22 12:50:00 +000034template <bool>
35struct CompileAssert {
36};
37
andrew@webrtc.org31628aa2013-10-22 12:50:00 +000038#define COMPILE_ASSERT(expr, msg) \
39 typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
andrew@webrtc.orgd1bcf112013-10-23 19:11:32 +000040#endif // COMPILE_ASSERT
andrew@webrtc.org31628aa2013-10-22 12:50:00 +000041
42// Implementation details of COMPILE_ASSERT:
43//
44// - COMPILE_ASSERT works by defining an array type that has -1
45// elements (and thus is invalid) when the expression is false.
46//
47// - The simpler definition
48//
49// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
50//
51// does not work, as gcc supports variable-length arrays whose sizes
52// are determined at run-time (this is gcc's extension and not part
53// of the C++ standard). As a result, gcc fails to reject the
54// following code with the simple definition:
55//
56// int foo;
57// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
58// // not a compile-time constant.
59//
60// - By using the type CompileAssert<(bool(expr))>, we ensures that
61// expr is a compile-time constant. (Template arguments must be
62// determined at compile-time.)
63//
64// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
65// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
66//
67// CompileAssert<bool(expr)>
68//
69// instead, these compilers will refuse to compile
70//
71// COMPILE_ASSERT(5 > 0, some_message);
72//
73// (They seem to think the ">" in "5 > 0" marks the end of the
74// template argument list.)
75//
76// - The array size is (bool(expr) ? 1 : -1), instead of simply
77//
78// ((expr) ? 1 : -1).
79//
80// This is to avoid running into a bug in MS VC 7.1, which
81// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
tommi@webrtc.org98ad0ff2012-04-10 11:53:07 +000082
83#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_