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