473,763 Members | 3,712 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

typesafe bitwise operations based on enums

Hi,
I just wanted to share another library for doing type-safe bitwise
operations in C++:
http://bitwise-enum.googlecode.com

I found it useful, so hopefully it'll be for somebody else as well.

BRgds,
Daniel.
Jan 10 '08 #1
8 8792
On Jan 10, 2:06 pm, Daniel Gutson <danielgut...@g mail.comwrote:
I just wanted to share another library for doing type-safe bitwise
operations in C++:
http://bitwise-enum.googlecode.com
Well, it has a number of problems. The most basic one is, of
course, that the results of or'ing or and'ing an enum aren't the
expected type. And of course, it fails for some enums.

What's wrong with just:

#define defineEnumOps( Enum, Underlying ) \
inline \
Enum operator|( Enum lhs, Enum rhs ) \
{ \
return static_cast< Enum >( \
static_cast< Underlying >( lhs ) \
| static_cast< Underlying >( rhs ) ) ; \
} \
inline \
Enum& operator|=( Enum& lhs, Enum rhs ) \
{ \
lhs = lsh | rhs ; \
return lsh ; \
} \
// and so on...

I've got code which actually parses the source file and
generates the operators directly, rather than using a #define.
But that's only because it was easy to add this to my code which
generated the enum<->string mappings---once you have the parser
and all of the information, generating the above is trivial, but
it's not worth writing all that for just the operators.

The real difficult is, of course, the underlying type. You're
probably safe using "unsigned long" in all cases, unless the
compiler also supports long long. I've found it acceptable to
require the user to provide it (defaulting to unsigned int in
the case of the code generator).

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 10 '08 #2
James Kanze wrote:
On Jan 10, 2:06 pm, Daniel Gutson <danielgut...@g mail.comwrote:
> I just wanted to share another library for doing type-safe bitwise
operations in C++:
http://bitwise-enum.googlecode.com

Well, it has a number of problems. The most basic one is, of
course, that the results of or'ing or and'ing an enum aren't the
expected type. And of course, it fails for some enums.

What's wrong with just:

#define defineEnumOps( Enum, Underlying ) \
inline \
Enum operator|( Enum lhs, Enum rhs ) \
{ \
return static_cast< Enum >( \
static_cast< Underlying >( lhs ) \
| static_cast< Underlying >( rhs ) ) ; \
} \
inline \
Enum& operator|=( Enum& lhs, Enum rhs ) \
{ \
lhs = lsh | rhs ; \
return lsh ; \
} \
// and so on...
<snip>

I have not read the implementation, but from the example on the site seems
that the library is intended for a different purpose then what your code is
for. It's not suposed to be used when as the result of a bitwise operation
it results the same enum type (as you said that that does not make sense
all the time) it is only made so that you can "safely" declare a function
saying that this function should take an integral value that is the result
of bitwise operations of this enum. I supose the function knowing this can
assume various things on that integral and work with it in some specific
way.

Tho I am not even sure that the library does achieve that (or if it is
possible to achieve it).

--
Dizzy

Jan 10 '08 #3
On 2008-01-10 10:47:47 -0500, Daniel Gutson <da**********@g mail.comsaid:
- however, grouping related (and combinable) bitmasks is not
'typesafe': if a function receives a mask of LEDs bits, and another
receives a mask of FANs bits, no matter if you group the bits in
different enumerations, once you or them, you'll loose the type.
That doesn't happen if you overload the bitwise operators for your
enumerated type.
>
My library tries to solve this:
given the enums above, you can then:

typedef bitwise_enum<LE D_BITSLeds_mask ;
typedef bitwise_enum<FA N_BITSFans_mask ;

void set_leds(Leds_m ask mask);
void turn_fans(Fans_ mask mask);

int main() {
set_leds(GREEN_ LED | KITCHEN_FAN); // Compiler error
}

Moreover, you can now overload functions depending on the mask.

Hope it's clearer now! And thanks Dizzy for helping me to clarify.
It's clearer, but what's the advantage of this approach over defining
operator| and operator& for the enum type, and simply writing functions
that take that enum?

LED_BITS operator|(LED_B ITS left, LED_BITS right)
{
return static_cast<LED _BITS>(left | right);
}

LED_BITS operator&(LED_B ITS left, LED_BITS right)
{
return static_cast<LED _BITS>(left & right);
}

void set_leds(LED_BI TS mask);
set_leds(GREEN_ LED | KITCHEN_FAN); // compiler error

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jan 10 '08 #4
On Jan 10, 1:56*pm, Pete Becker <p...@versatile coding.comwrote :
On 2008-01-10 10:47:47 -0500, Daniel Gutson <danielgut...@g mail.comsaid:
*- however, grouping related (and combinable) bitmasks is not
'typesafe': if a function receives a mask of LEDs bits, and another
receives a mask of FANs bits, no matter if you group the bits in
different enumerations, once you or them, you'll loose the type.

That doesn't happen if you overload the bitwise operators for your
enumerated type.


My library tries to solve this:
given the enums above, you can then:
typedef bitwise_enum<LE D_BITSLeds_mask ;
typedef bitwise_enum<FA N_BITSFans_mask ;
void set_leds(Leds_m ask mask);
void turn_fans(Fans_ mask mask);
int main() {
* set_leds(GREEN_ LED | KITCHEN_FAN); * // Compiler error
}
Moreover, you can now overload functions depending on the mask.
Hope it's clearer now! And thanks Dizzy for helping me to clarify.

It's clearer, but what's the advantage of this approach over defining
operator| and operator& for the enum type, and simply writing functions
that take that enum?

LED_BITS operator|(LED_B ITS left, LED_BITS right)
{
return static_cast<LED _BITS>(left | right);

}

LED_BITS operator&(LED_B ITS left, LED_BITS right)
{
return static_cast<LED _BITS>(left & right);

}

void set_leds(LED_BI TS mask);
set_leds(GREEN_ LED | KITCHEN_FAN); * * *// compiler error

--
* Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)- Hide quoted text -

- Show quoted text -
Hi Pete.
I don't like having enum variables holding values that are not enums.
That's a hack. And I simply think that the right way to do that is a
class. Why not? It doesn't add any overhead, neither does any wrong.

Daniel.
Jan 10 '08 #5
On 2008-01-10 11:08:15 -0500, Daniel Gutson <da**********@g mail.comsaid:
I don't like having enum variables holding values that are not enums.
That's a hack.
It's an intended property of enum types. Each enum's underlying type is
required to be large enough to hold all the bits that make up every
value (that's not exactly the requirement, but you get the point),
precisely so that this kind of code will work.
And I simply think that the right way to do that is a
class. Why not? It doesn't add any overhead, neither does any wrong.
It adds mental overhead, having to remember that objects of type
LED_BITS combine to create objects of type bitwise_enum<LE D_BITS>.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jan 10 '08 #6
class. Why not? It doesn't add any overhead, neither does any wrong.
>
It adds mental overhead, having to remember that objects of type
LED_BITS combine to create objects of type bitwise_enum<LE D_BITS>.
C'mon man!! Don't be that lazy! :D
Do a typedef and you're done!!

Daniel.
Jan 10 '08 #7
On 2008-01-10 12:20:49 -0500, Daniel Gutson <da**********@g mail.comsaid:
>>class. Why not? It doesn't add any overhead, neither does any wrong.

It adds mental overhead, having to remember that objects of type
LED_BITS combine to create objects of type bitwise_enum<LE D_BITS>.

C'mon man!! Don't be that lazy! :D
Sigh.
Do a typedef and you're done!!
Whatever you call it, it's two different names, wiht different
properties, for what should be the same thing.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jan 10 '08 #8
On Jan 10, 5:08 pm, Daniel Gutson <danielgut...@g mail.comwrote:
I don't like having enum variables holding values that are not
enums. That's a hack.
It's a design feature of C++ enums. A C++ enum is not (just) an
enumerated type. I agree that the language would be clearer if
it distinguished between enumerated types and bitmap types, but
it doesn't. The keyword enum is used for both.
And I simply think that the right way to do that is a class.
Why not? It doesn't add any overhead, neither does any wrong.
If you're going that route (and I can understand it), then
wouldn't the "correct" solution be something like:

class Leds
{
public:
static Leds const redLed ;
static Leds const greenLed ;
static Leds const blueLed ;

Leds() ; // all off.
Leds( Leds const& other ) ;
Leds& operator|=( Leds const& other ) ;
Leds& operator&=( Leds const& other ) ;
freind Leds operator~( Leds const& op ) ;

private:
unsigned int myValue ;
explicit Leds( unsigned int value ) ;
} ;

Leds operator|( Leds const& lhs, Leds const& rhs ) ;
Leds operator&( Leds const& lhs, Leds const& rhs ) ;

Internally, you use bits and a bit mask on myValue, but all the
user sees is some values which he can manipulate:

Leds l1 ;
l1 |= redLed ;
Leds l2( l1 | greenLed ) ;

It seems a bit heavy to me, but it's certainly the most
"correct" in the abstract sense. And if you need to do it a
lot... it would take about ten minutes to write an AWK script to
generate the class, given the class name and a list of its
(constant) values.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 11 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
6940
by: Paul E Collins | last post by:
Suppose I have a few Keys objects: Keys k1 = Keys.V; // V Keys k2 = Keys.Control | Keys.V; // Ctrl+V Keys k3 = Keys.Shift | Keys.J; // Shift+J I need to determine which of these include the Keys.V element, regardless of any other keys. I know it will be a bitwise comparison, but I can't work out the correct syntax to use.
9
7030
by: Christopher Weaver | last post by:
I know that the bitwise AND of 8 and 4 will return 0 or false and the bitwise AND of 8 and 9 will return 1 or true but I don't know how to write the synax for it in C#. I have a value that ranges from 0 to 15 and I need to compare it to 15 in order to find if it contains the values 1, 2, 4, or 8. To represent it more graphically, the value 1010 when ANDed with 1000 or 0010 will produce either true or a value greater than 0. I believe...
2
2326
by: Random | last post by:
I need to apply a filterparameter to a result set in my GridView based on the selection in a DropDownList control. I want to use the integer SelectedValue property of the DropDownList to filter the grid based on a bitwise comparator. I could just do this in my query select statement, but I want to cache the overall result set for faster subquery operations. In T-SQL the bitwise comparator is the ampersand (&), but I am getting an...
4
1885
by: AMDRIT | last post by:
Gang, I always get confused when it comes to 1's and 0's. I would like to perform a bitwise operation on a value based on checked boxes. Am I doing this right? assuming TurmsRemote.Weekdays has values of
17
2365
by: zirconx | last post by:
I'm trying to understand how the bitwise AND can be used. I've read about what it does but am having trouble applying it practically. I'm working on a system that somebody else wrote and they make use of a MODE flag that gets passed in. They then compare the mode flag against a hard coded value using bitwise AND, and then show or don't show certain features based on the mode. Example pseudocode: if (mode & 1) do something if (mode...
34
11201
by: Steven Nagy | last post by:
So I was needing some extra power from my enums and implemented the typesafe enum pattern. And it got me to thinking... why should I EVER use standard enums? There's now a nice little code snippet that I wrote today that gives me an instant implementation of the pattern. I could easily just always use such an implementation instead of a standard enum, so I wanted to know what you experts all thought. Is there a case for standard enums?
45
5301
by: Carramba | last post by:
Hi! I now that I can't do straight forward any bitwise operation on float (double etc..). But I wondering what is the easiest/best way to do this? I was thinking if I have float x=1.1111 so I can multiple it by 1000 to get 11111 and the preform bitwise like <<2 to get 88888 and then divide by 1000 to go back to float 8.8888. but these seem like "nasty" way to do it. So maybe some of you have great tips? Thank you in advance! L R
8
1589
by: Travis | last post by:
I don't have too much experience with bitwise operations. Here is what I'm trying to accomplish. I have enum say: enum myEnum { BILL = 0, KATIE = 1, JOHN = 2 } Then I have an int that represents some combination of that enum, like: int WhoIsAllowed = BILL | KATIE | JOHN;
29
5952
by: Carl Banks | last post by:
Anyone with me here? (I know the deadline for P3 PEPs has passed; this is just talk.) Not many people are bit-fiddling these days. One of the main uses of bit fields is flags, but that's not often done in Python because of keyword arguments and dicts, which are lot more versatile. Another major use, talking to hardware, is not something oft done in Python either. It seems like this occasional usage wouldn't justify having built-in...
0
10145
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9998
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9938
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9822
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8822
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7366
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5270
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
3523
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2793
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.