Weird Enumeration

Started by
12 comments, last by adder_noir 13 years, 8 months ago
Hi check this out:

enum{	// I use this ISceneNode ID to indicate a scene node that is	// not pickable by getSceneNodeAndCollisionPointFromRay()	ID_IsNotPickable = 0,	// I use this flag in ISceneNode IDs to indicate that the	// scene node can be picked by ray selection.	IDFlag_IsPickable = 1 << 0,	// I use this flag in ISceneNode IDs to indicate that the	// scene node can be highlighted.  In this example, the	// homonids can be highlighted, but the level mesh can't.	IDFlag_IsHighlightable = 1 << 1};


What's going on? I thought enums where mean to just be integer based I don't get the whole 1 << 1 thing. I thought enums just went 0 upwards by 1 unless stated I didn't know you could *do* stuff inside them. Any idea what's happening here? Thanks :oO/:o)
Advertisement
Quote:Original post by adder_noir
Hi check this out:

*** Source Snippet Removed ***

What's going on? I thought enums where mean to just be integer based I don't get the whole 1 << 1 thing. I thought enums just went 0 upwards by 1 unless stated I didn't know you could *do* stuff inside them. Any idea what's happening here? Thanks :oO/:o)
The x << y syntax means to shift the bits in x to the left by the number in y. For example, if you had the binary number 11 (3 in decimal) and shifted it by 4 you would get the new binary number 110000 (48 in decimal).

The exact purpose of the code you showed was to make 'bit flags' which you can read about in greater detail here.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Nope, you can define enums anyway you like. This example is a flag enum (or whatever you call them), i.e. you can mask them with bitwise operators: & behaves like a set intersection, | like a set union). You can use any expression (I think) to define an enum's value, here done with arithmetic shift left, which is the same as saying 2x:

1 << 0 == 20 == 1
1 << 1 == 21 == 2


(Disclaimer: I hardly use C++ so I might miss some minor details, but they behave similar in C#)


...ninja-ed again...
Very nice replies both of you thanks!
I see. So he's storing his flags within the same byte kind of thing? Is this some means of compression or is this just how it's done?

That << is raising a power essentially.
The idea is to save space, so it could indeed be called a form of compression. However, when a programmer hears 'compression', he'll usually think about algorithms to compress arbitrary data (RLE, zip files and much more complicated things like that). So maybe calling it 'compression' is a bit extreme :)
Quote:Original post by adder_noir
I see. So he's storing his flags within the same byte kind of thing? Is this some means of compression or is this just how it's done?

That << is raising a power essentially.


This is called "bit packing" iirc. It's used to switch on/off separate bits in a data type used as flags. Frankly, not only flags. In the older times, these were used to pack multiple variables into one to save on bandwidth.

[a relatively bad example ;D ]
Say you have 2 int values and none of them use more than 2 bytes (assuming int is defined as 4 bytes). You would take one of the int values, shift it 2 bytes to the left, combine it with the other int via bitwise OR, and shoot it out across the internet where the recipient performs this operation backwards.

Yo dawg, don't even trip.

Sounds great! So something you could use to optimise networking code?

Big thanks to all who have replied by the way ;o)
It's more than standard way of storing flags than it is compression. Nothing is really being compressed here; you only need 1 bit to store a simple on/off flag. Nothing has been compressed by storing 8 flags in 8 bits.

The << notation was used because it is less prone to screw ups.
The average person is much less likely to screw up the values when dealing with a consecutive list, i.e.

enum{a = 1 << 0,b = 1 << 1,c = 1 << 2,d = 1 << 3,...};


than

enum{a = 1,b = 2,c = 4,d = 8,...};


[Edited by - 1863 on August 26, 2010 10:14:13 AM]
Using bitflags in enum definitions is barely the tip of the iceberg. A lot of template meta-programming uses enums to essentially construct programs that run at compile time, producing a fixed result that gets compiled into the final executable.
Simply throw in C++ templates and template specialisation, as well. A basic example:
template <unsigned n> struct factorial {	enum {		ret = factorial<n-1>::ret * n	};};template <> struct factorial<0> {	enum {		ret = 1	}; };assert(factorial<5>::ret == 120);
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement