diff options
Diffstat (limited to 'gdb/common/enum-flags.h')
-rw-r--r-- | gdb/common/enum-flags.h | 221 |
1 files changed, 0 insertions, 221 deletions
diff --git a/gdb/common/enum-flags.h b/gdb/common/enum-flags.h deleted file mode 100644 index 88ba591..0000000 --- a/gdb/common/enum-flags.h +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright (C) 2015-2019 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - 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. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef COMMON_ENUM_FLAGS_H -#define COMMON_ENUM_FLAGS_H - -/* Type-safe wrapper for enum flags. enum flags are enums where the - values are bits that are meant to be ORed together. - - This allows writing code like the below, while with raw enums this - would fail to compile without casts to enum type at the assignments - to 'f': - - enum some_flag - { - flag_val1 = 1 << 1, - flag_val2 = 1 << 2, - flag_val3 = 1 << 3, - flag_val4 = 1 << 4, - }; - DEF_ENUM_FLAGS_TYPE(enum some_flag, some_flags); - - some_flags f = flag_val1 | flag_val2; - f |= flag_val3; - - It's also possible to assign literal zero to an enum flags variable - (meaning, no flags), dispensing adding an awkward explicit "no - value" value to the enumeration. For example: - - some_flags f = 0; - f |= flag_val3 | flag_val4; - - Note that literal integers other than zero fail to compile: - - some_flags f = 1; // error -*/ - -#ifdef __cplusplus - -/* Traits type used to prevent the global operator overloads from - instantiating for non-flag enums. */ -template<typename T> struct enum_flags_type {}; - -/* Use this to mark an enum as flags enum. It defines FLAGS as - enum_flags wrapper class for ENUM, and enables the global operator - overloads for ENUM. */ -#define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \ - typedef enum_flags<enum_type> flags_type; \ - template<> \ - struct enum_flags_type<enum_type> \ - { \ - typedef enum_flags<enum_type> type; \ - } - -/* Until we can rely on std::underlying type being universally - available (C++11), roll our own for enums. */ -template<int size, bool sign> class integer_for_size { typedef void type; }; -template<> struct integer_for_size<1, 0> { typedef uint8_t type; }; -template<> struct integer_for_size<2, 0> { typedef uint16_t type; }; -template<> struct integer_for_size<4, 0> { typedef uint32_t type; }; -template<> struct integer_for_size<8, 0> { typedef uint64_t type; }; -template<> struct integer_for_size<1, 1> { typedef int8_t type; }; -template<> struct integer_for_size<2, 1> { typedef int16_t type; }; -template<> struct integer_for_size<4, 1> { typedef int32_t type; }; -template<> struct integer_for_size<8, 1> { typedef int64_t type; }; - -template<typename T> -struct enum_underlying_type -{ - typedef typename - integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type - type; -}; - -template <typename E> -class enum_flags -{ -public: - typedef E enum_type; - typedef typename enum_underlying_type<enum_type>::type underlying_type; - -private: - /* Private type used to support initializing flag types with zero: - - foo_flags f = 0; - - but not other integers: - - foo_flags f = 1; - - The way this works is that we define an implicit constructor that - takes a pointer to this private type. Since nothing can - instantiate an object of this type, the only possible pointer to - pass to the constructor is the NULL pointer, or, zero. */ - struct zero_type; - - underlying_type - underlying_value () const - { - return m_enum_value; - } - -public: - /* Allow default construction. */ - enum_flags () - : m_enum_value ((enum_type) 0) - {} - - /* If you get an error saying these two overloads are ambiguous, - then you tried to mix values of different enum types. */ - enum_flags (enum_type e) - : m_enum_value (e) - {} - enum_flags (struct enum_flags::zero_type *zero) - : m_enum_value ((enum_type) 0) - {} - - enum_flags &operator&= (enum_type e) - { - m_enum_value = (enum_type) (underlying_value () & e); - return *this; - } - enum_flags &operator|= (enum_type e) - { - m_enum_value = (enum_type) (underlying_value () | e); - return *this; - } - enum_flags &operator^= (enum_type e) - { - m_enum_value = (enum_type) (underlying_value () ^ e); - return *this; - } - - operator enum_type () const - { - return m_enum_value; - } - - enum_flags operator& (enum_type e) const - { - return (enum_type) (underlying_value () & e); - } - enum_flags operator| (enum_type e) const - { - return (enum_type) (underlying_value () | e); - } - enum_flags operator^ (enum_type e) const - { - return (enum_type) (underlying_value () ^ e); - } - enum_flags operator~ () const - { - // We only the underlying type to be unsigned when actually using - // operator~ -- if it were not unsigned, undefined behavior could - // result. However, asserting this in the class itself would - // require too many unnecessary changes to otherwise ok enum - // types. - gdb_static_assert (std::is_unsigned<underlying_type>::value); - return (enum_type) ~underlying_value (); - } - -private: - /* Stored as enum_type because GDB knows to print the bit flags - neatly if the enum values look like bit flags. */ - enum_type m_enum_value; -}; - -/* Global operator overloads. */ - -template <typename enum_type> -typename enum_flags_type<enum_type>::type -operator& (enum_type e1, enum_type e2) -{ - return enum_flags<enum_type> (e1) & e2; -} - -template <typename enum_type> -typename enum_flags_type<enum_type>::type -operator| (enum_type e1, enum_type e2) -{ - return enum_flags<enum_type> (e1) | e2; -} - -template <typename enum_type> -typename enum_flags_type<enum_type>::type -operator^ (enum_type e1, enum_type e2) -{ - return enum_flags<enum_type> (e1) ^ e2; -} - -template <typename enum_type> -typename enum_flags_type<enum_type>::type -operator~ (enum_type e) -{ - return ~enum_flags<enum_type> (e); -} - -#else /* __cplusplus */ - -/* In C, the flags type is just a typedef for the enum type. */ - -#define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \ - typedef enum_type flags_type - -#endif /* __cplusplus */ - -#endif /* COMMON_ENUM_FLAGS_H */ |