Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __RAPICORN_CXXAUX_HH__ 00003 #define __RAPICORN_CXXAUX_HH__ 00004 00005 #include <rcore/rapicornconfig.h> // _GNU_SOURCE 00006 #include <stdbool.h> 00007 #include <stdarg.h> 00008 #include <stddef.h> // NULL 00009 #include <sys/types.h> // uint, ssize 00010 #include <stdint.h> // uint64_t 00011 #include <limits.h> // {INT|CHAR|...}_{MIN|MAX} 00012 #include <float.h> // {FLT|DBL}_{MIN|MAX|EPSILON} 00013 #include <string> 00014 #include <vector> 00015 #include <map> 00016 00017 // == Standard Macros == 00018 #ifndef FALSE 00019 # define FALSE false 00020 #endif 00021 #ifndef TRUE 00022 # define TRUE true 00023 #endif 00024 #define RAPICORN_ABS(a) ((a) < 0 ? -(a) : (a)) 00025 #define RAPICORN_MIN(a,b) ((a) <= (b) ? (a) : (b)) 00026 #define RAPICORN_MAX(a,b) ((a) >= (b) ? (a) : (b)) 00027 #define RAPICORN_CLAMP(v,mi,ma) ((v) < (mi) ? (mi) : ((v) > (ma) ? (ma) : (v))) 00028 #define RAPICORN_ARRAY_SIZE(array) (sizeof (array) / sizeof ((array)[0])) 00029 #undef ABS 00030 #define ABS RAPICORN_ABS 00031 #undef MIN 00032 #define MIN RAPICORN_MIN 00033 #undef MAX 00034 #define MAX RAPICORN_MAX 00035 #undef CLAMP 00036 #define CLAMP RAPICORN_CLAMP 00037 #undef ARRAY_SIZE 00038 #define ARRAY_SIZE RAPICORN_ARRAY_SIZE 00039 #undef EXTERN_C 00040 #ifdef __cplusplus 00041 #define EXTERN_C extern "C" 00042 #else 00043 #define EXTERN_C extern 00044 #endif 00045 #undef STRFUNC 00046 #define STRFUNC RAPICORN_SIMPLE_FUNCTION 00047 #if !defined (INT64_MAX) || !defined (INT64_MIN) || !defined (UINT64_MAX) 00048 #ifdef LLONG_MAX // some gcc versions ship limits.h that fail to define LLONG_MAX for C99 00049 # define INT64_MAX LLONG_MAX // +9223372036854775807LL 00050 # define INT64_MIN LLONG_MIN // -9223372036854775808LL 00051 # define UINT64_MAX ULLONG_MAX // +18446744073709551615LLU 00052 #else // !LLONG_MAX but gcc always has __LONG_LONG_MAX__ 00053 # define INT64_MAX __LONG_LONG_MAX__ 00054 # define INT64_MIN (-INT64_MAX - 1LL) 00055 # define UINT64_MAX (INT64_MAX * 2ULL + 1ULL) 00056 #endif 00057 #endif 00058 #ifndef SIZE_T_MAX 00059 #define SIZE_T_MAX (~size_t (0)) 00060 #define SSIZE_T_MAX (ssize_t (SIZE_T_MAX / 2)) 00061 #endif 00062 00063 // == Likelyness Hinting == 00064 #define RAPICORN__BOOL(expr) __extension__ ({ bool _rapicorn__bool; if (expr) _rapicorn__bool = 1; else _rapicorn__bool = 0; _rapicorn__bool; }) 00065 #define RAPICORN_ISLIKELY(expr) __builtin_expect (RAPICORN__BOOL (expr), 1) 00066 #define RAPICORN_UNLIKELY(expr) __builtin_expect (RAPICORN__BOOL (expr), 0) 00067 #define RAPICORN_LIKELY RAPICORN_ISLIKELY 00068 00069 // == Convenience Macros == 00070 #ifdef RAPICORN_CONVENIENCE 00071 #define ISLIKELY RAPICORN_ISLIKELY ///< Compiler hint that @a expression is likely to be true. 00072 #define UNLIKELY RAPICORN_UNLIKELY ///< Compiler hint that @a expression is unlikely to be true. 00073 #define LIKELY RAPICORN_LIKELY ///< Compiler hint that @a expression is likely to be true. 00074 #define STRINGIFY RAPICORN_CPP_STRINGIFY ///< Produces a const char C string from the macro @a argument. 00075 #endif 00076 00083 #ifdef DOXYGEN 00084 # define RAPICORN_CONVENIENCE 00085 #endif // DOXYGEN 00086 00087 // == Preprocessor Convenience == 00088 #define RAPICORN_CPP_PASTE2_(a,b) a ## b // indirection required to expand macros like __LINE__ 00089 #define RAPICORN_CPP_PASTE2(a,b) RAPICORN_CPP_PASTE2_ (a,b) 00090 #define RAPICORN_CPP_STRINGIFY_(s) #s // indirection required to expand macros like __LINE__ 00091 #define RAPICORN_CPP_STRINGIFY(s) RAPICORN_CPP_STRINGIFY_ (s) 00092 #define RAPICORN_STATIC_ASSERT(expr) static_assert (expr, #expr) ///< Shorthand for static_assert (condition, "condition") 00093 00094 // == GCC Attributes == 00095 #if __GNUC__ >= 4 00096 #define RAPICORN_PURE __attribute__ ((__pure__)) 00097 #define RAPICORN_MALLOC __attribute__ ((__malloc__)) 00098 #define RAPICORN_PRINTF(format_idx, arg_idx) __attribute__ ((__format__ (__printf__, format_idx, arg_idx))) 00099 #define RAPICORN_SCANF(format_idx, arg_idx) __attribute__ ((__format__ (__scanf__, format_idx, arg_idx))) 00100 #define RAPICORN_FORMAT(arg_idx) __attribute__ ((__format_arg__ (arg_idx))) 00101 #define RAPICORN_SENTINEL __attribute__ ((__sentinel__)) 00102 #define RAPICORN_NORETURN __attribute__ ((__noreturn__)) 00103 #define RAPICORN_CONST __attribute__ ((__const__)) 00104 #define RAPICORN_UNUSED __attribute__ ((__unused__)) 00105 #define RAPICORN_NO_INSTRUMENT __attribute__ ((__no_instrument_function__)) 00106 #define RAPICORN_DEPRECATED __attribute__ ((__deprecated__)) 00107 #define RAPICORN_ALWAYS_INLINE __attribute__ ((always_inline)) 00108 #define RAPICORN_NOINLINE __attribute__ ((noinline)) 00109 #define RAPICORN_CONSTRUCTOR __attribute__ ((constructor,used)) // gcc-3.3 also needs "used" to emit code 00110 #define RAPICORN_MAY_ALIAS __attribute__ ((may_alias)) 00111 #define RAPICORN_SIMPLE_FUNCTION (::Rapicorn::string_from_pretty_function_name (__PRETTY_FUNCTION__).c_str()) 00112 #else // !__GNUC__ 00113 #define RAPICORN_PURE 00114 #define RAPICORN_MALLOC 00115 #define RAPICORN_PRINTF(format_idx, arg_idx) 00116 #define RAPICORN_SCANF(format_idx, arg_idx) 00117 #define RAPICORN_FORMAT(arg_idx) 00118 #define RAPICORN_SENTINEL 00119 #define RAPICORN_NORETURN 00120 #define RAPICORN_CONST 00121 #define RAPICORN_UNUSED 00122 #define RAPICORN_NO_INSTRUMENT 00123 #define RAPICORN_DEPRECATED 00124 #define RAPICORN_ALWAYS_INLINE 00125 #define RAPICORN_NOINLINE 00126 #define RAPICORN_CONSTRUCTOR 00127 #define RAPICORN_MAY_ALIAS 00128 #define RAPICORN_SIMPLE_FUNCTION (__func__) 00129 #error Failed to detect a recent GCC version (>= 4) 00130 #endif // !__GNUC__ 00131 00132 // == C++11 Keywords == 00133 #if __GNUC__ == 4 && __GNUC_MINOR__ < 7 00134 #define override /* unimplemented */ 00135 #define final /* unimplemented */ 00136 #endif // GCC < 4.7 00137 00138 // == Ensure 'uint' in global namespace == 00139 #if RAPICORN_SIZEOF_SYS_TYPESH_UINT == 0 00140 typedef unsigned int uint; // for systems that don't define uint in sys/types.h 00141 #else 00142 RAPICORN_STATIC_ASSERT (RAPICORN_SIZEOF_SYS_TYPESH_UINT == 4); 00143 #endif 00144 RAPICORN_STATIC_ASSERT (sizeof (uint) == 4); 00145 00146 // == Rapicorn Namespace == 00147 namespace Rapicorn { 00148 00149 // == Provide Canonical Integer Types == 00150 typedef uint8_t uint8; 00151 typedef uint16_t uint16; 00152 typedef uint32_t uint32; 00153 typedef uint64_t uint64; 00154 typedef int8_t int8; 00155 typedef int16_t int16; 00156 typedef int32_t int32; 00157 typedef int64_t int64; 00158 typedef uint32_t unichar; 00159 RAPICORN_STATIC_ASSERT (sizeof (uint8) == 1 && sizeof (uint16) == 2 && sizeof (uint32) == 4 && sizeof (uint64) == 8); 00160 RAPICORN_STATIC_ASSERT (sizeof (int8) == 1 && sizeof (int16) == 2 && sizeof (int32) == 4 && sizeof (int64) == 8); 00161 RAPICORN_STATIC_ASSERT (sizeof (int) == 4 && sizeof (uint) == 4 && sizeof (unichar) == 4); 00162 00164 00173 #if __SIZEOF_LONG__ == 8 // 64bit 00174 typedef long long signed int LongIffy; 00175 typedef long long unsigned int ULongIffy; 00176 typedef int64_t CastIffy; 00177 typedef uint64_t UCastIffy; 00178 static_assert (__SIZEOF_LONG_LONG__ == 8, "__SIZEOF_LONG_LONG__"); 00179 static_assert (__SIZEOF_INT__ == 4, "__SIZEOF_INT__"); 00180 #elif __SIZEOF_LONG__ == 4 // 32bit 00181 typedef long signed int LongIffy; 00182 typedef long unsigned int ULongIffy; 00183 typedef int32_t CastIffy; 00184 typedef uint32_t UCastIffy; 00185 static_assert (__SIZEOF_LONG_LONG__ == 8, "__SIZEOF_LONG_LONG__"); 00186 static_assert (__SIZEOF_INT__ == 4, "__SIZEOF_INT__"); 00187 #else 00188 #error "Unknown long size:" __SIZEOF_LONG__ 00189 #endif 00190 static_assert (sizeof (CastIffy) == sizeof (LongIffy), "CastIffy == LongIffy"); 00191 static_assert (sizeof (UCastIffy) == sizeof (ULongIffy), "UCastIffy == ULongIffy"); 00193 00194 // == Convenient stdc++ Types == 00195 using std::map; 00196 using std::vector; 00197 typedef std::string String; 00198 typedef vector<String> StringVector; 00199 00200 // == File Path Handling == 00201 #ifdef _WIN32 00202 #define RAPICORN_DIR_SEPARATOR '\\' 00203 #define RAPICORN_DIR_SEPARATOR_S "\\" 00204 #define RAPICORN_SEARCHPATH_SEPARATOR ';' 00205 #define RAPICORN_SEARCHPATH_SEPARATOR_S ";" 00206 #define RAPICORN_IS_ABSPATH(p) (((p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z')) && p[1] == ':' && p[2] == '\\') 00207 #else // !_WIN32 00208 #define RAPICORN_DIR_SEPARATOR '/' 00209 #define RAPICORN_DIR_SEPARATOR_S "/" 00210 #define RAPICORN_SEARCHPATH_SEPARATOR ':' 00211 #define RAPICORN_SEARCHPATH_SEPARATOR_S ":" 00212 #define RAPICORN_IS_ABSPATH(p) (p[0] == RAPICORN_DIR_SEPARATOR) 00213 #endif // !_WIN32 00214 00215 // == C++ Macros == 00216 #define RAPICORN_CLASS_NON_COPYABLE(ClassName) private: \ 00217 /*copy-ctor*/ ClassName (const ClassName&) __attribute__ ((error ("NON_COPYABLE"))) = delete; \ 00218 ClassName& operator= (const ClassName&) __attribute__ ((error ("NON_COPYABLE"))) = delete 00219 00220 // == C++ Helper Classes == 00222 struct Init { 00223 explicit Init (void (*f) ()) { f(); } 00224 }; 00225 00226 } // Rapicorn 00227 00228 #endif // __RAPICORN_CXXAUX_HH__