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