mfbt/TypedEnumBits.h

changeset 0
6474c204b198
     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

mercurial