1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/TypedEnumBits.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,182 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. */ 1.11 + 1.12 +#ifndef mozilla_TypedEnumBits_h 1.13 +#define mozilla_TypedEnumBits_h 1.14 + 1.15 +#include "mozilla/IntegerTypeTraits.h" 1.16 +#include "mozilla/TypedEnumInternal.h" 1.17 + 1.18 +namespace mozilla { 1.19 + 1.20 +#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \ 1.21 +template<typename E> \ 1.22 +MOZ_CONSTEXPR ReturnType \ 1.23 +operator Op(const OtherType& e, const CastableTypedEnumResult<E>& r) \ 1.24 +{ \ 1.25 + return ReturnType(e Op OtherType(r)); \ 1.26 +} \ 1.27 +template<typename E> \ 1.28 +MOZ_CONSTEXPR ReturnType \ 1.29 +operator Op(const CastableTypedEnumResult<E>& r, const OtherType& e) \ 1.30 +{ \ 1.31 + return ReturnType(OtherType(r) Op e); \ 1.32 +} \ 1.33 +template<typename E> \ 1.34 +MOZ_CONSTEXPR ReturnType \ 1.35 +operator Op(const CastableTypedEnumResult<E>& r1, \ 1.36 + const CastableTypedEnumResult<E>& r2) \ 1.37 +{ \ 1.38 + return ReturnType(OtherType(r1) Op OtherType(r2)); \ 1.39 +} 1.40 + 1.41 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult<E>) 1.42 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(&, E, CastableTypedEnumResult<E>) 1.43 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(^, E, CastableTypedEnumResult<E>) 1.44 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(==, E, bool) 1.45 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(!=, E, bool) 1.46 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(||, bool, bool) 1.47 +MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool) 1.48 + 1.49 +template <typename E> 1.50 +MOZ_CONSTEXPR CastableTypedEnumResult<E> 1.51 +operator ~(const CastableTypedEnumResult<E>& r) 1.52 +{ 1.53 + return CastableTypedEnumResult<E>(~(E(r))); 1.54 +} 1.55 + 1.56 +#define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \ 1.57 +template<typename E> \ 1.58 +E& \ 1.59 +operator Op(E& r1, \ 1.60 + const CastableTypedEnumResult<E>& r2) \ 1.61 +{ \ 1.62 + return r1 Op E(r2); \ 1.63 +} 1.64 + 1.65 +MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=) 1.66 +MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=) 1.67 +MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=) 1.68 + 1.69 +#undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP 1.70 + 1.71 +#undef MOZ_CASTABLETYPEDENUMRESULT_BINOP 1.72 + 1.73 +#ifndef MOZ_HAVE_CXX11_STRONG_ENUMS 1.74 + 1.75 +#define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \ 1.76 +template<typename E> \ 1.77 +MOZ_CONSTEXPR ReturnType \ 1.78 +operator Op(typename E::Enum e, const CastableTypedEnumResult<E>& r) \ 1.79 +{ \ 1.80 + return ReturnType(e Op E(r)); \ 1.81 +} \ 1.82 +template<typename E> \ 1.83 +MOZ_CONSTEXPR ReturnType \ 1.84 +operator Op(const CastableTypedEnumResult<E>& r, typename E::Enum e) \ 1.85 +{ \ 1.86 + return ReturnType(E(r) Op e); \ 1.87 +} 1.88 + 1.89 +MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(|, CastableTypedEnumResult<E>) 1.90 +MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(&, CastableTypedEnumResult<E>) 1.91 +MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(^, CastableTypedEnumResult<E>) 1.92 +MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(==, bool) 1.93 +MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(!=, bool) 1.94 + 1.95 +#undef MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11 1.96 + 1.97 +#endif // not MOZ_HAVE_CXX11_STRONG_ENUMS 1.98 + 1.99 +namespace detail { 1.100 +template<typename E> 1.101 +struct UnsignedIntegerTypeForEnum 1.102 + : UnsignedStdintTypeForSize<sizeof(E)> 1.103 +{}; 1.104 +} 1.105 + 1.106 +} // namespace mozilla 1.107 + 1.108 +#define MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, Op) \ 1.109 + inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ 1.110 + operator Op(Name a, Name b) \ 1.111 + { \ 1.112 + typedef mozilla::CastableTypedEnumResult<Name> Result; \ 1.113 + typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \ 1.114 + return Result(Name(U(a) Op U(b))); \ 1.115 + } \ 1.116 + \ 1.117 + inline Name& \ 1.118 + operator Op##=(Name& a, Name b) \ 1.119 + { \ 1.120 + return a = a Op b; \ 1.121 + } 1.122 + 1.123 +#define MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \ 1.124 + MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \ 1.125 + MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \ 1.126 + MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \ 1.127 + inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ 1.128 + operator~(Name a) \ 1.129 + { \ 1.130 + typedef mozilla::CastableTypedEnumResult<Name> Result; \ 1.131 + typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \ 1.132 + return Result(Name(~(U(a)))); \ 1.133 + } 1.134 + 1.135 +#ifndef MOZ_HAVE_CXX11_STRONG_ENUMS 1.136 +# define MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, Op) \ 1.137 + inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ 1.138 + operator Op(Name a, Name::Enum b) \ 1.139 + { \ 1.140 + return a Op Name(b); \ 1.141 + } \ 1.142 + \ 1.143 + inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ 1.144 + operator Op(Name::Enum a, Name b) \ 1.145 + { \ 1.146 + return Name(a) Op b; \ 1.147 + } \ 1.148 + \ 1.149 + inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ 1.150 + operator Op(Name::Enum a, Name::Enum b) \ 1.151 + { \ 1.152 + return Name(a) Op Name(b); \ 1.153 + } \ 1.154 + \ 1.155 + inline Name& \ 1.156 + operator Op##=(Name& a, Name::Enum b) \ 1.157 + { \ 1.158 + return a = a Op Name(b); \ 1.159 + } 1.160 + 1.161 +# define MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name) \ 1.162 + MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, |) \ 1.163 + MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, &) \ 1.164 + MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, ^) \ 1.165 + inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ 1.166 + operator~(Name::Enum a) \ 1.167 + { \ 1.168 + return ~(Name(a)); \ 1.169 + } 1.170 +#endif 1.171 + 1.172 +/** 1.173 + * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators 1.174 + * for the given enum type. Use this to enable using an enum type as bit-field. 1.175 + */ 1.176 +#ifdef MOZ_HAVE_CXX11_STRONG_ENUMS 1.177 +# define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ 1.178 + MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) 1.179 +#else 1.180 +# define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ 1.181 + MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \ 1.182 + MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name) 1.183 +#endif 1.184 + 1.185 +#endif // mozilla_TypedEnumBits_h