1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. */
9 #ifndef mozilla_TypedEnumBits_h
10 #define mozilla_TypedEnumBits_h
12 #include "mozilla/IntegerTypeTraits.h"
13 #include "mozilla/TypedEnumInternal.h"
17 #define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \
18 template<typename E> \
19 MOZ_CONSTEXPR ReturnType \
20 operator Op(const OtherType& e, const CastableTypedEnumResult<E>& r) \
22 return ReturnType(e Op OtherType(r)); \
24 template<typename E> \
25 MOZ_CONSTEXPR ReturnType \
26 operator Op(const CastableTypedEnumResult<E>& r, const OtherType& e) \
28 return ReturnType(OtherType(r) Op e); \
30 template<typename E> \
31 MOZ_CONSTEXPR ReturnType \
32 operator Op(const CastableTypedEnumResult<E>& r1, \
33 const CastableTypedEnumResult<E>& r2) \
35 return ReturnType(OtherType(r1) Op OtherType(r2)); \
38 MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E
, CastableTypedEnumResult
<E
>)
39 MOZ_CASTABLETYPEDENUMRESULT_BINOP(&, E
, CastableTypedEnumResult
<E
>)
40 MOZ_CASTABLETYPEDENUMRESULT_BINOP(^, E
, CastableTypedEnumResult
<E
>)
41 MOZ_CASTABLETYPEDENUMRESULT_BINOP(==, E
, bool)
42 MOZ_CASTABLETYPEDENUMRESULT_BINOP(!=, E
, bool)
43 MOZ_CASTABLETYPEDENUMRESULT_BINOP(||, bool, bool)
44 MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool)
47 MOZ_CONSTEXPR CastableTypedEnumResult
<E
>
48 operator ~(const CastableTypedEnumResult
<E
>& r
)
50 return CastableTypedEnumResult
<E
>(~(E(r
)));
53 #define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \
54 template<typename E> \
57 const CastableTypedEnumResult<E>& r2) \
62 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=)
63 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=)
64 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=)
66 #undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP
68 #undef MOZ_CASTABLETYPEDENUMRESULT_BINOP
70 #ifndef MOZ_HAVE_CXX11_STRONG_ENUMS
72 #define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \
73 template<typename E> \
74 MOZ_CONSTEXPR ReturnType \
75 operator Op(typename E::Enum e, const CastableTypedEnumResult<E>& r) \
77 return ReturnType(e Op E(r)); \
79 template<typename E> \
80 MOZ_CONSTEXPR ReturnType \
81 operator Op(const CastableTypedEnumResult<E>& r, typename E::Enum e) \
83 return ReturnType(E(r) Op e); \
86 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(|, CastableTypedEnumResult
<E
>)
87 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(&, CastableTypedEnumResult
<E
>)
88 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(^, CastableTypedEnumResult
<E
>)
89 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(==, bool)
90 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(!=, bool)
92 #undef MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11
94 #endif // not MOZ_HAVE_CXX11_STRONG_ENUMS
98 struct UnsignedIntegerTypeForEnum
99 : UnsignedStdintTypeForSize
<sizeof(E
)>
103 } // namespace mozilla
105 #define MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, Op) \
106 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
107 operator Op(Name a, Name b) \
109 typedef mozilla::CastableTypedEnumResult<Name> Result; \
110 typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \
111 return Result(Name(U(a) Op U(b))); \
115 operator Op##=(Name& a, Name b) \
120 #define MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \
121 MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \
122 MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \
123 MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \
124 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
127 typedef mozilla::CastableTypedEnumResult<Name> Result; \
128 typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \
129 return Result(Name(~(U(a)))); \
132 #ifndef MOZ_HAVE_CXX11_STRONG_ENUMS
133 # define MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, Op) \
134 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
135 operator Op(Name a, Name::Enum b) \
137 return a Op Name(b); \
140 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
141 operator Op(Name::Enum a, Name b) \
143 return Name(a) Op b; \
146 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
147 operator Op(Name::Enum a, Name::Enum b) \
149 return Name(a) Op Name(b); \
153 operator Op##=(Name& a, Name::Enum b) \
155 return a = a Op Name(b); \
158 # define MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name) \
159 MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, |) \
160 MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, &) \
161 MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, ^) \
162 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \
163 operator~(Name::Enum a) \
170 * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators
171 * for the given enum type. Use this to enable using an enum type as bit-field.
173 #ifdef MOZ_HAVE_CXX11_STRONG_ENUMS
174 # define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \
175 MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name)
177 # define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \
178 MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \
179 MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name)
182 #endif // mozilla_TypedEnumBits_h