File indexing completed on 2024-04-28 05:46:50

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