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