00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef P99_ENUM_H_
00014 # define P99_ENUM_H_
00015
00016 #include "p99_for.h"
00017
00023 #define P00_ENUM_CASE(X) case X: return P99_STRINGIFY(X)
00024
00025 #define P00_ENUM_PARSE(C) \
00026 if (!memcmp(P99_STRINGIFY(C), p00_s, p00_len)) { \
00027 ++p00_c; \
00028 p00_ret = C; \
00029 }
00030
00031
00032
00033 #ifdef P00_DOXYGEN
00034
00038 #define P99_DECLARE_ENUM_GETNAME(T, ...) \
00039 \
00040 inline char const* P99_PASTE2(T, _getname)(T p00_x)
00041
00045 #define P99_DECLARE_ENUM_PARSE(T, ...) \
00046 \
00047 inline T P99_PASTE2(T, _parse)(char const* p00_s)
00048 #else
00049 P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 0)
00050 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 1)
00051 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 2)
00052 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 3)
00053 #define P99_DECLARE_ENUM_GETNAME(T, ...) \
00054 p99_inline \
00055 char const* P99_PASTE2(T, _getname)(T p00_x) { \
00056 switch ((uintmax_t)p00_x) { \
00057 P99_SEP(P00_ENUM_CASE, __VA_ARGS__); \
00058 default: return "((" #T ")unknown value)"; \
00059 } \
00060 } \
00061 P99_MACRO_END(declare_enum_getname, T)
00062
00063 P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_ENUM_PARSE, 0)
00064 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_PARSE, 1)
00065 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_PARSE, 2)
00066 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_PARSE, 3)
00067 #define P99_DECLARE_ENUM_PARSE(T, ...) \
00068 p99_inline \
00069 T P99_PASTE2(T, _parse)(char const p00_s[]) { \
00070 T p00_ret = P99_PASTE2(T, _amount); \
00071 if (p00_s) { \
00072 size_t p00_c = 0; \
00073 size_t const p00_len = strlen(p00_s); \
00074 P99_SEP(P00_ENUM_PARSE, __VA_ARGS__); \
00075 if (p00_c > 1) p00_ret = P99_PASTE2(T, _amount); \
00076 } \
00077 return p00_ret; \
00078 } \
00079 P99_MACRO_END(declare_enum_parse, T)
00080 #endif
00081
00082 #ifdef DOXYGEN
00083
00123 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_DECLARE_ENUM, 0)
00124 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 1)
00125 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 2)
00126 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 3)
00127 #define P99_DECLARE_ENUM(T, ...) \
00128 \
00129 enum T { __VA_ARGS__ , \
00130 \
00131 P99_PASTE2(T, _amount), \
00132 \
00133 P99_PASTE2(T, _max) = ((size_t)(P99_PASTE2(T, _amount)) - 1u), \
00134 \
00135 P99_PASTE2(T, _min) = 0 \
00136 }; \
00137 \
00138 \
00139 typedef enum T T; \
00140 P99_DECLARE_ENUM_GETNAME(T, __VA_ARGS__); \
00141 P99_DECLARE_ENUM_PARSE(T, __VA_ARGS__)
00142 #else
00143 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_DECLARE_ENUM, 0)
00144 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 1)
00145 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 2)
00146 P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 3)
00147 #define P99_DECLARE_ENUM(T, ...) \
00148 typedef enum T { __VA_ARGS__ , \
00149 \
00150 P99_PASTE2(T, _amount), \
00151 \
00152 P99_PASTE2(T, _max) = ((size_t)(P99_PASTE2(T, _amount)) - 1u), \
00153 \
00154 P99_PASTE2(T, _min) = 0 \
00155 } T; \
00156 P99_DECLARE_ENUM_GETNAME(T, __VA_ARGS__); \
00157 P99_DECLARE_ENUM_PARSE(T, __VA_ARGS__)
00158 #endif
00159
00165 P00_DOCUMENT_TYPE_ARGUMENT(P99_DEFINE_ENUM, 0)
00166 #define P99_DEFINE_ENUM(T) \
00167 P99_INSTANTIATE(char const*, P99_PASTE2(T, _getname), T); \
00168 P99_INSTANTIATE(T, P99_PASTE2(T, _parse), char const*)
00169
00170 p99_inline
00171 char const* bool_getname(bool p00_x) {
00172 switch ((uintmax_t)p00_x) {
00173 case 0: return "false";
00174 case 1: return "true";
00175 default: return "((bool)unknown value)";
00176 }
00177 }
00178
00191 typedef enum p99_endianness {
00192 p99_big_endian = 0x01020304u,
00193 p99_little_endian = 0x04030201u,
00194 p99_pdp_endian = 0x02010403u
00195 } p99_endianness;
00196
00197 P99_DECLARE_ENUM_GETNAME(
00198 p99_endianness,
00199 p99_big_endian,
00200 p99_little_endian,
00201 p99_pdp_endian
00202 );
00203
00208 #define P99_ENDIANNESS ((p99_endianness)P99_HTON(4, UINT32_C(0x01020304)))
00209
00214 #endif