macros.h revision af69d88d
1af69d88dSmrg/*
2af69d88dSmrg * Copyright © 2014 Intel Corporation
3af69d88dSmrg *
4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5af69d88dSmrg * copy of this software and associated documentation files (the "Software"),
6af69d88dSmrg * to deal in the Software without restriction, including without limitation
7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9af69d88dSmrg * Software is furnished to do so, subject to the following conditions:
10af69d88dSmrg *
11af69d88dSmrg * The above copyright notice and this permission notice (including the next
12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the
13af69d88dSmrg * Software.
14af69d88dSmrg *
15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21af69d88dSmrg * IN THE SOFTWARE.
22af69d88dSmrg */
23af69d88dSmrg
24af69d88dSmrg#ifndef UTIL_MACROS_H
25af69d88dSmrg#define UTIL_MACROS_H
26af69d88dSmrg
27af69d88dSmrg/* Compute the size of an array */
28af69d88dSmrg#ifndef ARRAY_SIZE
29af69d88dSmrg#  define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
30af69d88dSmrg#endif
31af69d88dSmrg
32af69d88dSmrg
33af69d88dSmrg/**
34af69d88dSmrg * __builtin_expect macros
35af69d88dSmrg */
36af69d88dSmrg#if !defined(__GNUC__)
37af69d88dSmrg#  define __builtin_expect(x, y) (x)
38af69d88dSmrg#endif
39af69d88dSmrg
40af69d88dSmrg#ifndef likely
41af69d88dSmrg#  ifdef __GNUC__
42af69d88dSmrg#    define likely(x)   __builtin_expect(!!(x), 1)
43af69d88dSmrg#    define unlikely(x) __builtin_expect(!!(x), 0)
44af69d88dSmrg#  else
45af69d88dSmrg#    define likely(x)   (x)
46af69d88dSmrg#    define unlikely(x) (x)
47af69d88dSmrg#  endif
48af69d88dSmrg#endif
49af69d88dSmrg
50af69d88dSmrg
51af69d88dSmrg/**
52af69d88dSmrg * Static (compile-time) assertion.
53af69d88dSmrg * Basically, use COND to dimension an array.  If COND is false/zero the
54af69d88dSmrg * array size will be -1 and we'll get a compilation error.
55af69d88dSmrg */
56af69d88dSmrg#define STATIC_ASSERT(COND) \
57af69d88dSmrg   do { \
58af69d88dSmrg      (void) sizeof(char [1 - 2*!(COND)]); \
59af69d88dSmrg   } while (0)
60af69d88dSmrg
61af69d88dSmrg
62af69d88dSmrg/**
63af69d88dSmrg * Unreachable macro. Useful for suppressing "control reaches end of non-void
64af69d88dSmrg * function" warnings.
65af69d88dSmrg */
66af69d88dSmrg#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
67af69d88dSmrg#define unreachable(str)    \
68af69d88dSmrgdo {                        \
69af69d88dSmrg   assert(!str);            \
70af69d88dSmrg   __builtin_unreachable(); \
71af69d88dSmrg} while (0)
72af69d88dSmrg#elif (defined(__clang__) && defined(__has_builtin))
73af69d88dSmrg# if __has_builtin(__builtin_unreachable)
74af69d88dSmrg#  define unreachable(str)  \
75af69d88dSmrgdo {                        \
76af69d88dSmrg   assert(!str);            \
77af69d88dSmrg   __builtin_unreachable(); \
78af69d88dSmrg} while (0)
79af69d88dSmrg# endif
80af69d88dSmrg#endif
81af69d88dSmrg
82af69d88dSmrg#ifndef unreachable
83af69d88dSmrg#define unreachable(str)
84af69d88dSmrg#endif
85af69d88dSmrg
86af69d88dSmrg
87af69d88dSmrg#if (__GNUC__ >= 3)
88af69d88dSmrg#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
89af69d88dSmrg#else
90af69d88dSmrg#define PRINTFLIKE(f, a)
91af69d88dSmrg#endif
92af69d88dSmrg
93af69d88dSmrg
94af69d88dSmrg/* Used to optionally mark structures with misaligned elements or size as
95af69d88dSmrg * packed, to trade off performance for space.
96af69d88dSmrg */
97af69d88dSmrg#if (__GNUC__ >= 3)
98af69d88dSmrg#define PACKED __attribute__((__packed__))
99af69d88dSmrg#else
100af69d88dSmrg#define PACKED
101af69d88dSmrg#endif
102af69d88dSmrg
103af69d88dSmrg
104af69d88dSmrg#ifdef __cplusplus
105af69d88dSmrg/**
106af69d88dSmrg * Macro function that evaluates to true if T is a trivially
107af69d88dSmrg * destructible type -- that is, if its (non-virtual) destructor
108af69d88dSmrg * performs no action and all member variables and base classes are
109af69d88dSmrg * trivially destructible themselves.
110af69d88dSmrg */
111af69d88dSmrg#   if defined(__GNUC__)
112af69d88dSmrg#      if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
113af69d88dSmrg#         define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
114af69d88dSmrg#      endif
115af69d88dSmrg#   elif (defined(__clang__) && defined(__has_feature))
116af69d88dSmrg#      if __has_feature(has_trivial_destructor)
117af69d88dSmrg#         define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
118af69d88dSmrg#      endif
119af69d88dSmrg#   endif
120af69d88dSmrg#   ifndef HAS_TRIVIAL_DESTRUCTOR
121af69d88dSmrg       /* It's always safe (if inefficient) to assume that a
122af69d88dSmrg        * destructor is non-trivial.
123af69d88dSmrg        */
124af69d88dSmrg#      define HAS_TRIVIAL_DESTRUCTOR(T) (false)
125af69d88dSmrg#   endif
126af69d88dSmrg#endif
127af69d88dSmrg
128af69d88dSmrg#endif /* UTIL_MACROS_H */
129