xref: /netbsd-src/external/gpl3/gdb.old/dist/gdbsupport/enum-flags.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1*6881a400Schristos /* Copyright (C) 2015-2023 Free Software Foundation, Inc.
27d62b00eSchristos 
37d62b00eSchristos    This file is part of GDB.
47d62b00eSchristos 
57d62b00eSchristos    This program is free software; you can redistribute it and/or modify
67d62b00eSchristos    it under the terms of the GNU General Public License as published by
77d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
87d62b00eSchristos    (at your option) any later version.
97d62b00eSchristos 
107d62b00eSchristos    This program is distributed in the hope that it will be useful,
117d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
127d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
137d62b00eSchristos    GNU General Public License for more details.
147d62b00eSchristos 
157d62b00eSchristos    You should have received a copy of the GNU General Public License
167d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
177d62b00eSchristos 
187d62b00eSchristos #ifndef COMMON_ENUM_FLAGS_H
197d62b00eSchristos #define COMMON_ENUM_FLAGS_H
207d62b00eSchristos 
21*6881a400Schristos #include "traits.h"
22*6881a400Schristos 
237d62b00eSchristos /* Type-safe wrapper for enum flags.  enum flags are enums where the
247d62b00eSchristos    values are bits that are meant to be ORed together.
257d62b00eSchristos 
267d62b00eSchristos    This allows writing code like the below, while with raw enums this
277d62b00eSchristos    would fail to compile without casts to enum type at the assignments
287d62b00eSchristos    to 'f':
297d62b00eSchristos 
307d62b00eSchristos     enum some_flag
317d62b00eSchristos     {
327d62b00eSchristos        flag_val1 = 1 << 1,
337d62b00eSchristos        flag_val2 = 1 << 2,
347d62b00eSchristos        flag_val3 = 1 << 3,
357d62b00eSchristos        flag_val4 = 1 << 4,
367d62b00eSchristos     };
377d62b00eSchristos     DEF_ENUM_FLAGS_TYPE(enum some_flag, some_flags);
387d62b00eSchristos 
397d62b00eSchristos     some_flags f = flag_val1 | flag_val2;
407d62b00eSchristos     f |= flag_val3;
417d62b00eSchristos 
427d62b00eSchristos    It's also possible to assign literal zero to an enum flags variable
437d62b00eSchristos    (meaning, no flags), dispensing adding an awkward explicit "no
447d62b00eSchristos    value" value to the enumeration.  For example:
457d62b00eSchristos 
467d62b00eSchristos     some_flags f = 0;
477d62b00eSchristos     f |= flag_val3 | flag_val4;
487d62b00eSchristos 
497d62b00eSchristos    Note that literal integers other than zero fail to compile:
507d62b00eSchristos 
517d62b00eSchristos     some_flags f = 1; // error
527d62b00eSchristos */
537d62b00eSchristos 
547d62b00eSchristos #ifdef __cplusplus
557d62b00eSchristos 
56*6881a400Schristos /* Use this to mark an enum as flags enum.  It defines FLAGS_TYPE as
577d62b00eSchristos    enum_flags wrapper class for ENUM, and enables the global operator
587d62b00eSchristos    overloads for ENUM.  */
597d62b00eSchristos #define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type)	\
607d62b00eSchristos   typedef enum_flags<enum_type> flags_type;		\
61*6881a400Schristos   void is_enum_flags_enum_type (enum_type *)
627d62b00eSchristos 
63*6881a400Schristos /* To enable the global enum_flags operators for enum, declare an
64*6881a400Schristos    "is_enum_flags_enum_type" overload that has exactly one parameter,
65*6881a400Schristos    of type a pointer to that enum class.  E.g.,:
66*6881a400Schristos 
67*6881a400Schristos      void is_enum_flags_enum_type (enum some_flag *);
68*6881a400Schristos 
69*6881a400Schristos    The function does not need to be defined, only declared.
70*6881a400Schristos    DEF_ENUM_FLAGS_TYPE declares this.
71*6881a400Schristos 
72*6881a400Schristos    A function declaration is preferred over a traits type, because the
73*6881a400Schristos    former allows calling the DEF_ENUM_FLAGS_TYPE macro inside a
74*6881a400Schristos    namespace to define the corresponding enum flags type in that
75*6881a400Schristos    namespace.  The compiler finds the corresponding
76*6881a400Schristos    is_enum_flags_enum_type function via ADL.  */
77*6881a400Schristos 
78*6881a400Schristos /* Note that std::underlying_type<enum_type> is not what we want here,
79*6881a400Schristos    since that returns unsigned int even when the enum decays to signed
80*6881a400Schristos    int.  */
817d62b00eSchristos template<int size, bool sign> class integer_for_size { typedef void type; };
827d62b00eSchristos template<> struct integer_for_size<1, 0> { typedef uint8_t type; };
837d62b00eSchristos template<> struct integer_for_size<2, 0> { typedef uint16_t type; };
847d62b00eSchristos template<> struct integer_for_size<4, 0> { typedef uint32_t type; };
857d62b00eSchristos template<> struct integer_for_size<8, 0> { typedef uint64_t type; };
867d62b00eSchristos template<> struct integer_for_size<1, 1> { typedef int8_t type; };
877d62b00eSchristos template<> struct integer_for_size<2, 1> { typedef int16_t type; };
887d62b00eSchristos template<> struct integer_for_size<4, 1> { typedef int32_t type; };
897d62b00eSchristos template<> struct integer_for_size<8, 1> { typedef int64_t type; };
907d62b00eSchristos 
917d62b00eSchristos template<typename T>
927d62b00eSchristos struct enum_underlying_type
937d62b00eSchristos {
94*6881a400Schristos   DIAGNOSTIC_PUSH
95*6881a400Schristos   DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION
967d62b00eSchristos   typedef typename
977d62b00eSchristos     integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type
987d62b00eSchristos     type;
99*6881a400Schristos   DIAGNOSTIC_POP
1007d62b00eSchristos };
1017d62b00eSchristos 
102*6881a400Schristos namespace enum_flags_detail
1037d62b00eSchristos {
1047d62b00eSchristos 
1057d62b00eSchristos /* Private type used to support initializing flag types with zero:
1067d62b00eSchristos 
1077d62b00eSchristos    foo_flags f = 0;
1087d62b00eSchristos 
1097d62b00eSchristos    but not other integers:
1107d62b00eSchristos 
1117d62b00eSchristos    foo_flags f = 1;
1127d62b00eSchristos 
1137d62b00eSchristos    The way this works is that we define an implicit constructor that
1147d62b00eSchristos    takes a pointer to this private type.  Since nothing can
1157d62b00eSchristos    instantiate an object of this type, the only possible pointer to
1167d62b00eSchristos    pass to the constructor is the NULL pointer, or, zero.  */
1177d62b00eSchristos struct zero_type;
1187d62b00eSchristos 
119*6881a400Schristos /* gdb::Requires trait helpers.  */
120*6881a400Schristos template <typename enum_type>
121*6881a400Schristos using EnumIsUnsigned
122*6881a400Schristos   = std::is_unsigned<typename enum_underlying_type<enum_type>::type>;
123*6881a400Schristos template <typename enum_type>
124*6881a400Schristos using EnumIsSigned
125*6881a400Schristos   = std::is_signed<typename enum_underlying_type<enum_type>::type>;
126*6881a400Schristos 
1277d62b00eSchristos }
1287d62b00eSchristos 
129*6881a400Schristos template <typename E>
130*6881a400Schristos class enum_flags
131*6881a400Schristos {
132*6881a400Schristos public:
133*6881a400Schristos   typedef E enum_type;
134*6881a400Schristos   typedef typename enum_underlying_type<enum_type>::type underlying_type;
135*6881a400Schristos 
1367d62b00eSchristos public:
1377d62b00eSchristos   /* Allow default construction.  */
138*6881a400Schristos   constexpr enum_flags ()
1397d62b00eSchristos     : m_enum_value ((enum_type) 0)
1407d62b00eSchristos   {}
1417d62b00eSchristos 
142*6881a400Schristos   /* The default move/copy ctor/assignment do the right thing.  */
143*6881a400Schristos 
1447d62b00eSchristos   /* If you get an error saying these two overloads are ambiguous,
1457d62b00eSchristos      then you tried to mix values of different enum types.  */
146*6881a400Schristos   constexpr enum_flags (enum_type e)
1477d62b00eSchristos     : m_enum_value (e)
1487d62b00eSchristos   {}
149*6881a400Schristos   constexpr enum_flags (enum_flags_detail::zero_type *zero)
1507d62b00eSchristos     : m_enum_value ((enum_type) 0)
1517d62b00eSchristos   {}
1527d62b00eSchristos 
153*6881a400Schristos   enum_flags &operator&= (enum_flags e) &
1547d62b00eSchristos   {
155*6881a400Schristos     m_enum_value = (enum_type) (m_enum_value & e.m_enum_value);
1567d62b00eSchristos     return *this;
1577d62b00eSchristos   }
158*6881a400Schristos   enum_flags &operator|= (enum_flags e) &
1597d62b00eSchristos   {
160*6881a400Schristos     m_enum_value = (enum_type) (m_enum_value | e.m_enum_value);
1617d62b00eSchristos     return *this;
1627d62b00eSchristos   }
163*6881a400Schristos   enum_flags &operator^= (enum_flags e) &
1647d62b00eSchristos   {
165*6881a400Schristos     m_enum_value = (enum_type) (m_enum_value ^ e.m_enum_value);
1667d62b00eSchristos     return *this;
1677d62b00eSchristos   }
1687d62b00eSchristos 
169*6881a400Schristos   /* Delete rval versions.  */
170*6881a400Schristos   void operator&= (enum_flags e) && = delete;
171*6881a400Schristos   void operator|= (enum_flags e) && = delete;
172*6881a400Schristos   void operator^= (enum_flags e) && = delete;
173*6881a400Schristos 
174*6881a400Schristos   /* Like raw enums, allow conversion to the underlying type.  */
175*6881a400Schristos   constexpr operator underlying_type () const
1767d62b00eSchristos   {
1777d62b00eSchristos     return m_enum_value;
1787d62b00eSchristos   }
1797d62b00eSchristos 
180*6881a400Schristos   /* Get the underlying value as a raw enum.  */
181*6881a400Schristos   constexpr enum_type raw () const
1827d62b00eSchristos   {
183*6881a400Schristos     return m_enum_value;
1847d62b00eSchristos   }
185*6881a400Schristos 
186*6881a400Schristos   /* Binary operations involving some unrelated type (which would be a
187*6881a400Schristos      bug) are implemented as non-members, and deleted.  */
1887d62b00eSchristos 
1897d62b00eSchristos private:
1907d62b00eSchristos   /* Stored as enum_type because GDB knows to print the bit flags
1917d62b00eSchristos      neatly if the enum values look like bit flags.  */
1927d62b00eSchristos   enum_type m_enum_value;
1937d62b00eSchristos };
1947d62b00eSchristos 
195*6881a400Schristos template <typename E>
196*6881a400Schristos using is_enum_flags_enum_type_t
197*6881a400Schristos   = decltype (is_enum_flags_enum_type (std::declval<E *> ()));
198*6881a400Schristos 
1997d62b00eSchristos /* Global operator overloads.  */
2007d62b00eSchristos 
201*6881a400Schristos /* Generate binary operators.  */
2027d62b00eSchristos 
203*6881a400Schristos #define ENUM_FLAGS_GEN_BINOP(OPERATOR_OP, OP)				\
204*6881a400Schristos 									\
205*6881a400Schristos   /* Raw enum on both LHS/RHS.  Returns raw enum type.  */		\
206*6881a400Schristos   template <typename enum_type,						\
207*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
208*6881a400Schristos   constexpr enum_type							\
209*6881a400Schristos   OPERATOR_OP (enum_type e1, enum_type e2)				\
210*6881a400Schristos   {									\
211*6881a400Schristos     using underlying = typename enum_flags<enum_type>::underlying_type;	\
212*6881a400Schristos     return (enum_type) (underlying (e1) OP underlying (e2));		\
213*6881a400Schristos   }									\
214*6881a400Schristos 									\
215*6881a400Schristos   /* enum_flags on the LHS.  */						\
216*6881a400Schristos   template <typename enum_type,						\
217*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
218*6881a400Schristos   constexpr enum_flags<enum_type>					\
219*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> e1, enum_type e2)			\
220*6881a400Schristos   { return e1.raw () OP e2; }						\
221*6881a400Schristos 									\
222*6881a400Schristos   /* enum_flags on the RHS.  */						\
223*6881a400Schristos   template <typename enum_type,						\
224*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
225*6881a400Schristos   constexpr enum_flags<enum_type>					\
226*6881a400Schristos   OPERATOR_OP (enum_type e1, enum_flags<enum_type> e2)			\
227*6881a400Schristos   { return e1 OP e2.raw (); }						\
228*6881a400Schristos 									\
229*6881a400Schristos   /* enum_flags on both LHS/RHS.  */					\
230*6881a400Schristos   template <typename enum_type,						\
231*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
232*6881a400Schristos   constexpr enum_flags<enum_type>					\
233*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> e1, enum_flags<enum_type> e2)	\
234*6881a400Schristos   { return e1.raw () OP e2.raw (); }					\
235*6881a400Schristos 									\
236*6881a400Schristos   /* Delete cases involving unrelated types.  */			\
237*6881a400Schristos 									\
238*6881a400Schristos   template <typename enum_type, typename unrelated_type,		\
239*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
240*6881a400Schristos   constexpr enum_flags<enum_type>					\
241*6881a400Schristos   OPERATOR_OP (enum_type e1, unrelated_type e2) = delete;		\
242*6881a400Schristos 									\
243*6881a400Schristos   template <typename enum_type, typename unrelated_type,		\
244*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
245*6881a400Schristos   constexpr enum_flags<enum_type>					\
246*6881a400Schristos   OPERATOR_OP (unrelated_type e1, enum_type e2) = delete;		\
247*6881a400Schristos 									\
248*6881a400Schristos   template <typename enum_type, typename unrelated_type,		\
249*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
250*6881a400Schristos   constexpr enum_flags<enum_type>					\
251*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> e1, unrelated_type e2) = delete;	\
252*6881a400Schristos 									\
253*6881a400Schristos   template <typename enum_type, typename unrelated_type,		\
254*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
255*6881a400Schristos   constexpr enum_flags<enum_type>					\
256*6881a400Schristos   OPERATOR_OP (unrelated_type e1, enum_flags<enum_type> e2) = delete;
2577d62b00eSchristos 
258*6881a400Schristos /* Generate non-member compound assignment operators.  Only the raw
259*6881a400Schristos    enum versions are defined here.  The enum_flags versions are
260*6881a400Schristos    defined as member functions, simply because it's less code that
261*6881a400Schristos    way.
2627d62b00eSchristos 
263*6881a400Schristos    Note we delete operators that would allow e.g.,
264*6881a400Schristos 
265*6881a400Schristos      "enum_type | 1" or "enum_type1 | enum_type2"
266*6881a400Schristos 
267*6881a400Schristos    because that would allow a mistake like :
268*6881a400Schristos      enum flags1 { F1_FLAGS1 = 1 };
269*6881a400Schristos      enum flags2 { F2_FLAGS2 = 2 };
270*6881a400Schristos      enum flags1 val;
271*6881a400Schristos      switch (val) {
272*6881a400Schristos        case F1_FLAGS1 | F2_FLAGS2:
273*6881a400Schristos      ...
274*6881a400Schristos 
275*6881a400Schristos    If you really need to 'or' enumerators of different flag types,
276*6881a400Schristos    cast to integer first.
277*6881a400Schristos */
278*6881a400Schristos #define ENUM_FLAGS_GEN_COMPOUND_ASSIGN(OPERATOR_OP, OP)			\
279*6881a400Schristos   /* lval reference version.  */					\
280*6881a400Schristos   template <typename enum_type,						\
281*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
282*6881a400Schristos   constexpr enum_type &							\
283*6881a400Schristos   OPERATOR_OP (enum_type &e1, enum_type e2)				\
284*6881a400Schristos   { return e1 = e1 OP e2; }						\
285*6881a400Schristos 									\
286*6881a400Schristos   /* rval reference version.  */					\
287*6881a400Schristos   template <typename enum_type,						\
288*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
289*6881a400Schristos   void									\
290*6881a400Schristos   OPERATOR_OP (enum_type &&e1, enum_type e2) = delete;			\
291*6881a400Schristos 									\
292*6881a400Schristos   /* Delete compound assignment from unrelated types.  */		\
293*6881a400Schristos 									\
294*6881a400Schristos   template <typename enum_type, typename other_enum_type,		\
295*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
296*6881a400Schristos   constexpr enum_type &							\
297*6881a400Schristos   OPERATOR_OP (enum_type &e1, other_enum_type e2) = delete;		\
298*6881a400Schristos 									\
299*6881a400Schristos   template <typename enum_type, typename other_enum_type,		\
300*6881a400Schristos 	    typename = is_enum_flags_enum_type_t<enum_type>>		\
301*6881a400Schristos   void									\
302*6881a400Schristos   OPERATOR_OP (enum_type &&e1, other_enum_type e2) = delete;
303*6881a400Schristos 
304*6881a400Schristos ENUM_FLAGS_GEN_BINOP (operator|, |)
305*6881a400Schristos ENUM_FLAGS_GEN_BINOP (operator&, &)
306*6881a400Schristos ENUM_FLAGS_GEN_BINOP (operator^, ^)
307*6881a400Schristos 
308*6881a400Schristos ENUM_FLAGS_GEN_COMPOUND_ASSIGN (operator|=, |)
309*6881a400Schristos ENUM_FLAGS_GEN_COMPOUND_ASSIGN (operator&=, &)
310*6881a400Schristos ENUM_FLAGS_GEN_COMPOUND_ASSIGN (operator^=, ^)
311*6881a400Schristos 
312*6881a400Schristos /* Allow comparison with enum_flags, raw enum, and integers, only.
313*6881a400Schristos    The latter case allows "== 0".  As side effect, it allows comparing
314*6881a400Schristos    with integer variables too, but that's not a common mistake to
315*6881a400Schristos    make.  It's important to disable comparison with unrelated types to
316*6881a400Schristos    prevent accidentally comparing with unrelated enum values, which
317*6881a400Schristos    are convertible to integer, and thus coupled with enum_flags
318*6881a400Schristos    convertion to underlying type too, would trigger the built-in 'bool
319*6881a400Schristos    operator==(unsigned, int)' operator.  */
320*6881a400Schristos 
321*6881a400Schristos #define ENUM_FLAGS_GEN_COMP(OPERATOR_OP, OP)				\
322*6881a400Schristos 									\
323*6881a400Schristos   /* enum_flags OP enum_flags */					\
324*6881a400Schristos 									\
325*6881a400Schristos   template <typename enum_type>						\
326*6881a400Schristos   constexpr bool							\
327*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> lhs, enum_flags<enum_type> rhs)	\
328*6881a400Schristos   { return lhs.raw () OP rhs.raw (); }					\
329*6881a400Schristos 									\
330*6881a400Schristos   /* enum_flags OP other */						\
331*6881a400Schristos 									\
332*6881a400Schristos   template <typename enum_type>						\
333*6881a400Schristos   constexpr bool							\
334*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> lhs, enum_type rhs)		\
335*6881a400Schristos   { return lhs.raw () OP rhs; }						\
336*6881a400Schristos 									\
337*6881a400Schristos   template <typename enum_type>						\
338*6881a400Schristos   constexpr bool							\
339*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> lhs, int rhs)			\
340*6881a400Schristos   { return lhs.raw () OP rhs; }						\
341*6881a400Schristos 									\
342*6881a400Schristos   template <typename enum_type, typename U>				\
343*6881a400Schristos   constexpr bool							\
344*6881a400Schristos   OPERATOR_OP (enum_flags<enum_type> lhs, U rhs) = delete;		\
345*6881a400Schristos 									\
346*6881a400Schristos   /* other OP enum_flags */						\
347*6881a400Schristos 									\
348*6881a400Schristos   template <typename enum_type>						\
349*6881a400Schristos   constexpr bool							\
350*6881a400Schristos   OPERATOR_OP (enum_type lhs, enum_flags<enum_type> rhs)		\
351*6881a400Schristos   { return lhs OP rhs.raw (); }						\
352*6881a400Schristos 									\
353*6881a400Schristos   template <typename enum_type>						\
354*6881a400Schristos   constexpr bool							\
355*6881a400Schristos   OPERATOR_OP (int lhs, enum_flags<enum_type> rhs)			\
356*6881a400Schristos   { return lhs OP rhs.raw (); }						\
357*6881a400Schristos 									\
358*6881a400Schristos   template <typename enum_type, typename U>				\
359*6881a400Schristos   constexpr bool							\
360*6881a400Schristos   OPERATOR_OP (U lhs, enum_flags<enum_type> rhs) = delete;
361*6881a400Schristos 
362*6881a400Schristos ENUM_FLAGS_GEN_COMP (operator==, ==)
363*6881a400Schristos ENUM_FLAGS_GEN_COMP (operator!=, !=)
364*6881a400Schristos 
365*6881a400Schristos /* Unary operators for the raw flags enum.  */
366*6881a400Schristos 
367*6881a400Schristos /* We require underlying type to be unsigned when using operator~ --
368*6881a400Schristos    if it were not unsigned, undefined behavior could result.  However,
369*6881a400Schristos    asserting this in the class itself would require too many
370*6881a400Schristos    unnecessary changes to usages of otherwise OK enum types.  */
371*6881a400Schristos template <typename enum_type,
372*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>,
373*6881a400Schristos 	  typename
374*6881a400Schristos 	    = gdb::Requires<enum_flags_detail::EnumIsUnsigned<enum_type>>>
375*6881a400Schristos constexpr enum_type
3767d62b00eSchristos operator~ (enum_type e)
3777d62b00eSchristos {
378*6881a400Schristos   using underlying = typename enum_flags<enum_type>::underlying_type;
379*6881a400Schristos   return (enum_type) ~underlying (e);
3807d62b00eSchristos }
3817d62b00eSchristos 
382*6881a400Schristos template <typename enum_type,
383*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>,
384*6881a400Schristos 	  typename = gdb::Requires<enum_flags_detail::EnumIsSigned<enum_type>>>
385*6881a400Schristos constexpr void operator~ (enum_type e) = delete;
386*6881a400Schristos 
387*6881a400Schristos template <typename enum_type,
388*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>,
389*6881a400Schristos 	  typename
390*6881a400Schristos 	    = gdb::Requires<enum_flags_detail::EnumIsUnsigned<enum_type>>>
391*6881a400Schristos constexpr enum_flags<enum_type>
392*6881a400Schristos operator~ (enum_flags<enum_type> e)
393*6881a400Schristos {
394*6881a400Schristos   using underlying = typename enum_flags<enum_type>::underlying_type;
395*6881a400Schristos   return (enum_type) ~underlying (e);
396*6881a400Schristos }
397*6881a400Schristos 
398*6881a400Schristos template <typename enum_type,
399*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>,
400*6881a400Schristos 	  typename = gdb::Requires<enum_flags_detail::EnumIsSigned<enum_type>>>
401*6881a400Schristos constexpr void operator~ (enum_flags<enum_type> e) = delete;
402*6881a400Schristos 
403*6881a400Schristos /* Delete operator<< and operator>>.  */
404*6881a400Schristos 
405*6881a400Schristos template <typename enum_type, typename any_type,
406*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>>
407*6881a400Schristos void operator<< (const enum_type &, const any_type &) = delete;
408*6881a400Schristos 
409*6881a400Schristos template <typename enum_type, typename any_type,
410*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>>
411*6881a400Schristos void operator<< (const enum_flags<enum_type> &, const any_type &) = delete;
412*6881a400Schristos 
413*6881a400Schristos template <typename enum_type, typename any_type,
414*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>>
415*6881a400Schristos void operator>> (const enum_type &, const any_type &) = delete;
416*6881a400Schristos 
417*6881a400Schristos template <typename enum_type, typename any_type,
418*6881a400Schristos 	  typename = is_enum_flags_enum_type_t<enum_type>>
419*6881a400Schristos void operator>> (const enum_flags<enum_type> &, const any_type &) = delete;
420*6881a400Schristos 
4217d62b00eSchristos #else /* __cplusplus */
4227d62b00eSchristos 
4237d62b00eSchristos /* In C, the flags type is just a typedef for the enum type.  */
4247d62b00eSchristos 
4257d62b00eSchristos #define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \
4267d62b00eSchristos   typedef enum_type flags_type
4277d62b00eSchristos 
4287d62b00eSchristos #endif /* __cplusplus */
4297d62b00eSchristos 
4307d62b00eSchristos #endif /* COMMON_ENUM_FLAGS_H */
431