180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkTypedEnum_DEFINED
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkTypedEnum_DEFINED
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPreprocessorSeq.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//Compatibility with non-clang compilers.
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef __has_feature
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define __has_feature(x) 0
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef __has_extension
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define __has_extension __has_feature
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//Detect if typed enums are supported.
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(_MSC_VER) && _MSC_VER >= 1400
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUMS
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#elif defined(__clang__) && __has_extension(cxx_strong_enums)
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUMS
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Scoped enums are buggy in GCC 4.4.0 through 4.5.1.
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// __cplusplus should actually be accurate now.
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#elif defined(__GNUC__) && (((__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ >= 40501) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || __cplusplus >= 201103L)
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUMS
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//Define what a typed enum looks like.
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_TYPED_ENUMS
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM_VALUES(data, elem) \
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SK_PAIR_FIRST(elem) = SK_PAIR_SECOND(elem),
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM_IDS(data, elem) \
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        elem,
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM_IDS_L(data, elem) \
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        elem
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM(enumName, enumType, enumSeq, idSeq) \
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        enum enumName : enumType { \
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SK_SEQ_FOREACH(SK_TYPED_ENUM_VALUES, _, enumSeq) \
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } SK_SEQ_FOREACH_L(SK_TYPED_ENUM_IDS, SK_TYPED_ENUM_IDS_L, _, idSeq);
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM_VALUES(enumType, elem) \
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        static const enumType SK_PAIR_FIRST(elem) = SK_PAIR_SECOND(elem);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM_IDS(enumType, elem) \
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        enumType elem;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SK_TYPED_ENUM(enumName, enumType, enumSeq, idSeq) \
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        typedef enumType enumName; \
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SK_SEQ_FOREACH(SK_TYPED_ENUM_VALUES, enumType, enumSeq) \
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SK_SEQ_FOREACH(SK_TYPED_ENUM_IDS, enumType, idSeq)
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
69