1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/* 2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2013 Apple Inc. All rights reserved. 3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions 6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met: 7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifndef WTF_EnumClass_h 27926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define WTF_EnumClass_h 28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 29591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/Compiler.h" 30926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 31926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace WTF { 32926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 33926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// How to define a type safe enum list using the ENUM_CLASS macros? 34926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// =============================================================== 35926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// To get an enum list like this: 36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// enum class MyEnums { 38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Value1, 39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Value2, 40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ... 41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ValueN 42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// }; 43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ... write this: 45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ENUM_CLASS(MyEnums) { 47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Value1, 48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Value2, 49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ... 50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ValueN 51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// } ENUM_CLASS_END(MyEnums); 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The ENUM_CLASS macros will use C++11's enum class if the compiler supports it. 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Otherwise, it will use the EnumClass template below. 55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#if COMPILER_SUPPORTS(CXX_STRONG_ENUMS) 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define ENUM_CLASS(__enumName) \ 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) enum class __enumName 60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define ENUM_CLASS_END(__enumName) 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#else // !COMPILER_SUPPORTS(CXX_STRONG_ENUMS) 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// How to define a type safe enum list using the EnumClass template? 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ================================================================ 67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Definition should be a struct that encapsulates an enum list. 68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// The enum list should be names Enums. 69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Here's an example of how to define a type safe enum named MyEnum using 71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// the EnumClass template: 72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// struct MyEnumDefinition { 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// enum Enums { 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ValueDefault, 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Value1, 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ... 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// ValueN 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// }; 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// }; 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// typedef EnumClass<MyEnumDefinition, MyEnumDefinition::ValueDefault> MyEnum; 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// With that, you can now use MyEnum enum values as follow: 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// MyEnum value1; // value1 is assigned MyEnum::ValueDefault by default. 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// MyEnum value2 = MyEnum::Value1; // value2 is assigned MyEnum::Value1; 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <typename Definition> 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class EnumClass : public Definition { 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) typedef enum Definition::Enums Value; 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public: 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE EnumClass() { } 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE EnumClass(Value value) : m_value(value) { } 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE Value value() const { return m_value; } 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator==(const EnumClass other) { return m_value == other.m_value; } 98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator!=(const EnumClass other) { return m_value != other.m_value; } 99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator<(const EnumClass other) { return m_value < other.m_value; } 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator<=(const EnumClass other) { return m_value <= other.m_value; } 101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator>(const EnumClass other) { return m_value > other.m_value; } 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator>=(const EnumClass other) { return m_value >= other.m_value; } 103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator==(const Value value) { return m_value == value; } 105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator!=(const Value value) { return m_value != value; } 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator<(const Value value) { return m_value < value; } 107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator<=(const Value value) { return m_value <= value; } 108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator>(const Value value) { return m_value > value; } 109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE bool operator>=(const Value value) { return m_value >= value; } 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ALWAYS_INLINE operator Value() { return m_value; } 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)private: 114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Value m_value; 115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}; 116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define ENUM_CLASS(__enumName) \ 118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) struct __enumName ## Definition { \ 119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) enum Enums 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define ENUM_CLASS_END(__enumName) \ 122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ; \ 123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) }; \ 124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) typedef EnumClass< __enumName ## Definition > __enumName 125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif // !COMPILER_SUPPORTS(CXX_STRONG_ENUMS) 127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // namespace WTF 129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#if !COMPILER_SUPPORTS(CXX_STRONG_ENUMS) 131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)using WTF::EnumClass; 132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif // WTF_EnumClass_h 135