File indexing completed on 2024-05-19 13:35:40
0001 /***************************************************************************** 0002 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU Lesser General Public License as * 0006 * published by the Free Software Foundation; either version 2.1 of the * 0007 * License, or (at your option) version 3, or any later version accepted * 0008 * by the membership of KDE e.V. (or its successor approved by the * 0009 * membership of KDE e.V.), which shall act as a proxy defined in * 0010 * Section 6 of version 3 of the license. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0015 * Lesser General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU Lesser General Public * 0018 * License along with this library. If not, * 0019 * see <http://www.gnu.org/licenses/>. * 0020 *****************************************************************************/ 0021 0022 #ifndef _QTC_UTILS_MACROS_H_ 0023 #define _QTC_UTILS_MACROS_H_ 0024 0025 /** 0026 * \file macros.h 0027 * \author Yichao Yu <yyc1992@gmail.com> 0028 * \brief Definitions of some useful macros. 0029 */ 0030 0031 /** \defgroup qtc_switch Macros for detecting empty arguments 0032 * \brief Used to implement function overloading and default arguments in c. 0033 * 0034 * The idea of this implementation is borrowed from the following 0035 * [post](https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments) 0036 * and is modified in order to fit with our usage. 0037 * @{ 0038 */ 0039 0040 #define __QTC_USE_3(_1, _2, _3, ...) _3 0041 // Test if args has one comma 0042 #define __QTC_HAS_COMMA1(ret_true, ret_false, args...) \ 0043 __QTC_USE_3(args, ret_true, ret_false) 0044 // Convert parentheses to comma, used to check if the next character is "(" 0045 #define __QTC_CONVERT_PAREN(...) , 0046 // Check if arg starts with "(" 0047 #define __QTC_IS_PAREN_(ret_true, ret_false, arg) \ 0048 __QTC_HAS_COMMA1(ret_true, ret_false, __QTC_CONVERT_PAREN arg) 0049 // Extra layer just to make sure more evaluation (if any) is done than the 0050 // separator path. 0051 #define __QTC_IS_PAREN(ret_true, ret_false, arg) \ 0052 __QTC_IS_PAREN_(ret_true, ret_false, arg) 0053 // Check if arg is not empty and does not start with "(" 0054 // Will not work if arg has comma or is the name of a function like macro 0055 #define __QTC_IS_SEP(ret_true, ret_false, arg) \ 0056 __QTC_HAS_COMMA1(ret_false, ret_true, __QTC_CONVERT_PAREN arg()) 0057 #define __QTC_IS_EMPTY_PAREN_TRUE(ret_true, ret_false, arg) ret_false 0058 #define __QTC_IS_EMPTY_PAREN_FALSE(ret_true, ret_false, arg) \ 0059 __QTC_IS_SEP(ret_false, ret_true, arg) 0060 0061 /** 0062 * \brief Test if \param arg is empty. 0063 * Evaluate to \param ret_true if it is not empty, 0064 * evaluate to \param ret_false otherwise. 0065 * 0066 * NOTE: this may not work if \param arg is a macro that can be evaluated to a 0067 * comma separate list without parentheses or is the name of 0068 * a function like macro. 0069 */ 0070 #define QTC_SWITCH(arg, ret_true, ret_false) \ 0071 __QTC_IS_PAREN(__QTC_IS_EMPTY_PAREN_TRUE, __QTC_IS_EMPTY_PAREN_FALSE, arg) \ 0072 (ret_false, ret_true, arg) 0073 /** 0074 * Evaluate to \param def if \param v is empty and to \param v otherwise. 0075 * \sa QTC_SWITCH for restrictions. 0076 **/ 0077 #define QTC_DEFAULT(v, def) QTC_SWITCH(v, v, def) 0078 0079 /** @} */ 0080 0081 #define qtcMakeVersion(a, b, c...) \ 0082 ((a) << 16 | (b) << 8 | (QTC_DEFAULT(c, 0))) 0083 #ifdef __GNUC__ 0084 # define QTC_GCC_VERSION \ 0085 qtcMakeVersion(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) 0086 #else 0087 # define QTC_GCC_VERSION 0 0088 #endif 0089 #define QTC_CHECK_GCC_VERSION(args...) \ 0090 (QTC_GCC_VERSION >= qtcMakeVersion(args)) 0091 0092 /** 0093 * \brief Export symbol. 0094 */ 0095 #define QTC_EXPORT __attribute__((visibility("default"))) 0096 0097 /** 0098 * \def QTC_BEGIN_DECLS 0099 * \brief start declaring c-linked functions. 0100 */ 0101 /** 0102 * \def QTC_END_DECLS 0103 * \brief end declaring c-linked functions. 0104 */ 0105 // For public c headers 0106 #ifdef __cplusplus 0107 # define QTC_BEGIN_DECLS extern "C" { 0108 # define QTC_END_DECLS } 0109 #else 0110 # define QTC_BEGIN_DECLS 0111 # define QTC_END_DECLS 0112 #endif 0113 0114 /** 0115 * \brief always inline the function. 0116 * 0117 * Should only be used for small functions 0118 */ 0119 #define QTC_ALWAYS_INLINE __attribute__((always_inline)) 0120 0121 /** 0122 * Suppress unused parameter warning on variable \param x. 0123 */ 0124 #define QTC_UNUSED(x) ((void)(x)) 0125 0126 /** 0127 * cast the \param member pointer \param ptr of a structure \param type to 0128 * the containing structure. 0129 */ 0130 #define qtcContainerOf(ptr, type, member) \ 0131 ((type*)(((char*)(ptr)) - offsetof(type, member))) 0132 0133 /** 0134 * Tell the compiler that \param exp is likely to be \param var. 0135 */ 0136 #if QTC_CHECK_GCC_VERSION(3, 0) 0137 # define qtcExpect(exp, var) __builtin_expect(exp, var) 0138 #else 0139 # define qtcExpect(exp, var) (exp) 0140 #endif 0141 0142 /** 0143 * Tell the compiler that \param x is likely to be true. 0144 */ 0145 #define qtcLikely(x) qtcExpect(!!(x), 1) 0146 0147 /** 0148 * Tell the compiler that \param x is likely to be false. 0149 */ 0150 #define qtcUnlikely(x) qtcExpect(!!(x), 0) 0151 0152 #endif