// Copyright 2015 The Android Open Source Project // // This software is licensed under the terms of the GNU General Public // License version 2, as published by the Free Software Foundation, and // may be copied, distributed, and modified under those terms. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. #pragma once #include // This header defines some utitily methods to manipulate scoped enums as flags // C++11 scoped enums by default don't support flag operations (e.g. if (a & b)) // We need to define bitwise operations for them to be able to have strongly // typed flags in our code. // // To enable the flag operators for your enum, most probably you just need to // include this file. The only exception is if your enum is located in some // namespace other than android, android::base or global. In that case you also // need to add the following using to bring in the operators: // // using namespace ::android::base::EnumFlags; namespace android { namespace base { namespace EnumFlags { // A predicate which checks if template agument is a scoped enum template using is_scoped_enum = std::integral_constant< bool, std::is_enum::value && !std::is_convertible::value>; template using underlying_enum_type = typename std::underlying_type::type; template using enable_if_scoped_enum = typename std::enable_if::value, Res>::type; template enable_if_scoped_enum operator|(E l, E r) { return static_cast(static_cast>(l) | static_cast>(r)); } template enable_if_scoped_enum operator&(E l, E r) { return static_cast(static_cast>(l) & static_cast>(r)); } template enable_if_scoped_enum operator~(E e) { return static_cast(~static_cast>(e)); } template enable_if_scoped_enum operator|=(E& l, E r) { return l = (l | r); } template enable_if_scoped_enum operator&=(E& l, E r) { return l = (l & r); } template enable_if_scoped_enum operator!(E e) { return !static_cast>(e); } template enable_if_scoped_enum operator!=(E e, int val) { return static_cast>(e) != static_cast>(val); } template enable_if_scoped_enum operator!=(int val, E e) { return e != val; } template enable_if_scoped_enum operator==(E e, int val) { return static_cast>(e) == static_cast>(val); } template enable_if_scoped_enum operator==(int val, E e) { return e == val; } template enable_if_scoped_enum nonzero(E e) { return static_cast>(e) != 0; } } // namespace EnumFlags // For the ADL to kick in let's make sure we bring all the operators into our // main AndroidEmu namespaces... using namespace ::android::base::EnumFlags; } // namespace base using namespace ::android::base::EnumFlags; } // namespace android // ... and into the global one, where most of the client functions are using namespace ::android::base::EnumFlags;