Home | History | Annotate | Download | only in sfnt
      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