Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 standard conformant bitmasks using enum class

Can you implement standard conformant (as described in 17.5.2.1.3 of the n3242 draft) type safe bitmasks using enum class? The way I read it, a type T is a bitmask if it supports the |,&,^,~,|=,&= and ^= operators and further you can do if(l&r) where l and r are of type T. Missing from the list are the operator != and == and to allow sorting one probably also wants to overload <.

Getting the operators to works is just annoying boilerplate code but I do not see how to do if(l&r). At least the following does not compile with GCC (besides being extremely dangerous as it allows an erroneous implicit conversion to int):

enum class Foo{     operator bool(){         return (unsigned)*this;     } }; 

EDIT: I now know for certain that enum classes can not have members. The actual question how to do if(l&r) remains though.

like image 347
B.S. Avatar asked Aug 21 '12 17:08

B.S.


People also ask

Is enum class A class C++?

enum class is not a class definition - the combination of keywords is used to define a scoped enumeration, which is a completely separate entity from a class .

What is a bitmask enum?

Bitmask enums are a way of organizing flags. Like having a collection of booleans without having to keep track of a dozen different variables. They are fast and compact, so generally good for network related data.

What are enum classes in C++?

In C++ programming, enum or enumeration is a data type consisting of named values like elements, members, etc., that represent integral constants. It provides a way to define and group integral constants.


1 Answers

I think you can... You'll have to add operators for bitmasky things. I didn't do it here but you could easily overload any relational operator.

  /**    *    */   // NOTE: I changed to a more descriptive and consistent name   //       This needs to be a real bitmask type.   enum class file_permissions : int   {     no_perms        = 0,      owner_read      =  0400,     owner_write     =  0200,     owner_exe       =  0100,     owner_all       =  0700,      group_read      =   040,     group_write     =   020,     group_exe       =   010,     group_all       =   070,      others_read     =    04,     others_write    =    02,     others_exe      =    01,     others_all      =    07,      all_all     = owner_all | group_all | others_all, // 0777      set_uid_on_exe  = 04000,     set_gid_on_exe  = 02000,     sticky_bit      = 01000,      perms_mask      = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit, // 07777      perms_not_known = 0xffff,      add_perms       = 0x1000,     remove_perms    = 0x2000,     symlink_perms   = 0x4000   };    inline constexpr file_permissions   operator&(file_permissions x, file_permissions y)   {     return static_cast<file_permissions>       (static_cast<int>(x) & static_cast<int>(y));   }    inline constexpr file_permissions   operator|(file_permissions x, file_permissions y)   {     return static_cast<file_permissions>       (static_cast<int>(x) | static_cast<int>(y));   }    inline constexpr file_permissions   operator^(file_permissions x, file_permissions y)   {     return static_cast<file_permissions>       (static_cast<int>(x) ^ static_cast<int>(y));   }    inline constexpr file_permissions   operator~(file_permissions x)   {     return static_cast<file_permissions>(~static_cast<int>(x));   }    inline file_permissions &   operator&=(file_permissions & x, file_permissions y)   {     x = x & y;     return x;   }    inline file_permissions &   operator|=(file_permissions & x, file_permissions y)   {     x = x | y;     return x;   }    inline file_permissions &   operator^=(file_permissions & x, file_permissions y)   {     x = x ^ y;     return x;   } 
like image 50
emsr Avatar answered Sep 19 '22 11:09

emsr