/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WTF_EnumClass_h #define WTF_EnumClass_h #include namespace WTF { // How to define a type-safe enum list using the ENUM_CLASS macros? // =============================================================== // To get an enum list like this: // // enum class MyEnums { // Value1, // Value2, // ... // ValueN // }; // // ... write this: // // ENUM_CLASS(MyEnums) { // Value1, // Value2, // ... // ValueN // } ENUM_CLASS_END(MyEnums); // // The ENUM_CLASS macros will use C++11's enum class if the compiler supports it. // Otherwise, it will use the EnumClass template below. #if COMPILER_SUPPORTS(CXX_STRONG_ENUMS) #define ENUM_CLASS(__enumName) \ enum class __enumName #define ENUM_CLASS_END(__enumName) #else // !COMPILER_SUPPORTS(CXX_STRONG_ENUMS) // How to define a type-safe enum list using the EnumClass template? // ================================================================ // Definition should be a struct that encapsulates an enum list. // The enum list should be names Enums. // // Here's an example of how to define a type-safe enum named MyEnum using // the EnumClass template: // // struct MyEnumDefinition { // enum Enums { // ValueDefault, // Value1, // ... // ValueN // }; // }; // typedef EnumClass MyEnum; // // With that, you can now use MyEnum enum values as follow: // // MyEnum value1; // value1 is assigned MyEnum::ValueDefault by default. // MyEnum value2 = MyEnum::Value1; // value2 is assigned MyEnum::Value1; template class EnumClass : public Definition { typedef enum Definition::Enums Value; public: ALWAYS_INLINE EnumClass() { } ALWAYS_INLINE EnumClass(Value value) : m_value(value) { } ALWAYS_INLINE Value value() const { return m_value; } ALWAYS_INLINE bool operator==(const EnumClass other) { return m_value == other.m_value; } ALWAYS_INLINE bool operator!=(const EnumClass other) { return m_value != other.m_value; } ALWAYS_INLINE bool operator<(const EnumClass other) { return m_value < other.m_value; } ALWAYS_INLINE bool operator<=(const EnumClass other) { return m_value <= other.m_value; } ALWAYS_INLINE bool operator>(const EnumClass other) { return m_value > other.m_value; } ALWAYS_INLINE bool operator>=(const EnumClass other) { return m_value >= other.m_value; } ALWAYS_INLINE bool operator==(const Value value) { return m_value == value; } ALWAYS_INLINE bool operator!=(const Value value) { return m_value != value; } ALWAYS_INLINE bool operator<(const Value value) { return m_value < value; } ALWAYS_INLINE bool operator<=(const Value value) { return m_value <= value; } ALWAYS_INLINE bool operator>(const Value value) { return m_value > value; } ALWAYS_INLINE bool operator>=(const Value value) { return m_value >= value; } ALWAYS_INLINE operator Value() { return m_value; } private: Value m_value; }; #define ENUM_CLASS(__enumName) \ struct __enumName ## Definition { \ enum Enums #define ENUM_CLASS_END(__enumName) \ ; \ }; \ typedef EnumClass< __enumName ## Definition > __enumName #endif // !COMPILER_SUPPORTS(CXX_STRONG_ENUMS) } // namespace WTF #if !COMPILER_SUPPORTS(CXX_STRONG_ENUMS) using WTF::EnumClass; #endif #endif // WTF_EnumClass_h