C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Re: Using bool values as loop indexes
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Ed Avis
Guest





PostPosted: Thu Jun 26, 2003 7:35 pm    Post subject: Re: Using bool values as loop indexes Reply with quote



Other languages have a 'foreach' construct, which might look something
like

foreach bool b (false, true) {
// do something with b
}

Now I know the standard library has for_each(), but it seems a bit
heavyweight to construct a container with two bools and then iterate
over it. Also you must define a function for the loop body, though
various 'lambda' libraries can sometimes make that a bit easier.

I wonder if for simple cases a template function could be written?

For_each<bool, VALUES_2(false, true)>(some_function_taking_bool);

where VALUES_2 expands to one of those compile-time lists (a list of
values, mind you, not a list of types) that certain columnists always
go on about - something like cons<false, cons.

Here I have made some_function an ordinary parameter of the function,
but you could make it a template parameter instead for extra inlining
goodness. Then the code would combine down to just two calls to this
function, one with false and one with true.

Does any existing 'library of weird template stuff' provide such a
foreach loop?

--
Ed Avis <ed (AT) membled (DOT) com>


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Andrey Tarasevich
Guest





PostPosted: Thu Jun 26, 2003 7:40 pm    Post subject: Re: Using bool values as loop indexes Reply with quote



Tom Houlder wrote:
Quote:
...
Nice, but a bit too obfuscated for my taste. And there is no need to
pull any "simple circular nature" into this. For those who like
packing
several actions into one statement, my version can be transformed
into
the following

bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << (a && !b) << std::endl;
} while (!b++);
} while (!a++);

But normally I refrain from doing that in practice.

I hope you do, as postfix incrementing a bool is deprecated and in
the future it will most likely be an ill-formed program. Indeed,
prefix
increment is also deprecated as stated in 5.2.6 and 5.3.2 but,
AFAICS, erroneously not listed in Appendix D.

My previous statement was actually about combining several relatively
independent actions into one statement, like stuffing any
side-effect-producing operators into an logical expression used as an
argument of '} while ()'.

Whether the above use of increment operator is deprecated or not is
rather irrelevant here, since the OP's message was already applying an
increment operator to a 'bool' object. It is his choice, not main.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Thu Jun 26, 2003 10:27 pm    Post subject: Re: Using bool values as loop indexes Reply with quote




No comment on the code supplied for the subject question. I have
no idea why something other than a loop would be used to write a
loop.

On 25 Jun 2003 19:29:05 -0400, "Jeff Greif"
<jgreif (AT) spam-me-not (DOT) alumni.princeton.edu> wrote:

Quote:
Is it possible to construct a functor and evaluate its operator() in the
same expression? This does not work in the compiler I tried (gcc 3.2
prerelease):
Functor(args)();
Instead I had to do use two statements:
Functor f(args);
f();

Same compiler, works fine. Post minimal code. Here is mine.

struct F {
F (int) { }
bool operator() () { return true; }
};
int main () {
F(42)();
}

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Thu Jun 26, 2003 10:32 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

On 25 Jun 2003 19:35:52 -0400, "News Admin" <news (AT) news (DOT) demon.net> wrote:

Quote:
for( bool a = false; a < true; ++a){
for(bool b = false; b std::cout << a << " " << b << " " << a && !b << std::endl;
}
}

Since that is clearly what the poster meant. (The difference is =
substituting "<" for "<=").

I don't think so. Run it. One line of output. The poster wanted
four lines of output.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Thu Jun 26, 2003 10:32 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

On 25 Jun 2003 19:38:04 -0400, Andrey Tarasevich
<andreytarasevich (AT) hotmail (DOT) com> wrote:

Quote:
Not bad. Did you consider the simple circular nature of the
problem? It is like traversing a non-empty circular list.

bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << a && !b << std::endl;
} while (b = ! b);
} while (a = ! a);
...

Nice, but a bit too obfuscated for my taste.

Is it obfuscated like x = (x + 1) % n or x = 1 - x ? I'm serious,
I do not understand.

Quote:
And there is no need to pull any "simple circular nature" into this.

It is a general pattern. If you want to cover all cases, you use
do-while with an increment before the first test. The test is for
not first value. The code that Becker posted can also be written
this way rather than using a larger range type. For unsigned, it
works fine and bool is unsigned. For signed it is undefined but
usually does what is expected like Pete said. If you want only
all positives for signed types a modified test works.

unsigned short i(0);
do {
something_with(i);
++ i;
} while (i != 0);

short i(SHORT_MIN);
do {
something_with(i);
++ i;
} while (i != SHORT_MIN);
// technically, undefined behavior, but typically works fine

for (short i = 0; i >= 0; ++i)
// technically, undefined behavior, but typically works fine

for (short i = 0; i >= 0; i = i == SHORT_MAX ? -42 : i + 1)
// no undefined behavior here

BTW, your abortive do-while reminded me of the general solution.
With the abort, there is no difference between while and do-while.
I keep forgetting that there are times when do-while is the answer.

Quote:
For those who like packing several actions into one statement,

Just a concise way to use the pattern. If that is the only objection,
use two statements to keep the pattern nice.

bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << (a && !b) << std::endl;
b = ! b;
} while (b);
a = ! a;
} while (a);

Quote:
my version can be transformed into
the following

bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << (a && !b) << std::endl;
} while (!b++);
} while (!a++);

But normally I refrain from doing that in practice.

That's good because prefix/postfix increment is depricated for bool and
there is no decrement. It was a mistake to have something like an
unsigned integral type with pseudo arithmetic which is not circular.
Let x be false and y be true, then ++ x == true, x + 1 == true,
++ y == true, y + 1 != true. Of course, you would also want to be able
to run the loop backwards to give true before false as the philosophers
use. Change the initialization and test but not the increment.

bool a(true);
do {
something_with(a);
a = ! a;
} while (! a);

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
KIM Seungbeom
Guest





PostPosted: Fri Jun 27, 2003 4:45 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

Pete Becker <petebecker (AT) acm (DOT) org> wrote

Quote:

There's always a problem when you try to loop up to and including the
largest representable value for any type.

The solution is to use a larger type and convert to the type you need:

for (unsigned i = 0; i <= USHRT_MAX; ++i)
// okay, if unsigned is larger than unsigned short

for (int i = 0; i <= SHRT_MAX; ++i)
// okay, if unsigned is larger than unsigned short

for (int i = 0; i < 2; ++i)
bool b = i;

Your solution is not always feasible;
what if the loop is from 0 to ULONG_MAX?

I would suggest exiting the loop before the increment:

for (unsigned long i = 0; /* i <= ULONG_MAX */; ++i) {
// do something
if (i == ULONG_MAX) break;
}

For bools:

for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}

Nothing to worry about the type conversion.

--
KIM Seungbeom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrey Tarasevich
Guest





PostPosted: Fri Jun 27, 2003 4:47 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

John Potter wrote:
Quote:
...
Not bad. Did you consider the simple circular nature of the
problem? It is like traversing a non-empty circular list.

bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << a && !b << std::endl;
} while (b = ! b);
} while (a = ! a);
...

Nice, but a bit too obfuscated for my taste.

Is it obfuscated like x = (x + 1) % n or x = 1 - x ? I'm serious,
I do not understand.

I'm just referring to using the '} while(...)' part of the code to both
modify the value of the index and verify the resultant value.

Quote:
And there is no need to pull any "simple circular nature" into
this.

It is a general pattern. If you want to cover all cases, you use
do-while with an increment before the first test. The test is for
not first value. The code that Becker posted can also be written
this way rather than using a larger range type. For unsigned, it
works fine and bool is unsigned. For signed it is undefined but
usually does what is expected like Pete said. If you want only
all positives for signed types a modified test works.

unsigned short i(0);
do {
something_with(i);
++ i;
} while (i != 0);

I prefer a different general pattern

unsigned short i(0);
do {
something_with(i);

if (i == USHORT_MAX)
break;

++i;

} while (true);

This version does not impose the requirement that the arithmetic of the
index type is circular and can be easily modified to run the loop
backwards. Of course, in this form it is not as polymorphic with regard
to unsigned types as your version, since it explicitly mentions
'USHORT_MAX'. But this could be easily corrected by using
'std::numeric_limits'.

Quote:
BTW, your abortive do-while reminded me of the general solution.
With the abort, there is no difference between while and do-while.
I keep forgetting that there are times when do-while is the answer.

I prefer using 'do {...} while (...)' to implement cycles, whose bodies
are entered unconditionally, including 'exit from the middle' type of
cycle ('do {...} while (true)'). Others probably might prefer using
something like 'for (;Wink'.

Quote:
...
++ y == true, y + 1 != true. Of course, you would also want to be
able
to run the loop backwards to give true before false as the
philosophers
use. Change the initialization and test but not the increment.

bool a(true);
do {
something_with(a);
a = ! a;
} while (! a);
...

Well, if you consider it as a general pattern, it doesn't really run the
loop backwards. The results just happen to be the same for two-element
loops.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrey Tarasevich
Guest





PostPosted: Fri Jun 27, 2003 4:47 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

John Potter wrote:
Quote:
...
Not really. A do-loop will work:

bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << a && !b << "n";
} while (b++ != true);
} while (a++ != true);

Sorry, there is no postfix increment/decrement for bool. Prefix is
valid but depricated.
...

Huh? There is no decrement for 'bool' (neither postfix nor prefix).
There are both postfix and prefix increments for 'bool', although both
forms are deprecated.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Sat Jun 28, 2003 11:05 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

KIM Seungbeom wrote:
Quote:

For bools:

for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}


do_something(false);
do_something(true);

Much simpler.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Sun Jun 29, 2003 12:34 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker <petebecker (AT) acm (DOT) org>
writes
Quote:
KIM Seungbeom wrote:

For bools:

for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}


do_something(false);
do_something(true);

Much simpler.

True, for a single level but rather different when you have such loops
nested three or four deep -- which was the OP's motivation.


--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andy Sawyer
Guest





PostPosted: Mon Jun 30, 2003 9:13 am    Post subject: Re: Using bool values as loop indexes Reply with quote

In article <H2HJa.61589$Io.5776802 (AT) newsread2 (DOT) prod.itd.earthlink.net>,
on 23 Jun 2003 18:43:03 -0400,
"Matthew Seitz" <mseitz (AT) yahoo (DOT) com> wrote:

Quote:
Is there a commonly accepted "best way" or idiom for using a bool value as a
loop index? I want to generate a boolean truth-table. Here is a simplified
version of my initial code:

for( bool a = false; a <= true; ++a){
for(bool b = false; b<=true; ++b){
std::cout << a << " " << b << " " << a && !b << std::endl;
}
}

Unfortunately, this leads to an infinite loop, because ++b still equals
true. I can see various ways to solve this problem. I was wondering what
is the most common or best solution to the problem.

How about something like:

class boolindex {
unsigned value_;
public:
boolindex() : value_(0) {}
boolindex operator++() { ++value_; }
operator bool() const { return value_; }
bool operator!() const { return !value_; }
bool valid() const { return value_ < 2; }
};



for( boolindex a ; a.valid() ; ++a )
for( boolindex b ; b.valid() ; ++b )
std::cout << a << ' ' << b ' ' << (a && !b) << std::endl;



--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Mon Jun 30, 2003 9:21 am    Post subject: Re: Using bool values as loop indexes Reply with quote

On 29 Jun 2003 08:34:36 -0400, Francis Glassborow
<francis.glassborow (AT) ntlworld (DOT) com> wrote:

Quote:
In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker writes

do_something(false);
do_something(true);

Much simpler.

True, for a single level but rather different when you have such loops
nested three or four deep -- which was the OP's motivation.

I just noticed that Pete has the optimal. Consider three levels.

do_something(false, false, false);
do_something(false, false, true);
do_something(false, true, false);
do_something(false, true, true);
do_something(true, false, false);
do_something(true, false, true);
do_something(true, true, false);
do_something(true, true, true);

Try loops.

bool a(false);
do {
bool b(false);
do {
bool c(false);
do {
do_something(a, b, c);
c = ! c;
} while (c);
b = ! b;
} while (b);
a = ! a;
} while (a);

Eventually the loops will be less statements than the repeated code.
Will it be interesting?

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Tue Jul 01, 2003 9:57 pm    Post subject: Re: Using bool values as loop indexes Reply with quote

Francis Glassborow wrote:
Quote:

In message <864r27ths7.fsf (AT) Zorthluthik (DOT) local.bar>, llewelly
[email]llewelly.at (AT) xmission (DOT) dot.com[/email]> writes
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:

On 29 Jun 2003 08:34:36 -0400, Francis Glassborow
[email]francis.glassborow (AT) ntlworld (DOT) com[/email]> wrote:

In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker
[email]petebecker (AT) acm (DOT) org[/email]
writes

do_something(false);
do_something(true);

Much simpler.

True, for a single level but rather different when you have
such
loops
nested three or four deep -- which was the OP's motivation.

At four deep Pete's style still wins, by one line, by my
calculations. At 5 deep the nested do-whiles win, but who wants
loops nested 5 deep?

But what it does not do is to express clearly in code the intent.

What could be clearer than enumerating all the desired cases?

Quote:
It
also require a great deal of care to ensure that all cases have been
covered (and none repeated).

On the contrary: it's easy. Just count in binary.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
llewelly
Guest





PostPosted: Wed Jul 02, 2003 1:00 am    Post subject: Re: Using bool values as loop indexes Reply with quote

Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> writes:

Quote:
In message <864r27ths7.fsf (AT) Zorthluthik (DOT) local.bar>, llewelly
[email]llewelly.at (AT) xmission (DOT) dot.com[/email]> writes
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:

On 29 Jun 2003 08:34:36 -0400, Francis Glassborow
[email]francis.glassborow (AT) ntlworld (DOT) com[/email]> wrote:

In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker
[email]petebecker (AT) acm (DOT) org[/email]
writes

do_something(false);
do_something(true);

Much simpler.

True, for a single level but rather different when you have such
loops
nested three or four deep -- which was the OP's motivation.

At four deep Pete's style still wins, by one line, by my
calculations. At 5 deep the nested do-whiles win, but who wants
loops nested 5 deep?

But what it does not do is to express clearly in code the intent.

I think I agree with you, but I am not sure which it you are referring
to. I do not think either Pete's linear example or John's
nested do-while loops express clearly in code the intent for any
number of levels greater than 2. The do-while with bool is IMO
uncommonly seen, and if they are nested three or more deep I think
most of the people I have worked with would be completely
mystified.
Quote:

It also require a great deal of care to ensure that all cases have been
covered (and none repeated). LoC is not a very good measure of clarity.

I thought we were playing a game with line counts. I would say LoC is
not a measure of clarity at all; note that my example has several
more lines than necessary, for reasons of clarity. I am sorry, but
I cannot take discussions about line counts seriously; the fact
that we teach each other to measure our code by an illusion that
has nothing to do with functionality, has no clear relation to
readibility or complexity, is somewhere between disturbing and
ridiculous.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Peter Dimov
Guest





PostPosted: Wed Jul 02, 2003 2:52 am    Post subject: Re: Using bool values as loop indexes Reply with quote

Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote

Quote:
In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker writes
KIM Seungbeom wrote:

For bools:

for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}


do_something(false);
do_something(true);

Much simpler.

True, for a single level but rather different when you have such loops
nested three or four deep -- which was the OP's motivation.

Three levels of bools are a very obfuscated way to count from 0 to 7.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.