1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkTypedEnum_DEFINED 9 #define SkTypedEnum_DEFINED 10 11 #include "SkPreprocessorSeq.h" 12 13 //Compatibility with non-clang compilers. 14 #ifndef __has_feature 15 #define __has_feature(x) 0 16 #endif 17 #ifndef __has_extension 18 #define __has_extension __has_feature 19 #endif 20 21 //Detect if typed enums are supported. 22 #if defined(_MSC_VER) && _MSC_VER >= 1400 23 #define SK_TYPED_ENUMS 24 25 #elif defined(__clang__) && __has_extension(cxx_strong_enums) 26 #define SK_TYPED_ENUMS 27 28 // Scoped enums are buggy in GCC 4.4.0 through 4.5.1. 29 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 30 // __cplusplus should actually be accurate now. 31 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773 32 #elif defined(__GNUC__) && (((__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ >= 40501) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || __cplusplus >= 201103L) 33 #define SK_TYPED_ENUMS 34 #endif 35 36 //Define what a typed enum looks like. 37 #ifdef SK_TYPED_ENUMS 38 39 #define SK_TYPED_ENUM_VALUES(data, elem) \ 40 SK_PAIR_FIRST(elem) = SK_PAIR_SECOND(elem), 41 42 #define SK_TYPED_ENUM_IDS(data, elem) \ 43 elem, 44 45 #define SK_TYPED_ENUM_IDS_L(data, elem) \ 46 elem 47 48 #define SK_TYPED_ENUM(enumName, enumType, enumSeq, idSeq) \ 49 enum enumName : enumType { \ 50 SK_SEQ_FOREACH(SK_TYPED_ENUM_VALUES, _, enumSeq) \ 51 } SK_SEQ_FOREACH_L(SK_TYPED_ENUM_IDS, SK_TYPED_ENUM_IDS_L, _, idSeq); 52 53 #else 54 55 #define SK_TYPED_ENUM_VALUES(enumType, elem) \ 56 static const enumType SK_PAIR_FIRST(elem) = SK_PAIR_SECOND(elem); 57 58 #define SK_TYPED_ENUM_IDS(enumType, elem) \ 59 enumType elem; 60 61 #define SK_TYPED_ENUM(enumName, enumType, enumSeq, idSeq) \ 62 typedef enumType enumName; \ 63 SK_SEQ_FOREACH(SK_TYPED_ENUM_VALUES, enumType, enumSeq) \ 64 SK_SEQ_FOREACH(SK_TYPED_ENUM_IDS, enumType, idSeq) 65 66 #endif 67 68 #endif 69