1 // scoped_enum.hpp ---------------------------------------------------------// 2 3 // Copyright Beman Dawes, 2009 4 // Copyright (C) 2011-2012 Vicente J. Botet Escriba 5 // Copyright (C) 2012 Anthony Williams 6 7 // Distributed under the Boost Software License, Version 1.0. 8 // See http://www.boost.org/LICENSE_1_0.txt 9 10 #ifndef BOOST_CORE_SCOPED_ENUM_HPP 11 #define BOOST_CORE_SCOPED_ENUM_HPP 12 13 #include <boost/config.hpp> 14 15 #ifdef BOOST_HAS_PRAGMA_ONCE 16 #pragma once 17 #endif 18 19 namespace boost 20 { 21 22 #ifdef BOOST_NO_CXX11_SCOPED_ENUMS 23 24 /** 25 * Meta-function to get the native enum type associated to an enum class or its emulation. 26 */ 27 template <typename EnumType> 28 struct native_type 29 { 30 /** 31 * The member typedef type names the native enum type associated to the scoped enum, 32 * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum. 33 */ 34 typedef typename EnumType::enum_type type; 35 }; 36 37 /** 38 * Casts a scoped enum to its underlying type. 39 * 40 * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type. 41 * @param v A scoped enum. 42 * @returns The underlying type. 43 * @throws No-throws. 44 */ 45 template <typename UnderlyingType, typename EnumType> 46 inline underlying_cast(EnumType v)47 BOOST_CONSTEXPR UnderlyingType underlying_cast(EnumType v) BOOST_NOEXCEPT 48 { 49 return v.get_underlying_value_(); 50 } 51 52 /** 53 * Casts a scoped enum to its native enum type. 54 * 55 * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can. 56 * 57 * EnumType the scoped enum type 58 * 59 * @param v A scoped enum. 60 * @returns The native enum value. 61 * @throws No-throws. 62 */ 63 template <typename EnumType> 64 inline native_value(EnumType e)65 BOOST_CONSTEXPR typename EnumType::enum_type native_value(EnumType e) BOOST_NOEXCEPT 66 { 67 return e.get_native_value_(); 68 } 69 70 #else // BOOST_NO_CXX11_SCOPED_ENUMS 71 72 template <typename EnumType> 73 struct native_type 74 { 75 typedef EnumType type; 76 }; 77 78 template <typename UnderlyingType, typename EnumType> 79 inline 80 BOOST_CONSTEXPR UnderlyingType underlying_cast(EnumType v) BOOST_NOEXCEPT 81 { 82 return static_cast<UnderlyingType>(v); 83 } 84 85 template <typename EnumType> 86 inline 87 BOOST_CONSTEXPR EnumType native_value(EnumType e) BOOST_NOEXCEPT 88 { 89 return e; 90 } 91 92 #endif // BOOST_NO_CXX11_SCOPED_ENUMS 93 } 94 95 96 #ifdef BOOST_NO_CXX11_SCOPED_ENUMS 97 98 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS 99 100 #define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ 101 explicit BOOST_CONSTEXPR operator underlying_type() const BOOST_NOEXCEPT { return get_underlying_value_(); } 102 103 #else 104 105 #define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR 106 107 #endif 108 109 /** 110 * Start a declaration of a scoped enum. 111 * 112 * @param EnumType The new scoped enum. 113 * @param UnderlyingType The underlying type. 114 */ 115 #define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \ 116 struct EnumType { \ 117 typedef void is_boost_scoped_enum_tag; \ 118 typedef UnderlyingType underlying_type; \ 119 EnumType() BOOST_NOEXCEPT {} \ 120 explicit BOOST_CONSTEXPR EnumType(underlying_type v) BOOST_NOEXCEPT : v_(v) {} \ 121 BOOST_CONSTEXPR underlying_type get_underlying_value_() const BOOST_NOEXCEPT { return v_; } \ 122 BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ 123 private: \ 124 underlying_type v_; \ 125 typedef EnumType self_type; \ 126 public: \ 127 enum enum_type 128 129 #define BOOST_SCOPED_ENUM_DECLARE_END2() \ 130 BOOST_CONSTEXPR enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \ 131 friend BOOST_CONSTEXPR bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \ 132 friend BOOST_CONSTEXPR bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \ 133 friend BOOST_CONSTEXPR bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \ 134 friend BOOST_CONSTEXPR bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \ 135 friend BOOST_CONSTEXPR bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \ 136 friend BOOST_CONSTEXPR bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \ 137 friend BOOST_CONSTEXPR bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \ 138 friend BOOST_CONSTEXPR bool operator <(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \ 139 friend BOOST_CONSTEXPR bool operator <(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \ 140 friend BOOST_CONSTEXPR bool operator <=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \ 141 friend BOOST_CONSTEXPR bool operator <=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \ 142 friend BOOST_CONSTEXPR bool operator <=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \ 143 friend BOOST_CONSTEXPR bool operator >(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \ 144 friend BOOST_CONSTEXPR bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \ 145 friend BOOST_CONSTEXPR bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \ 146 friend BOOST_CONSTEXPR bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \ 147 friend BOOST_CONSTEXPR bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \ 148 friend BOOST_CONSTEXPR bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \ 149 }; 150 151 #define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \ 152 ; \ 153 BOOST_CONSTEXPR EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \ 154 BOOST_SCOPED_ENUM_DECLARE_END2() 155 156 /** 157 * Starts a declaration of a scoped enum with the default int underlying type. 158 * 159 * @param EnumType The new scoped enum. 160 */ 161 #define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \ 162 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int) 163 164 /** 165 * Name of the native enum type. 166 * 167 * @param EnumType The new scoped enum. 168 */ 169 #define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type 170 /** 171 * Forward declares an scoped enum. 172 * 173 * @param EnumType The scoped enum. 174 */ 175 #define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType 176 177 #else // BOOST_NO_CXX11_SCOPED_ENUMS 178 179 #define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType : UnderlyingType 180 #define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType 181 #define BOOST_SCOPED_ENUM_DECLARE_END2() 182 #define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ; 183 184 #define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType 185 #define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType 186 187 #endif // BOOST_NO_CXX11_SCOPED_ENUMS 188 189 // Deprecated macros 190 #define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name) 191 #define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2() 192 #define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name) 193 194 #endif // BOOST_CORE_SCOPED_ENUM_HPP 195