Apple sometimes uses the Bitwise-Shift operator in their enum definitions. For example, in the CGDirectDisplay.h file which is part of Core Graphics:
enum {
kCGDisplayBeginConfigurationFlag = (1 << 0),
kCGDisplayMovedFlag = (1 << 1),
kCGDisplaySetMainFlag = (1 << 2),
kCGDisplaySetModeFlag = (1 << 3),
kCGDisplayAddFlag = (1 << 4),
kCGDisplayRemoveFlag = (1 << 5),
kCGDisplayEnabledFlag = (1 << 8),
kCGDisplayDisabledFlag = (1 << 9),
kCGDisplayMirrorFlag = (1 << 10),
kCGDisplayUnMirrorFlag = (1 << 11),
kCGDisplayDesktopShapeChangedFlag = (1 << 12)
};
typedef uint32_t CGDisplayChangeSummaryFlags;
Why not simply use incrementing int's like in a "normal" enum?
The bitwise shift operators move the bit values of a binary object. The left operand specifies the value to be shifted. The right operand specifies the number of positions that the bits in the value are to be shifted. The result is not an lvalue.
Because they allow greater precision and require fewer resources, bitwise operators can make some code faster and more efficient. Examples of uses of bitwise operations include encryption, compression, graphics, communications over ports/sockets, embedded systems programming and finite state machines.
Bit shifting is an operation done on all the bits of a binary value in which they are moved by a determined number of places to either the left or right. Bit shifting is used when the operand is being used as a series of bits rather than as a whole.
C# provides 4 bitwise and 2 bit shift operators. Bitwise and bit shift operators are used to perform bit level operations on integer (int, long, etc) and boolean data. These operators are not commonly used in real life situations.
Maybe writing the values in hexadecimal (or binary) helps :-)
enum { kCGDisplayBeginConfigurationFlag = (1 << 0), /* 0b0000000000000001 */ kCGDisplayMovedFlag = (1 << 1), /* 0b0000000000000010 */ kCGDisplaySetMainFlag = (1 << 2), /* 0b0000000000000100 */ kCGDisplaySetModeFlag = (1 << 3), /* 0b0000000000001000 */ kCGDisplayAddFlag = (1 << 4), /* 0b0000000000010000 */ kCGDisplayRemoveFlag = (1 << 5), /* 0b0000000000100000 */ kCGDisplayEnabledFlag = (1 << 8), /* 0b0000000100000000 */ kCGDisplayDisabledFlag = (1 << 9), /* 0b0000001000000000 */ kCGDisplayMirrorFlag = (1 << 10),/* 0b0000010000000000 */ kCGDisplayUnMirrorFlag = (1 << 11),/* 0b0000100000000000 */ kCGDisplayDesktopShapeChangedFlag = (1 << 12) /* 0b0001000000000000 */ };
Now you can add them (or "or" them) and get different values
kCGDisplayAddFlag | kCGDisplayDisabledFlag /* 0b0000001000010000 */
This way you can add multiple flags together to create a "set" of flags and can then use &
to find out whether any given flag is in such a set.
You couldn't do that if it simply used incrementing numbers.
Example:
int flags = kCGDisplayMovedFlag | kCGDisplaySetMainFlag; // 6 if(flags & kCGDisplayMovedFlag) {} // true if(flags & kCGDisplaySetModeFlag) {} // not true
New in C# 7 is finally adding binary literals, so you can just write it as this:
enum MyEnum
{
kCGDisplayBeginConfigurationFlag = 0b0000000000000001;
kCGDisplayMovedFlag = 0b0000000000000010;
kCGDisplaySetMainFlag = 0b0000000000000100;
kCGDisplaySetModeFlag = 0b0000000000001000;
kCGDisplayAddFlag = 0b0000000000010000;
kCGDisplayRemoveFlag = 0b0000000000100000;
kCGDisplayEnabledFlag = 0b0000000001000000;
kCGDisplayDisabledFlag = 0b0000000010000000;
kCGDisplayMirrorFlag = 0b0000000100000000;
kCGDisplayUnMirrorFlag = 0b0000001000000000;
kCGDisplayDesktopShapeChangedFlag = 0b0000010000000000;
};
And if you want to make things even neater, you use this: _
which is also new to C# 7, which allows you to put spaces in numbers to make things more readable, like so:
enum MyEnum
{
kCGDisplayBeginConfigurationFlag = 0b_0000_0000_0000_0001;
kCGDisplayMovedFlag = 0b_0000_0000_0000_0010;
kCGDisplaySetMainFlag = 0b_0000_0000_0000_0100;
kCGDisplaySetModeFlag = 0b_0000_0000_0000_1000;
kCGDisplayAddFlag = 0b_0000_0000_0001_0000;
kCGDisplayRemoveFlag = 0b_0000_0000_0010_0000;
kCGDisplayEnabledFlag = 0b_0000_0000_0100_0000;
kCGDisplayDisabledFlag = 0b_0000_0000_1000_0000;
kCGDisplayMirrorFlag = 0b_0000_0001_0000_0000;
kCGDisplayUnMirrorFlag = 0b_0000_0010_0000_0000;
kCGDisplayDesktopShapeChangedFlag = 0b_0000_0100_0000_0000;
};
Makes it so much easier to keep track of the numbers.
If you have FlagA=1, FlagB=2 and FlagC=3, FlagA or FlagB would give the same value as FlagC. The shift operator is used to ensure that every combination of flags is unique.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With