SlideShare a Scribd company logo
Take a quick look at the following code:
typedef enum style
{
plain,
bold,
italic,
underline = 4,
strikethrough = 8,
small_caps = 16
} style;
What language is it in? It could be C or C++,
although the style is clearly C-like; C++ does not
need all that typedef noise to obtain a usable type name.
The following code fragments fix the language:
style selected = plain;
...
selected |= italic;
...
if(selected & bold)
...
It’s C. To be precise, it’s common but not particu-
larly good C.The code demonstrates a weakness of the
type system that encourages sloppy design. Unfortu-
nately, given the enduring C influence on C++ cod-
ing practices, this style for flags and sets of flags is also
prevalent in C++. C++ programmers without a C
background can acquire these habits by osmosis
from their C-speaking colleagues or through C-influ-
enced libraries.
Flag poll
First, some quick explanation and a little bit of
reformatting. As its name suggests, an enum is nor-
mally used to enumerate a set of constants. By default,
the enumerators have distinct values, starting at 0 and
rising by 1 for each successive enumerator. Alterna-
tively, an enumerator can be given a specific constant
integer value.
A common approach for holding a set of binary
options is to treat an integer value as a collection of bits,
ignoring its numeric properties. If a bit at a particular
position is set, the option represented by that position
is enabled.This duality is common at the systems pro-
gramming level and many programmers never think
to question it. C programmers and, indeed, C com-
pilers make little distinction between enumerators,
integers, flags and bit sets.
An enum is often used to list the distinct options
in a bit set, but instead of acting as distinct symbols,
enumerator constants are used to represent bit masks.
This brings us to the first bit of laziness to tidy up in
the original enum definition. As it happens, the first
three values form the sequence 0, 1 and 2, which spec-
ifies no bits, the first bit and the second bit respec-
tively. Each integer power of 2, from 0 up, represents
a different bit. To make it clear that the enumerators
do not form a conventional sequence, but instead rep-
resent bit masks, developers typically set the mask val-
ues explicitly. As neither C nor C++ supports binary
literals, it is more common to use hexadecimal rather
than either decimal or octal to define the constants:
enum style
{
plain,
bold = 0x01,
italic = 0x02,
underline = 0x04,
strikethrough = 0x08,
small_caps = 0x10
};
Since the aim of this column is to reconsider how
we work with flags in C++, I have also taken the
small liberty of dropping the C-ish typedef. Let’s look
at another common approach to specifying the enu-
merators, that makes the basic idea of sequence (bit 0,
bit 1, bit 2 etc) a little more explicit:
enum style
{
plain,
bold = 1 << 0,
italic = 1 << 1,
underline = 1 << 2,
strikethrough = 1 << 3,
56 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.co.uk
Kevlin Henney is an
independent software
development consultant
and trainer.He can be
reached at
www.curbralan.com
C++ WORKSHOP
q C habits still affect C++ style, such as
how to work with flags.
q C++’s stronger type checking makes the
C use of enums as bit sets somewhat
awkward.
q The standard library’s bitset template
provides a simpler and more direct
implementation for sets of flag options.
q Programmers can define their own types
for holding bit sets based on std::bitset.
q Trait classes and policy parameters allow
for flexible implementation.
FACTS AT A GLANCE
Using enum to manage bit sets works fine in C, but things become a little more
complex in C++. Kevlin Henney explains an alternative method of handling
flags, using the bitset template
Flag waiving
small_caps = 1 << 4
};
This approach makes the bit-masking purpose of the enumera-
tors a little clearer.The relationship to integers and ordinary count-
ing numbers is less interesting than the shifted position of a set bit.
But what about the code that shows how the style flags are used? Alas,
the following won’t compile:
selected |= italic;
This fails because enum and integer types are not interchangeable:
arithmetic and bitwise operators do not apply to enums. When you
use an enum where an integer is expected, you get an implicit con-
version to the enum’s associated integer value, in effect:
static_cast<int>(selected) |= static_cast<int>(italic);
When integers go bad
While there is not much wrong with using an enum as an inte-
ger, there is plenty wrong with using an integer as an enum.
Every enumerator will map to a valid integer value but not every
valid integer will map to a valid enumerator.That’s why C++ banned
the implicit conversion from integer to enum and why the code
shown won’t compile. So how do you make it compile? You can
force the compiler to succumb to your wicked way with a cast as
your accomplice:
selected = static_cast<style>(selected | italic);
It would be fair to say this lacks both grace and convenience.
Alternatively, you could overload the bitwise or operators to do
your bidding:
style operator|(style lhs, style rhs)
{
return static_cast<style>(int(lhs) | int(rhs));
}
style &operator|=(style &lhs, style rhs)
{
return lhs = lhs | rhs;
}
This will allow the code to compile in its original form, but you
should not forget to define the other relevant bitwise operators. One
problem with this approach is that you need to define these
operators anew for every enum type you want to use as a bit set. And
what do you do for the definition of the bitwise not operator?This
is used to ensure that a bit is disabled:
selected &= ~italic;
What should the value of ~italic be? bold | underline | strikethrough
| small_caps or ~int(italic)? The former includes only bits that
have been defined as valid for the bit set, but the latter is a simpler
interpretation of the bit set concept.
A quick aside on cast style: the constructor-like form, eg int(italic)
is used where the conversion is safe and would otherwise be
implicit. You are constructing an int from a style.The keyword cast
form, static_cast, is being used where the conversion is potentially
unsafe and we are taking liberties with the type system.
Which brings us neatly to the next point: we are messing with the
typesystem.Thereisanunderlyingreasonwhywearehavingtoperform
with a cast of thousands: the design is flawed. If you recall, the style
type is an enumeration type. In other words, it enumerates the intended
legal values of a style variable that is designed to hold one of the
enumerator values at a time. However, the common practice uses
a style variable to hold not an option but a set of options. While the
bit representation of an enum affords such usage, it is by default a
type error that is fundamentally a category error: a thing and a collection
of things are different types.
This answers the question of why plain is not really a valid enu-
merator for style. It represents a combination of options (or, rather,
their absence); it is a set rather than an individual option.The canon-
ical C type for a bit set is the integer, signed or otherwise, but the
C’slaxtypesystemallowsthefreeandeasymixingofunrelatedconcepts.
Here is the revised code:
const unsigned plain = 0;
...
unsigned selected = plain;
...
selected |= italic;
...
if(selected & bold)
...
However, what the other approaches lacked in grace, the inte-
ger bit set loses in safety and precision.There is nothing that constrains
the actual use of an unsigned to be the same as its intended use.
Taking a step back from these many variations, you may realise
the nagging truth: it’s all a bit of a hack. Why should you be man-
ually organising your constants according to bit masks at all? It is
easy to become rooted in only one form of thinking. Sometimes a
freshlookwillhelpyoubreakoutofaruttoamoreappropriatesolution.
Let’s leave C behind.
It’s time to get back to basics, ignoring all this bitwise gymnas-
tics, and restate the core problem: you need to hold a set of options,
each of which is effectively Boolean.This suggests a simple solution:
hold a set of options.
enum style
{
bold, italic, underline, strikethrough, small_caps
};
...
std::set<style> selected;
...
selected.insert(italic);
...
if(selected.count(bold))
...
This method is a lot simpler to work with: the style type sim-
ply enumerates the options with no hard coding of literal values.
The standard set class template allows a set of options to be
manipulated as a type-checked set rather than at the systems
programming level. In other words, the language and library do
all the work for you.
Honing for efficiency
Functionally, there are no problems with this approach, but
many programmers may justifiably have concerns over its efficiency.
The bitwise solution required an integer for storage, no additional
dynamic memory usage, and efficient, fixed-time manipulation
of the options. In contrast, an std::set is an associative node-based
container that uses dynamic memory for its representation.
If you hold these space and time efficiency concerns (and have
good reason to), all is not lost: you can still have abstraction and
efficiency. The flat_set class template presented in the last column1
is an improvement over std::set for this purpose. But better still
is the standard bitset template:
APRIL 2002 57
C++ WORKSHOP
std::bitset<5> selected;
...
selected.set(italic);
...
if(selected.test(bold))
...
The std::bitset class template, defined in the standard <bitset> header,
is not a part of the STL, hence the seemingly non-standard member
function names. But it is still standard and it still solves the
problem. A more legitimate obstacle is that the size of the set must
be wired in at compile time. There is also nothing that constrains
you to working with the style type.
There is a simple hack that allows you to avoid having to count
the number of enumerators:
enum style
{
bold, italic, underline, strikethrough, small_caps,
_style_size
};
...
std::bitset<_style_size> selected;
...
I say this is a hack because you are using the property of enumerators
tocount,bydefault,instepsof1from0.Thelastenumerator,_style_size,
is not really part of the valid set of enumerators because it does not
represent an option. However, in its favour, this technique does
save you from many of the ravages of change: the addition or
removal of enumerators and any consequent change to the declared
size of the bitset.
Rhyme and treason
Now I think we have a better idea of what is needed: something
that works like a type-safe bitset for enums. Alas, we won’t find one
of these in the standard so we will have to create it. Let’s start with
the intended usage:
enum_set<style> selected;
...
selected.set(italic);
...
if(selected.test(bold))
...
It seems reasonable enough to follow the std::bitset interface
because the two are conceptually related. Additionally, a const
subscript operator would make its use even more intuitive:
if(selected[bold])
...
To save on all the bit twiddling, we can use std::bitset as the
representation of our enum_set. However, a quick sketch reveals
a problem:
template<typename enum_type>
class enum_set
{
...
private:
std::bitset<???> bits;
};
How big should the bitset be? One unsatisfactory solution would
be to require the user to provide the size as well as the type, ie:
enum_set<style, _style_size> selected;
This is clumsy and smacks of redundancy. We state the type and
then a property of the type, relying in this case on a little hack to
keep everything in sync. It would be nice to look up the relevant type
properties based on the type name, so that the type is all the user
has to specify in a declaration. C++’s reflective capabilities are
quite narrow, limited to runtime-type information in the form of
typeid and dynamic_cast and compile-time type information in the
form of sizeof. However, the traits technique2
, first used in the C++
standard library, offers a simple form of customisable compile-time
type information.
It is a myth that classes exist only to act as the DNA for objects.
Classes can be used to group non-instance information in the form
of constants, types or static member functions, describing policies or
other types. A class template can be used to describe properties
that relate to its parameters, specialising as necessary. This form
of compile-time lookup allows us to answer neatly the question
of the bitset’s size:
template<typename enum_type>
class enum_set
{
...
private:
typedef enum_traits<enum_type> traits;
std::bitset<traits::count> bits;
};
Producing a rabbit with style
However, there is no such thing as magic. If you wish to pull a rabbit
out of a hat, you had better have a rabbit somewhere to hand. Here
is a definition of what the traits for the style type would look like:
template<>
struct enum_traits<style>
{
typedef style enum_type;
static const bool is_specialized = true;
static const style first = bold;
static const style last = small_caps;
static const int step = 1;
static const std::size_t count = last - first + 1;
};
It is common to use struct rather than class for traits because they
do not represent the type of encapsulated objects, and a private-public
distinction serves no useful purpose.The trait class just shown is a
full specialisation of the primary template, which is effectively just
a shell with non-functional placeholder values:
template<typename type>
struct enum_traits
{
typedef type enum_type;
static const bool is_specialized = false;
static const style first = type();
static const style last = type();
static const int step = 0;
static const std::size_t count = 0;
};
The information available to an enum_traits user includes the type
of the enum; whether or not the trait is valid (has been specialised);
the first and last enumerator values; the step increment, if any, between
58 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.co.uk
C++ WORKSHOP
each enumerator; and the count of the enumerators.This is all good
information to have but it does seem like a lot of work: a separate
specialisation is required for each enum type. Fortunately, we can provide
a helper class to cover most of this ground:
template<
typename type,
type last_value, type first_value = type(),
int step_value = 1>
struct enum_traiter
{
typedef type enum_type;
static const bool is_specialized = true;
static const type first = first_value;
static const type last = last_value;
static const int step = step_value;
static const std::size_t count =
(last - first) / step + 1;
};
The enum_traiter template is designed for use as a base, reducing
the enum_traits specialisation for style:
template<>
struct enum_traits<style> :
enum_traiter<style, small_caps>
{
};
This makes life a lot easier, and accommodates enum types whose
enumerators do not number from 0 and whose step is not 1.
However, the common case is catered for with default template
parameters, remembering that the explicit default construction
for integers and enums is zero initialisation.
Wrapping and forwarding
The implementation for enum_set becomes a fairly simple matter
of wrapping and forwarding to a std::bitset:
template<typename enum_type>
class enum_set
{
public:
enum_set()
{
}
enum_set(enum_type setting)
{
set(setting);
}
enum_set &operator&=(const enum_set &rhs)
{
bits &= rhs.bits;
return *this;
}
enum_set &operator|=(const enum_set &rhs)
{
bits |= rhs.bits;
return *this;
}
enum_set &operator^=(const enum_set &rhs)
{
bits ^= rhs.bits;
return *this;
}
std::size_t count() const
{
return bits.count();
}
std::size_t size() const
{
return bits.size();
}
bool operator[](enum_type testing) const
{
return bits.test(to_bit(testing));
}
enum_set &set()
{
bits.set();
return *this;
}
enum_set &set(enum_type setting, bool value = true)
{
bits.set(to_bit(setting), value);
return *this;
}
enum_set &reset()
{
bits.reset();
return *this;
}
enum_set &reset(enum_type resetting)
{
bits.reset(to_bit(resetting));
return *this;
}
enum_set &flip()
{
bits.flip();
return *this;
}
enum_set &flip(enum_type flipping)
{
bits.flip(to_bit(flipping));
return *this;
}
enum_set operator~() const
{
return enum_set(*this).flip();
}
bool any() const
{
return bits.any();
}
bool none() const
{
return bits.none();
}
...
private:
typedef enum_traits<enum_type> traits;
static std::size_t to_bit(enum_type value)
{
return (value - traits::first) / traits::step;
}
std::bitset<traits::count> bits;
};
APRIL 2002 59
C++ WORKSHOP
...
There is one final tweak that, for no extra hassle, makes the code
a little more generic. A common use of trait classes in the standard
library is as policy parameters. The default is to use the default trait
for a type, but the user could provide an alternative.The use of policies
isalong-standingC++techniquethathasmaturedoverthelastdecade3,4,5,6,7
.
The only difference to the enum_set template would be to
remove the traits typedef and add a defaulted parameter:
template<
typename enum_type,
typename traits = enum_traits<enum_type> >
class enum_set
{
...
};
This facility can be used to define sets on a subset of options:
struct simple_style : enum_traiter<style, underline>
{
};
...
enum_set<style, simple_style> selected;
...
This declaration of selected allows it to hold only bold, italic and
underline options.
Looking to the standard library can be a good way of finding either
a solution or the inspiration for one.There are a lot of programming
tasks that are repetitive and tedious. Because of their repetitive
nature they become part of the background hum of programming,
often forgotten.Taking the opportunity to call into question certain
C bit bashing tactics leads to the identification of new abstractions
which, once implemented, reduce the density and quantity of code
needed to express what are in essence high-level ideas. There is no
need to jump through hoops when using the abstractions, although
their implementation does call on some relatively advanced idioms.
How far could you take the use of enum_traits? It is possible to
extend it to accommodate existing enum types that are defined in
terms of a bit-shifted progression rather than an arithmetic one. Based
on traits, you can also define iteration for enum types. For the moment,
these are left as exercises for the reader. s
References
1. Kevlin Henney, “Bound and Checked”, Application
Development Advisor, January 2002, available from
www.appdevadvisor.co.uk
2. Nathan Myers, “Traits: A new and useful template
technique”, C++ Report, June 1995, available from
www.cantrip.org
3. Andrei Alexandrescu, Modern C++ Design, Addison-Wesley,
2001
4. Grady Booch, Object-Oriented Analysis and Design with
Applications, 2nd edition, Benjamin/Cummings, 1994
5. Erich Gamma, Richard Helm, Ralph Johnson and John
Vlissides, Design Patterns, Addison-Wesley, 1995
6. Kevlin Henney, “Making an Exception”, Application
Development Advisor, May 2001, available from
www.appdevadvisor.co.uk
7. Bjarne Stroustrup, The Design and Evolution of C++,
Addison-Wesley, 1994
C++ WORKSHOP
ADA's free e-mail newsletter
for software developers
By now many of you will have had a free on-line newsletter which is a service to
readers of ADA and packed with the very latest editorial for software and
application developers. However, some of our readers don't get this free service.
If you don't get your free newsletter it's for one of two good reasons.
b
Even though you subscribed to ADA,
you haven't supplied us with your e-mail address.
c
You ticked the privacy box at the time you subscribed
and we can't now send you our newsletter.
Sign up for this free service at www.appdevadvisor.co.uk/subscribe.htm
www.appdevadvisor.co.uk/subscribe.htm

More Related Content

What's hot

C language
C languageC language
C Sharp Nagina (1)
C Sharp Nagina (1)C Sharp Nagina (1)
C Sharp Nagina (1)
guest58c84c
 
Operators in C Programming
Operators in C ProgrammingOperators in C Programming
Operators in C Programming
Qazi Shahzad Ali
 
Constants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya JyothiConstants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya Jyothi
SowmyaJyothi3
 
Strings-Computer programming
Strings-Computer programmingStrings-Computer programming
Strings-Computer programming
nmahi96
 
Constant, variables, data types
Constant, variables, data typesConstant, variables, data types
Constant, variables, data types
Pratik Devmurari
 
Strings in c mrs.sowmya jyothi
Strings in c mrs.sowmya jyothiStrings in c mrs.sowmya jyothi
Strings in c mrs.sowmya jyothi
Sowmya Jyothi
 
Data Types and Variables In C Programming
Data Types and Variables In C ProgrammingData Types and Variables In C Programming
Data Types and Variables In C Programming
Kamal Acharya
 
MANAGING INPUT AND OUTPUT OPERATIONS IN C MRS.SOWMYA JYOTHI.pdf
MANAGING INPUT AND OUTPUT OPERATIONS IN C    MRS.SOWMYA JYOTHI.pdfMANAGING INPUT AND OUTPUT OPERATIONS IN C    MRS.SOWMYA JYOTHI.pdf
MANAGING INPUT AND OUTPUT OPERATIONS IN C MRS.SOWMYA JYOTHI.pdf
SowmyaJyothi3
 
Character set of c
Character set of cCharacter set of c
Character set of c
Chandrapriya Rediex
 
Computer programming(CP)
Computer programming(CP)Computer programming(CP)
Computer programming(CP)
nmahi96
 
C programming part4
C programming part4C programming part4
C programming part4
Keroles karam khalil
 
Constants and variables in c programming
Constants and variables in c programmingConstants and variables in c programming
Constants and variables in c programming
Chitrank Dixit
 
Data Type in C Programming
Data Type in C ProgrammingData Type in C Programming
Data Type in C Programming
Qazi Shahzad Ali
 
Lesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmeticLesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmetic
PVS-Studio
 
C programming session 09
C programming session 09C programming session 09
C programming session 09
Dushmanta Nath
 
Getting started with c++
Getting started with c++Getting started with c++
Getting started with c++
K Durga Prasad
 
Variables and data types IN SWIFT
 Variables and data types IN SWIFT Variables and data types IN SWIFT
Variables and data types IN SWIFT
LOVELY PROFESSIONAL UNIVERSITY
 
Programming construction tools
Programming construction toolsProgramming construction tools
Programming construction tools
sunilchute1
 
Concept of c data types
Concept of c data typesConcept of c data types
Concept of c data types
Manisha Keim
 

What's hot (20)

C language
C languageC language
C language
 
C Sharp Nagina (1)
C Sharp Nagina (1)C Sharp Nagina (1)
C Sharp Nagina (1)
 
Operators in C Programming
Operators in C ProgrammingOperators in C Programming
Operators in C Programming
 
Constants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya JyothiConstants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya Jyothi
 
Strings-Computer programming
Strings-Computer programmingStrings-Computer programming
Strings-Computer programming
 
Constant, variables, data types
Constant, variables, data typesConstant, variables, data types
Constant, variables, data types
 
Strings in c mrs.sowmya jyothi
Strings in c mrs.sowmya jyothiStrings in c mrs.sowmya jyothi
Strings in c mrs.sowmya jyothi
 
Data Types and Variables In C Programming
Data Types and Variables In C ProgrammingData Types and Variables In C Programming
Data Types and Variables In C Programming
 
MANAGING INPUT AND OUTPUT OPERATIONS IN C MRS.SOWMYA JYOTHI.pdf
MANAGING INPUT AND OUTPUT OPERATIONS IN C    MRS.SOWMYA JYOTHI.pdfMANAGING INPUT AND OUTPUT OPERATIONS IN C    MRS.SOWMYA JYOTHI.pdf
MANAGING INPUT AND OUTPUT OPERATIONS IN C MRS.SOWMYA JYOTHI.pdf
 
Character set of c
Character set of cCharacter set of c
Character set of c
 
Computer programming(CP)
Computer programming(CP)Computer programming(CP)
Computer programming(CP)
 
C programming part4
C programming part4C programming part4
C programming part4
 
Constants and variables in c programming
Constants and variables in c programmingConstants and variables in c programming
Constants and variables in c programming
 
Data Type in C Programming
Data Type in C ProgrammingData Type in C Programming
Data Type in C Programming
 
Lesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmeticLesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmetic
 
C programming session 09
C programming session 09C programming session 09
C programming session 09
 
Getting started with c++
Getting started with c++Getting started with c++
Getting started with c++
 
Variables and data types IN SWIFT
 Variables and data types IN SWIFT Variables and data types IN SWIFT
Variables and data types IN SWIFT
 
Programming construction tools
Programming construction toolsProgramming construction tools
Programming construction tools
 
Concept of c data types
Concept of c data typesConcept of c data types
Concept of c data types
 

Viewers also liked

The Perfect Couple
The Perfect CoupleThe Perfect Couple
The Perfect Couple
Kevlin Henney
 
Promoting Polymorphism
Promoting PolymorphismPromoting Polymorphism
Promoting Polymorphism
Kevlin Henney
 
Worse Is Better, for Better or for Worse
Worse Is Better, for Better or for WorseWorse Is Better, for Better or for Worse
Worse Is Better, for Better or for Worse
Kevlin Henney
 
One Careful Owner
One Careful OwnerOne Careful Owner
One Careful Owner
Kevlin Henney
 
Collections for States
Collections for StatesCollections for States
Collections for States
Kevlin Henney
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things Along
Kevlin Henney
 
Inside Requirements
Inside RequirementsInside Requirements
Inside Requirements
Kevlin Henney
 
Learning Curve
Learning CurveLearning Curve
Learning Curve
Kevlin Henney
 
Substitutability
SubstitutabilitySubstitutability
Substitutability
Kevlin Henney
 
Bound and Checked
Bound and CheckedBound and Checked
Bound and Checked
Kevlin Henney
 
คนไทยในอังกฤษชุมนุมครั้งที่ ๒
คนไทยในอังกฤษชุมนุมครั้งที่ ๒คนไทยในอังกฤษชุมนุมครั้งที่ ๒
คนไทยในอังกฤษชุมนุมครั้งที่ ๒
konthaiuk
 
Little Things That Make a BIG Difference in Sales
Little Things That Make a BIG Difference in SalesLittle Things That Make a BIG Difference in Sales
Little Things That Make a BIG Difference in Sales
Abhishek Shah
 
Pokran certificate computer
Pokran certificate computerPokran certificate computer
Pokran certificate computer
Bhivraj Bhati
 
Operation emmental appsec
Operation emmental appsecOperation emmental appsec
Operation emmental appsec
Cyber Security Alliance
 
Scottish government approval rating increases
Scottish government approval rating increasesScottish government approval rating increases
Scottish government approval rating increases
Ipsos UK
 
Nettech International Co., Ltd.
Nettech International Co., Ltd.Nettech International Co., Ltd.
Nettech International Co., Ltd.
Saran Yuwanna
 
IGE Presentation to Foyson Shareholders
IGE Presentation to Foyson ShareholdersIGE Presentation to Foyson Shareholders
IGE Presentation to Foyson Shareholders
Foyson Resources
 
Making Hashtags Talk
Making Hashtags TalkMaking Hashtags Talk
Making Hashtags Talk
ixigo.com
 
Representação de imagens em formato digital
Representação de imagens em formato digitalRepresentação de imagens em formato digital
Representação de imagens em formato digital
Helinton Bruce
 
Quantified Sleep - Science behind the sleep trackers
Quantified Sleep - Science behind the sleep trackersQuantified Sleep - Science behind the sleep trackers
Quantified Sleep - Science behind the sleep trackers
Quantified Self Dublin
 

Viewers also liked (20)

The Perfect Couple
The Perfect CoupleThe Perfect Couple
The Perfect Couple
 
Promoting Polymorphism
Promoting PolymorphismPromoting Polymorphism
Promoting Polymorphism
 
Worse Is Better, for Better or for Worse
Worse Is Better, for Better or for WorseWorse Is Better, for Better or for Worse
Worse Is Better, for Better or for Worse
 
One Careful Owner
One Careful OwnerOne Careful Owner
One Careful Owner
 
Collections for States
Collections for StatesCollections for States
Collections for States
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things Along
 
Inside Requirements
Inside RequirementsInside Requirements
Inside Requirements
 
Learning Curve
Learning CurveLearning Curve
Learning Curve
 
Substitutability
SubstitutabilitySubstitutability
Substitutability
 
Bound and Checked
Bound and CheckedBound and Checked
Bound and Checked
 
คนไทยในอังกฤษชุมนุมครั้งที่ ๒
คนไทยในอังกฤษชุมนุมครั้งที่ ๒คนไทยในอังกฤษชุมนุมครั้งที่ ๒
คนไทยในอังกฤษชุมนุมครั้งที่ ๒
 
Little Things That Make a BIG Difference in Sales
Little Things That Make a BIG Difference in SalesLittle Things That Make a BIG Difference in Sales
Little Things That Make a BIG Difference in Sales
 
Pokran certificate computer
Pokran certificate computerPokran certificate computer
Pokran certificate computer
 
Operation emmental appsec
Operation emmental appsecOperation emmental appsec
Operation emmental appsec
 
Scottish government approval rating increases
Scottish government approval rating increasesScottish government approval rating increases
Scottish government approval rating increases
 
Nettech International Co., Ltd.
Nettech International Co., Ltd.Nettech International Co., Ltd.
Nettech International Co., Ltd.
 
IGE Presentation to Foyson Shareholders
IGE Presentation to Foyson ShareholdersIGE Presentation to Foyson Shareholders
IGE Presentation to Foyson Shareholders
 
Making Hashtags Talk
Making Hashtags TalkMaking Hashtags Talk
Making Hashtags Talk
 
Representação de imagens em formato digital
Representação de imagens em formato digitalRepresentação de imagens em formato digital
Representação de imagens em formato digital
 
Quantified Sleep - Science behind the sleep trackers
Quantified Sleep - Science behind the sleep trackersQuantified Sleep - Science behind the sleep trackers
Quantified Sleep - Science behind the sleep trackers
 

Similar to Flag Waiving

An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++Templates
Ganesh Samarthyam
 
The Little Wonders of C# 6
The Little Wonders of C# 6The Little Wonders of C# 6
The Little Wonders of C# 6
BlackRabbitCoder
 
C –FAQ:
C –FAQ:C –FAQ:
5 introduction-to-c
5 introduction-to-c5 introduction-to-c
5 introduction-to-c
Rohit Shrivastava
 
PSPC--UNIT-2.pdf
PSPC--UNIT-2.pdfPSPC--UNIT-2.pdf
PSPC--UNIT-2.pdf
ArshiniGubbala3
 
Chapter1.pptx
Chapter1.pptxChapter1.pptx
Chapter1.pptx
WondimuBantihun1
 
C programming session 04
C programming session 04C programming session 04
C programming session 04
Dushmanta Nath
 
INPUT AND OUTPUT PROCESSINGPlease note that the material o.docx
INPUT AND OUTPUT PROCESSINGPlease note that the material o.docxINPUT AND OUTPUT PROCESSINGPlease note that the material o.docx
INPUT AND OUTPUT PROCESSINGPlease note that the material o.docx
jaggernaoma
 
How to avoid bugs using modern C++
How to avoid bugs using modern C++How to avoid bugs using modern C++
How to avoid bugs using modern C++
PVS-Studio
 
Core C# Programming Constructs, Part 1
Core C# Programming Constructs, Part 1Core C# Programming Constructs, Part 1
Core C# Programming Constructs, Part 1
Vahid Farahmandian
 
Development of a static code analyzer for detecting errors of porting program...
Development of a static code analyzer for detecting errors of porting program...Development of a static code analyzer for detecting errors of porting program...
Development of a static code analyzer for detecting errors of porting program...
PVS-Studio
 
C#
C#C#
Glimpses of C++0x
Glimpses of C++0xGlimpses of C++0x
Glimpses of C++0x
ppd1961
 
Intake 37 2
Intake 37 2Intake 37 2
Intake 37 2
Mahmoud Ouf
 
2 expressions (ppt-2) in C++
2 expressions (ppt-2) in C++2 expressions (ppt-2) in C++
2 expressions (ppt-2) in C++
Kuntal Bhowmick
 
CProgrammingTutorial
CProgrammingTutorialCProgrammingTutorial
CProgrammingTutorial
Muthuselvam RS
 
Intake 38 2
Intake 38 2Intake 38 2
Intake 38 2
Mahmoud Ouf
 
Exploring Microoptimizations Using Tizen Code as an Example
Exploring Microoptimizations Using Tizen Code as an ExampleExploring Microoptimizations Using Tizen Code as an Example
Exploring Microoptimizations Using Tizen Code as an Example
PVS-Studio
 
If I Had a Hammer...
If I Had a Hammer...If I Had a Hammer...
If I Had a Hammer...
Kevlin Henney
 
unit 1 (1).pptx
unit 1 (1).pptxunit 1 (1).pptx
unit 1 (1).pptx
PriyadarshiniS28
 

Similar to Flag Waiving (20)

An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++Templates
 
The Little Wonders of C# 6
The Little Wonders of C# 6The Little Wonders of C# 6
The Little Wonders of C# 6
 
C –FAQ:
C –FAQ:C –FAQ:
C –FAQ:
 
5 introduction-to-c
5 introduction-to-c5 introduction-to-c
5 introduction-to-c
 
PSPC--UNIT-2.pdf
PSPC--UNIT-2.pdfPSPC--UNIT-2.pdf
PSPC--UNIT-2.pdf
 
Chapter1.pptx
Chapter1.pptxChapter1.pptx
Chapter1.pptx
 
C programming session 04
C programming session 04C programming session 04
C programming session 04
 
INPUT AND OUTPUT PROCESSINGPlease note that the material o.docx
INPUT AND OUTPUT PROCESSINGPlease note that the material o.docxINPUT AND OUTPUT PROCESSINGPlease note that the material o.docx
INPUT AND OUTPUT PROCESSINGPlease note that the material o.docx
 
How to avoid bugs using modern C++
How to avoid bugs using modern C++How to avoid bugs using modern C++
How to avoid bugs using modern C++
 
Core C# Programming Constructs, Part 1
Core C# Programming Constructs, Part 1Core C# Programming Constructs, Part 1
Core C# Programming Constructs, Part 1
 
Development of a static code analyzer for detecting errors of porting program...
Development of a static code analyzer for detecting errors of porting program...Development of a static code analyzer for detecting errors of porting program...
Development of a static code analyzer for detecting errors of porting program...
 
C#
C#C#
C#
 
Glimpses of C++0x
Glimpses of C++0xGlimpses of C++0x
Glimpses of C++0x
 
Intake 37 2
Intake 37 2Intake 37 2
Intake 37 2
 
2 expressions (ppt-2) in C++
2 expressions (ppt-2) in C++2 expressions (ppt-2) in C++
2 expressions (ppt-2) in C++
 
CProgrammingTutorial
CProgrammingTutorialCProgrammingTutorial
CProgrammingTutorial
 
Intake 38 2
Intake 38 2Intake 38 2
Intake 38 2
 
Exploring Microoptimizations Using Tizen Code as an Example
Exploring Microoptimizations Using Tizen Code as an ExampleExploring Microoptimizations Using Tizen Code as an Example
Exploring Microoptimizations Using Tizen Code as an Example
 
If I Had a Hammer...
If I Had a Hammer...If I Had a Hammer...
If I Had a Hammer...
 
unit 1 (1).pptx
unit 1 (1).pptxunit 1 (1).pptx
unit 1 (1).pptx
 

More from Kevlin Henney

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
Kevlin Henney
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
Kevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
Kevlin Henney
 
Get Kata
Get KataGet Kata
Get Kata
Kevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Kevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
Kevlin Henney
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
Kevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
Kevlin Henney
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
Kevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
Kevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
Kevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
Kevlin Henney
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
Kevlin Henney
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
Kevlin Henney
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
Kevlin Henney
 
Good Code
Good CodeGood Code
Good Code
Kevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 

Recently uploaded

VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
jealousviolet
 
Wired_2.0_Create_AmsterdamJUG_09072024.pptx
Wired_2.0_Create_AmsterdamJUG_09072024.pptxWired_2.0_Create_AmsterdamJUG_09072024.pptx
Wired_2.0_Create_AmsterdamJUG_09072024.pptx
SimonedeGijt
 
Leading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptxLeading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptx
taskroupseo
 
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
rachitkumar09887
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
neshakor5152
 
Google ML-Kit - Understanding on-device machine learning
Google ML-Kit - Understanding on-device machine learningGoogle ML-Kit - Understanding on-device machine learning
Google ML-Kit - Understanding on-device machine learning
VishrutGoyani1
 
Introduction_to_Security_Assessments.ppt
Introduction_to_Security_Assessments.pptIntroduction_to_Security_Assessments.ppt
Introduction_to_Security_Assessments.ppt
sudsdeep
 
Top 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your WebsiteTop 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your Website
e-Definers Technology
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...
karim wahed
 
WEBINAR SLIDES: CCX for Cloud Service Providers
WEBINAR SLIDES: CCX for Cloud Service ProvidersWEBINAR SLIDES: CCX for Cloud Service Providers
WEBINAR SLIDES: CCX for Cloud Service Providers
Severalnines
 
11 Top Cross Browser Testing Tools to Know About.pdf
11 Top Cross Browser Testing Tools to Know About.pdf11 Top Cross Browser Testing Tools to Know About.pdf
11 Top Cross Browser Testing Tools to Know About.pdf
kalichargn70th171
 
Il Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazioneIl Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazione
confluent
 
Odoo E-commerce website development guides
Odoo E-commerce website development guidesOdoo E-commerce website development guides
Odoo E-commerce website development guides
jhkdigitalmarketing
 
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
josephinedrea942
 
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docxComprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Aardwolf Security
 
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
confluent
 
Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.
shivamt017
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdfAWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
karim wahed
 
active-directory-auditing-solution (2).pptx
active-directory-auditing-solution (2).pptxactive-directory-auditing-solution (2).pptx
active-directory-auditing-solution (2).pptx
sudsdeep
 
React Native vs Flutter - SSTech System
React Native vs Flutter  - SSTech SystemReact Native vs Flutter  - SSTech System
React Native vs Flutter - SSTech System
SSTech System
 

Recently uploaded (20)

VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
 
Wired_2.0_Create_AmsterdamJUG_09072024.pptx
Wired_2.0_Create_AmsterdamJUG_09072024.pptxWired_2.0_Create_AmsterdamJUG_09072024.pptx
Wired_2.0_Create_AmsterdamJUG_09072024.pptx
 
Leading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptxLeading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptx
 
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
Agra Girls Call Agra 0X0000000X Unlimited Short Providing Girls Service Avail...
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
 
Google ML-Kit - Understanding on-device machine learning
Google ML-Kit - Understanding on-device machine learningGoogle ML-Kit - Understanding on-device machine learning
Google ML-Kit - Understanding on-device machine learning
 
Introduction_to_Security_Assessments.ppt
Introduction_to_Security_Assessments.pptIntroduction_to_Security_Assessments.ppt
Introduction_to_Security_Assessments.ppt
 
Top 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your WebsiteTop 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your Website
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Final Course Know...
 
WEBINAR SLIDES: CCX for Cloud Service Providers
WEBINAR SLIDES: CCX for Cloud Service ProvidersWEBINAR SLIDES: CCX for Cloud Service Providers
WEBINAR SLIDES: CCX for Cloud Service Providers
 
11 Top Cross Browser Testing Tools to Know About.pdf
11 Top Cross Browser Testing Tools to Know About.pdf11 Top Cross Browser Testing Tools to Know About.pdf
11 Top Cross Browser Testing Tools to Know About.pdf
 
Il Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazioneIl Data Streaming per un’AI real-time di nuova generazione
Il Data Streaming per un’AI real-time di nuova generazione
 
Odoo E-commerce website development guides
Odoo E-commerce website development guidesOdoo E-commerce website development guides
Odoo E-commerce website development guides
 
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
HIRE A HACKER FOR CHEATING HUSBAND/WIFE)
 
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docxComprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
Comprehensive Vulnerability Assessments Process _ Aardwolf Security.docx
 
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
Unleashing the Future: Building a Scalable and Up-to-Date GenAI Chatbot with ...
 
Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdfAWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
 
active-directory-auditing-solution (2).pptx
active-directory-auditing-solution (2).pptxactive-directory-auditing-solution (2).pptx
active-directory-auditing-solution (2).pptx
 
React Native vs Flutter - SSTech System
React Native vs Flutter  - SSTech SystemReact Native vs Flutter  - SSTech System
React Native vs Flutter - SSTech System
 

Flag Waiving

  • 1. Take a quick look at the following code: typedef enum style { plain, bold, italic, underline = 4, strikethrough = 8, small_caps = 16 } style; What language is it in? It could be C or C++, although the style is clearly C-like; C++ does not need all that typedef noise to obtain a usable type name. The following code fragments fix the language: style selected = plain; ... selected |= italic; ... if(selected & bold) ... It’s C. To be precise, it’s common but not particu- larly good C.The code demonstrates a weakness of the type system that encourages sloppy design. Unfortu- nately, given the enduring C influence on C++ cod- ing practices, this style for flags and sets of flags is also prevalent in C++. C++ programmers without a C background can acquire these habits by osmosis from their C-speaking colleagues or through C-influ- enced libraries. Flag poll First, some quick explanation and a little bit of reformatting. As its name suggests, an enum is nor- mally used to enumerate a set of constants. By default, the enumerators have distinct values, starting at 0 and rising by 1 for each successive enumerator. Alterna- tively, an enumerator can be given a specific constant integer value. A common approach for holding a set of binary options is to treat an integer value as a collection of bits, ignoring its numeric properties. If a bit at a particular position is set, the option represented by that position is enabled.This duality is common at the systems pro- gramming level and many programmers never think to question it. C programmers and, indeed, C com- pilers make little distinction between enumerators, integers, flags and bit sets. An enum is often used to list the distinct options in a bit set, but instead of acting as distinct symbols, enumerator constants are used to represent bit masks. This brings us to the first bit of laziness to tidy up in the original enum definition. As it happens, the first three values form the sequence 0, 1 and 2, which spec- ifies no bits, the first bit and the second bit respec- tively. Each integer power of 2, from 0 up, represents a different bit. To make it clear that the enumerators do not form a conventional sequence, but instead rep- resent bit masks, developers typically set the mask val- ues explicitly. As neither C nor C++ supports binary literals, it is more common to use hexadecimal rather than either decimal or octal to define the constants: enum style { plain, bold = 0x01, italic = 0x02, underline = 0x04, strikethrough = 0x08, small_caps = 0x10 }; Since the aim of this column is to reconsider how we work with flags in C++, I have also taken the small liberty of dropping the C-ish typedef. Let’s look at another common approach to specifying the enu- merators, that makes the basic idea of sequence (bit 0, bit 1, bit 2 etc) a little more explicit: enum style { plain, bold = 1 << 0, italic = 1 << 1, underline = 1 << 2, strikethrough = 1 << 3, 56 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.co.uk Kevlin Henney is an independent software development consultant and trainer.He can be reached at www.curbralan.com C++ WORKSHOP q C habits still affect C++ style, such as how to work with flags. q C++’s stronger type checking makes the C use of enums as bit sets somewhat awkward. q The standard library’s bitset template provides a simpler and more direct implementation for sets of flag options. q Programmers can define their own types for holding bit sets based on std::bitset. q Trait classes and policy parameters allow for flexible implementation. FACTS AT A GLANCE Using enum to manage bit sets works fine in C, but things become a little more complex in C++. Kevlin Henney explains an alternative method of handling flags, using the bitset template Flag waiving
  • 2. small_caps = 1 << 4 }; This approach makes the bit-masking purpose of the enumera- tors a little clearer.The relationship to integers and ordinary count- ing numbers is less interesting than the shifted position of a set bit. But what about the code that shows how the style flags are used? Alas, the following won’t compile: selected |= italic; This fails because enum and integer types are not interchangeable: arithmetic and bitwise operators do not apply to enums. When you use an enum where an integer is expected, you get an implicit con- version to the enum’s associated integer value, in effect: static_cast<int>(selected) |= static_cast<int>(italic); When integers go bad While there is not much wrong with using an enum as an inte- ger, there is plenty wrong with using an integer as an enum. Every enumerator will map to a valid integer value but not every valid integer will map to a valid enumerator.That’s why C++ banned the implicit conversion from integer to enum and why the code shown won’t compile. So how do you make it compile? You can force the compiler to succumb to your wicked way with a cast as your accomplice: selected = static_cast<style>(selected | italic); It would be fair to say this lacks both grace and convenience. Alternatively, you could overload the bitwise or operators to do your bidding: style operator|(style lhs, style rhs) { return static_cast<style>(int(lhs) | int(rhs)); } style &operator|=(style &lhs, style rhs) { return lhs = lhs | rhs; } This will allow the code to compile in its original form, but you should not forget to define the other relevant bitwise operators. One problem with this approach is that you need to define these operators anew for every enum type you want to use as a bit set. And what do you do for the definition of the bitwise not operator?This is used to ensure that a bit is disabled: selected &= ~italic; What should the value of ~italic be? bold | underline | strikethrough | small_caps or ~int(italic)? The former includes only bits that have been defined as valid for the bit set, but the latter is a simpler interpretation of the bit set concept. A quick aside on cast style: the constructor-like form, eg int(italic) is used where the conversion is safe and would otherwise be implicit. You are constructing an int from a style.The keyword cast form, static_cast, is being used where the conversion is potentially unsafe and we are taking liberties with the type system. Which brings us neatly to the next point: we are messing with the typesystem.Thereisanunderlyingreasonwhywearehavingtoperform with a cast of thousands: the design is flawed. If you recall, the style type is an enumeration type. In other words, it enumerates the intended legal values of a style variable that is designed to hold one of the enumerator values at a time. However, the common practice uses a style variable to hold not an option but a set of options. While the bit representation of an enum affords such usage, it is by default a type error that is fundamentally a category error: a thing and a collection of things are different types. This answers the question of why plain is not really a valid enu- merator for style. It represents a combination of options (or, rather, their absence); it is a set rather than an individual option.The canon- ical C type for a bit set is the integer, signed or otherwise, but the C’slaxtypesystemallowsthefreeandeasymixingofunrelatedconcepts. Here is the revised code: const unsigned plain = 0; ... unsigned selected = plain; ... selected |= italic; ... if(selected & bold) ... However, what the other approaches lacked in grace, the inte- ger bit set loses in safety and precision.There is nothing that constrains the actual use of an unsigned to be the same as its intended use. Taking a step back from these many variations, you may realise the nagging truth: it’s all a bit of a hack. Why should you be man- ually organising your constants according to bit masks at all? It is easy to become rooted in only one form of thinking. Sometimes a freshlookwillhelpyoubreakoutofaruttoamoreappropriatesolution. Let’s leave C behind. It’s time to get back to basics, ignoring all this bitwise gymnas- tics, and restate the core problem: you need to hold a set of options, each of which is effectively Boolean.This suggests a simple solution: hold a set of options. enum style { bold, italic, underline, strikethrough, small_caps }; ... std::set<style> selected; ... selected.insert(italic); ... if(selected.count(bold)) ... This method is a lot simpler to work with: the style type sim- ply enumerates the options with no hard coding of literal values. The standard set class template allows a set of options to be manipulated as a type-checked set rather than at the systems programming level. In other words, the language and library do all the work for you. Honing for efficiency Functionally, there are no problems with this approach, but many programmers may justifiably have concerns over its efficiency. The bitwise solution required an integer for storage, no additional dynamic memory usage, and efficient, fixed-time manipulation of the options. In contrast, an std::set is an associative node-based container that uses dynamic memory for its representation. If you hold these space and time efficiency concerns (and have good reason to), all is not lost: you can still have abstraction and efficiency. The flat_set class template presented in the last column1 is an improvement over std::set for this purpose. But better still is the standard bitset template: APRIL 2002 57 C++ WORKSHOP
  • 3. std::bitset<5> selected; ... selected.set(italic); ... if(selected.test(bold)) ... The std::bitset class template, defined in the standard <bitset> header, is not a part of the STL, hence the seemingly non-standard member function names. But it is still standard and it still solves the problem. A more legitimate obstacle is that the size of the set must be wired in at compile time. There is also nothing that constrains you to working with the style type. There is a simple hack that allows you to avoid having to count the number of enumerators: enum style { bold, italic, underline, strikethrough, small_caps, _style_size }; ... std::bitset<_style_size> selected; ... I say this is a hack because you are using the property of enumerators tocount,bydefault,instepsof1from0.Thelastenumerator,_style_size, is not really part of the valid set of enumerators because it does not represent an option. However, in its favour, this technique does save you from many of the ravages of change: the addition or removal of enumerators and any consequent change to the declared size of the bitset. Rhyme and treason Now I think we have a better idea of what is needed: something that works like a type-safe bitset for enums. Alas, we won’t find one of these in the standard so we will have to create it. Let’s start with the intended usage: enum_set<style> selected; ... selected.set(italic); ... if(selected.test(bold)) ... It seems reasonable enough to follow the std::bitset interface because the two are conceptually related. Additionally, a const subscript operator would make its use even more intuitive: if(selected[bold]) ... To save on all the bit twiddling, we can use std::bitset as the representation of our enum_set. However, a quick sketch reveals a problem: template<typename enum_type> class enum_set { ... private: std::bitset<???> bits; }; How big should the bitset be? One unsatisfactory solution would be to require the user to provide the size as well as the type, ie: enum_set<style, _style_size> selected; This is clumsy and smacks of redundancy. We state the type and then a property of the type, relying in this case on a little hack to keep everything in sync. It would be nice to look up the relevant type properties based on the type name, so that the type is all the user has to specify in a declaration. C++’s reflective capabilities are quite narrow, limited to runtime-type information in the form of typeid and dynamic_cast and compile-time type information in the form of sizeof. However, the traits technique2 , first used in the C++ standard library, offers a simple form of customisable compile-time type information. It is a myth that classes exist only to act as the DNA for objects. Classes can be used to group non-instance information in the form of constants, types or static member functions, describing policies or other types. A class template can be used to describe properties that relate to its parameters, specialising as necessary. This form of compile-time lookup allows us to answer neatly the question of the bitset’s size: template<typename enum_type> class enum_set { ... private: typedef enum_traits<enum_type> traits; std::bitset<traits::count> bits; }; Producing a rabbit with style However, there is no such thing as magic. If you wish to pull a rabbit out of a hat, you had better have a rabbit somewhere to hand. Here is a definition of what the traits for the style type would look like: template<> struct enum_traits<style> { typedef style enum_type; static const bool is_specialized = true; static const style first = bold; static const style last = small_caps; static const int step = 1; static const std::size_t count = last - first + 1; }; It is common to use struct rather than class for traits because they do not represent the type of encapsulated objects, and a private-public distinction serves no useful purpose.The trait class just shown is a full specialisation of the primary template, which is effectively just a shell with non-functional placeholder values: template<typename type> struct enum_traits { typedef type enum_type; static const bool is_specialized = false; static const style first = type(); static const style last = type(); static const int step = 0; static const std::size_t count = 0; }; The information available to an enum_traits user includes the type of the enum; whether or not the trait is valid (has been specialised); the first and last enumerator values; the step increment, if any, between 58 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.co.uk C++ WORKSHOP
  • 4. each enumerator; and the count of the enumerators.This is all good information to have but it does seem like a lot of work: a separate specialisation is required for each enum type. Fortunately, we can provide a helper class to cover most of this ground: template< typename type, type last_value, type first_value = type(), int step_value = 1> struct enum_traiter { typedef type enum_type; static const bool is_specialized = true; static const type first = first_value; static const type last = last_value; static const int step = step_value; static const std::size_t count = (last - first) / step + 1; }; The enum_traiter template is designed for use as a base, reducing the enum_traits specialisation for style: template<> struct enum_traits<style> : enum_traiter<style, small_caps> { }; This makes life a lot easier, and accommodates enum types whose enumerators do not number from 0 and whose step is not 1. However, the common case is catered for with default template parameters, remembering that the explicit default construction for integers and enums is zero initialisation. Wrapping and forwarding The implementation for enum_set becomes a fairly simple matter of wrapping and forwarding to a std::bitset: template<typename enum_type> class enum_set { public: enum_set() { } enum_set(enum_type setting) { set(setting); } enum_set &operator&=(const enum_set &rhs) { bits &= rhs.bits; return *this; } enum_set &operator|=(const enum_set &rhs) { bits |= rhs.bits; return *this; } enum_set &operator^=(const enum_set &rhs) { bits ^= rhs.bits; return *this; } std::size_t count() const { return bits.count(); } std::size_t size() const { return bits.size(); } bool operator[](enum_type testing) const { return bits.test(to_bit(testing)); } enum_set &set() { bits.set(); return *this; } enum_set &set(enum_type setting, bool value = true) { bits.set(to_bit(setting), value); return *this; } enum_set &reset() { bits.reset(); return *this; } enum_set &reset(enum_type resetting) { bits.reset(to_bit(resetting)); return *this; } enum_set &flip() { bits.flip(); return *this; } enum_set &flip(enum_type flipping) { bits.flip(to_bit(flipping)); return *this; } enum_set operator~() const { return enum_set(*this).flip(); } bool any() const { return bits.any(); } bool none() const { return bits.none(); } ... private: typedef enum_traits<enum_type> traits; static std::size_t to_bit(enum_type value) { return (value - traits::first) / traits::step; } std::bitset<traits::count> bits; }; APRIL 2002 59 C++ WORKSHOP
  • 5. ... There is one final tweak that, for no extra hassle, makes the code a little more generic. A common use of trait classes in the standard library is as policy parameters. The default is to use the default trait for a type, but the user could provide an alternative.The use of policies isalong-standingC++techniquethathasmaturedoverthelastdecade3,4,5,6,7 . The only difference to the enum_set template would be to remove the traits typedef and add a defaulted parameter: template< typename enum_type, typename traits = enum_traits<enum_type> > class enum_set { ... }; This facility can be used to define sets on a subset of options: struct simple_style : enum_traiter<style, underline> { }; ... enum_set<style, simple_style> selected; ... This declaration of selected allows it to hold only bold, italic and underline options. Looking to the standard library can be a good way of finding either a solution or the inspiration for one.There are a lot of programming tasks that are repetitive and tedious. Because of their repetitive nature they become part of the background hum of programming, often forgotten.Taking the opportunity to call into question certain C bit bashing tactics leads to the identification of new abstractions which, once implemented, reduce the density and quantity of code needed to express what are in essence high-level ideas. There is no need to jump through hoops when using the abstractions, although their implementation does call on some relatively advanced idioms. How far could you take the use of enum_traits? It is possible to extend it to accommodate existing enum types that are defined in terms of a bit-shifted progression rather than an arithmetic one. Based on traits, you can also define iteration for enum types. For the moment, these are left as exercises for the reader. s References 1. Kevlin Henney, “Bound and Checked”, Application Development Advisor, January 2002, available from www.appdevadvisor.co.uk 2. Nathan Myers, “Traits: A new and useful template technique”, C++ Report, June 1995, available from www.cantrip.org 3. Andrei Alexandrescu, Modern C++ Design, Addison-Wesley, 2001 4. Grady Booch, Object-Oriented Analysis and Design with Applications, 2nd edition, Benjamin/Cummings, 1994 5. Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Design Patterns, Addison-Wesley, 1995 6. Kevlin Henney, “Making an Exception”, Application Development Advisor, May 2001, available from www.appdevadvisor.co.uk 7. Bjarne Stroustrup, The Design and Evolution of C++, Addison-Wesley, 1994 C++ WORKSHOP ADA's free e-mail newsletter for software developers By now many of you will have had a free on-line newsletter which is a service to readers of ADA and packed with the very latest editorial for software and application developers. However, some of our readers don't get this free service. If you don't get your free newsletter it's for one of two good reasons. b Even though you subscribed to ADA, you haven't supplied us with your e-mail address. c You ticked the privacy box at the time you subscribed and we can't now send you our newsletter. Sign up for this free service at www.appdevadvisor.co.uk/subscribe.htm www.appdevadvisor.co.uk/subscribe.htm