1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CHPP_MACROS_H_ 18 #define CHPP_MACROS_H_ 19 20 #include <assert.h> 21 #include <inttypes.h> 22 #include <stddef.h> 23 #include <stdlib.h> 24 25 #include "chpp/memory.h" 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 #define MOST_SIGNIFICANT_NIBBLE 0xf0 32 #define LEAST_SIGNIFICANT_NIBBLE 0x0f 33 34 #ifndef UNUSED_VAR 35 #define UNUSED_VAR(var) ((void)(var)) 36 #endif 37 38 #ifndef MIN 39 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 40 #endif 41 42 #ifndef MAX 43 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 44 #endif 45 46 #ifndef ARRAY_SIZE 47 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) 48 #endif 49 50 #ifndef CHPP_ASSERT 51 #define CHPP_ASSERT(var) assert(var) 52 #endif 53 54 #ifndef CHPP_ASSERT_LOG 55 #define CHPP_ASSERT_LOG(var, fmt, ...) \ 56 do { \ 57 if (!(var)) { \ 58 CHPP_LOGE(fmt, ##__VA_ARGS__); \ 59 CHPP_ASSERT(false); \ 60 } \ 61 } while (0) 62 #endif 63 64 #ifndef CHPP_NOT_NULL 65 #define CHPP_NOT_NULL(var) CHPP_ASSERT((var) != NULL) 66 #endif 67 68 /** 69 * Debug assertions that are not intended to be enabled for production software. 70 */ 71 #ifndef CHPP_DEBUG_ASSERT 72 #ifdef CHPP_DEBUG_ASSERT_ENABLED 73 #define CHPP_DEBUG_ASSERT(var) CHPP_ASSERT(var) 74 #else 75 #define CHPP_DEBUG_ASSERT(var) UNUSED_VAR(var) 76 #endif // CHPP_DEBUG_ASSERT_ENABLED 77 #endif // CHPP_DEBUG_ASSERT 78 79 #ifndef CHPP_DEBUG_NOT_NULL 80 #define CHPP_DEBUG_NOT_NULL(var) CHPP_DEBUG_ASSERT((var) != NULL) 81 #endif 82 83 #ifndef CHPP_DEBUG_ASSERT_LOG 84 #define CHPP_DEBUG_ASSERT_LOG(var, fmt, ...) \ 85 do { \ 86 if (!(var)) { \ 87 CHPP_LOGE(fmt, ##__VA_ARGS__); \ 88 CHPP_DEBUG_ASSERT(false); \ 89 } \ 90 } while (0) 91 #endif 92 93 #ifndef PRIu64 // Pre-C99 lacks PRIu64 support. Note that the correct 94 // definition on pre-C99 systems would be compiler-dependent. 95 #define PRIu64 "llu" 96 #endif 97 98 #if (defined(__cpp_static_assert) && (__cpp_static_assert >= 200410)) || \ 99 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) 100 #define CHPP_STATIC_ASSERT static_assert 101 102 #else // Use fallback implementation as static_assert is not available. 103 #define CHPP_STATIC_ASSERT4(cond, var) typedef char var[(!!(cond)) * 2 - 1] 104 #define CHPP_STATIC_ASSERT3(cond, line) \ 105 CHPP_STATIC_ASSERT4(cond, static_assertion_at_line_##line) 106 #define CHPP_STATIC_ASSERT2(cond, line) CHPP_STATIC_ASSERT3(cond, line) 107 #define CHPP_STATIC_ASSERT(cond, msg) CHPP_STATIC_ASSERT2(cond, __LINE__) 108 109 #endif // Use C11 or C++11 static_assert 110 111 // Time-related macros 112 #define CHPP_TIME_NONE 0 113 #define CHPP_TIME_MAX UINT64_MAX 114 #define CHPP_MSEC_PER_SEC UINT64_C(1000) 115 #define CHPP_USEC_PER_MSEC UINT64_C(1000) 116 #define CHPP_NSEC_PER_USEC UINT64_C(1000) 117 #define CHPP_USEC_PER_SEC (CHPP_USEC_PER_MSEC * CHPP_MSEC_PER_SEC) 118 #define CHPP_NSEC_PER_MSEC (CHPP_NSEC_PER_USEC * CHPP_USEC_PER_MSEC) 119 #define CHPP_NSEC_PER_SEC \ 120 (CHPP_NSEC_PER_USEC * CHPP_USEC_PER_MSEC * CHPP_MSEC_PER_SEC) 121 #define CHPP_NSEC_PER_MINUTE (CHPP_NSEC_PER_SEC * 60) 122 #define CHPP_NSEC_PER_HOUR (CHPP_NSEC_PER_MINUTE * 60) 123 124 #if defined(__GNUC__) || defined(__clang__) 125 #define check_types_match(t1, t2) ((__typeof__(t1) *)0 != (__typeof__(t2) *)0) 126 #else 127 #define check_types_match(t1, t2) 0 128 #endif 129 130 #define container_of(ptr, type, member) \ 131 ((type *)(void *)((char *)(ptr)-offsetof(type, member)) + \ 132 check_types_match(*(ptr), ((type *)0)->member)) 133 134 #define sizeof_member(type, member) (sizeof(((type *)0)->member)) 135 136 /** 137 * Macros for defining (compiler dependent) packed structures 138 */ 139 #if defined(__GNUC__) || defined(__clang__) 140 // For GCC and clang 141 #define CHPP_PACKED_START 142 #define CHPP_PACKED_END 143 #define CHPP_PACKED_ATTR __attribute__((packed)) 144 145 #elif defined(__ICCARM__) || defined(__CC_ARM) 146 // For IAR ARM and Keil MDK-ARM compilers 147 #define CHPP_PACKED_START _Pragma("pack(push, 1)") 148 #define CHPP_PACKED_END _Pragma("pack(pop)") 149 #define CHPP_PACKED_ATTR 150 151 #elif defined(_MSC_VER) 152 // For Microsoft Visual Studio 153 #define CHPP_PACKED_START __pragma(pack(push, 1)) 154 #define CHPP_PACKED_END __pragma(pack(pop)) 155 #define CHPP_PACKED_ATTR 156 157 #else 158 // Unknown compiler 159 #error Unrecognized compiler 160 #endif 161 162 #define CHPP_FREE_AND_NULLIFY(p) \ 163 do { \ 164 chppFree(p); \ 165 (p) = NULL; \ 166 } while (0) 167 168 //! Cast a const pointer to a non-const. This is necessary for removing const 169 //! with the -Wcast-qual compiler flag. 170 #define CHPP_CONST_CAST_POINTER(p) (void *)(intptr_t)(p) 171 172 #ifdef __cplusplus 173 } 174 #endif 175 176 #endif // CHPP_MACROS_H_ 177