471,612 Members | 2,515 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,612 software developers and data experts.

Exiting a loop half way through

While playing around with my quine I was reminded
of a situation I have come across before: when
the exit-condition for a loop needs to be checked
in the middle of a loop, rather than at the
beginning (while) or the end (do ... while). It
always seems to come up when I'm hand-rolling very
simple parsers. (Doctor, it hurts when I do this ...)

Anyone want to argue for or against any of these
three alternatives, or suggest something better?

template <typename RulesFuction>
void format (const string & s, RulesFunction f)
{
// f will be applied to an iterator to a '%' character.
// Applying f should return an iterator to the character
// after the whole '%' escape sequence.
// Side-effects of f should be limited to output on cout.

iter b (s.begin ()), e (s.end ()), i;
ostream_iterator <char> out (cout);

#if defined A

copy (b, i = find (b, e, '%'), out);
while (i != e) {
b = f (i);
copy (b, i = find (b, e, '%'), out);
}

#elif defined B

while (true) {
copy (b, i = find (b, e, '%'), out);
if (i == e) break;
b = f (i);
}

#else

goto start;
while (i != e) {
b = f (i);
start: copy (b, i = find (b, e, '%'), out);
}

#endif

}

Jul 19 '05 #1
5 3791
Buster Copley wrote:
While playing around with my quine


Practice what you preach, Buster. The complete,
compilable code follows. You can see which way
I've settled on at the moment.

#include <iostream>
#include <ostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
typedef string::const_iterator iter;

template <typename F>
void format (const string & s, F f) {
iter b (s.begin ()), e (s.end ()), i;
ostream_iterator <char> out (cout);
goto start;
while (i != e) {
b = f (i);
start: copy (b, i = find (b, e, '%'), out);
}
}

iter p (iter i) {
cout << '%' << * ++ i;
if (* i == 'n') cout << "\"\n \"";
return ++ i;
}

struct q {
iter operator () (iter i) {
switch (* ++ i) {
case 's': format (s, p); break;
case 'n': cout << '\n'; break;
case 'q': cout << '\"'; break;
case 'b': cout << '\\'; break;
default: cout << * i;
}
return ++ i;
}
q (const string & s) : s (s) { }
const string & s;
};

int main () {
string s (
"#include <iostream>%n"
"#include <ostream>%n"
"#include <string>%n"
"#include <algorithm>%n"
"#include <iterator>%n"
"using namespace std;%n"
"typedef string::const_iterator iter;%n"
"%n"
"template <typename F>%n"
"void format (const string & s, F f) {%n"
" iter b (s.begin ()), e (s.end ()), i;%n"
" ostream_iterator <char> out (cout);%n"
" goto start;%n"
" while (i != e) {%n"
" b = f (i);%n"
" start: copy (b, i = find (b, e, '%%'), out);%n"
" }%n"
"}%n"
"%n"
"iter p (iter i) {%n"
" cout << '%%' << * ++ i;%n"
" if (* i == 'n') cout << %q%b%q%bn %b%q%q;%n"
" return ++ i;%n"
"}%n"
"%n"
"struct q {%n"
" iter operator () (iter i) {%n"
" switch (* ++ i) {%n"
" case 's': format (s, p); break;%n"
" case 'n': cout << '%bn'; break;%n"
" case 'q': cout << '%b%q'; break;%n"
" case 'b': cout << '%b%b'; break;%n"
" default: cout << * i;%n"
" }%n"
" return ++ i;%n"
" }%n"
" q (const string & s) : s (s) { }%n"
" const string & s;%n"
"};%n"
"%n"
"int main () {%n"
" string s (%n"
" %q%s%q);%n"
" format (s, q (s));%n"
"}%n"
"");
format (s, q (s));
}

Jul 19 '05 #2
Buster Copley wrote:
While playing around with my quine I was reminded
of a situation I have come across before: when
the exit-condition for a loop needs to be checked
in the middle of a loop, rather than at the
beginning (while) or the end (do ... while). It
always seems to come up when I'm hand-rolling very
simple parsers. (Doctor, it hurts when I do this ...)

Anyone want to argue for or against any of these
three alternatives, or suggest something better?

copy (b, i = find (b, e, '%'), out);
while (i != e) {
b = f (i);
copy (b, i = find (b, e, '%'), out);
Code duplication.
#elif defined B

while (true) {
copy (b, i = find (b, e, '%'), out);
if (i == e) break;
b = f (i);
How I used to do that (if I had to) was to add // NOTE! after the break.
So no one will miss it.
goto start;
while (i != e) {
b = f (i);
start: copy (b, i = find (b, e, '%'), out);


Ahh. I looked at a goto. Now I have to go and confess. :-)

I sort of like that. It reminds me of the Duff's device and this:

http://www.cuj.com/documents/s=8890/cujexp0310dewhurst/

Since I am coming down with a fever (and it is not Saturday night here) I
might have missed important things here.

--
WW aka Attila
Jul 19 '05 #3
White Wolf wrote:
copy (b, i = find (b, e, '%'), out);
while (i != e) {
b = f (i);
copy (b, i = find (b, e, '%'), out);
Code duplication.


Yeah, that's my least favourite.
#elif defined B

while (true) {
copy (b, i = find (b, e, '%'), out);
if (i == e) break;
b = f (i);

How I used to do that (if I had to) was to add // NOTE! after the break.
So no one will miss it.


Good call.
goto start;
while (i != e) {
b = f (i);
start: copy (b, i = find (b, e, '%'), out);

Ahh. I looked at a goto. Now I have to go and confess. :-)

I sort of like that.


Me too.
It reminds me of the Duff's device and this:

http://www.cuj.com/documents/s=8890/cujexp0310dewhurst/

Since I am coming down with a fever (and it is not Saturday night here) I
might have missed important things here.


Thanks a lot for your comments.

Jul 19 '05 #4
"White Wolf" <wo***@freemail.hu> wrote in message
news:bk**********@phys-news1.kolumbus.fi...
#elif defined B

while (true) {
copy (b, i = find (b, e, '%'), out);
if (i == e) break;
b = f (i);


How I used to do that (if I had to) was to add // NOTE! after the break.
So no one will miss it.


Hello, Wolf and Buster.

Did you ever consider:

while(true)
{
doSomethingFirst();
if (condition)
break;

doSomethingElse();
}

or possibly even (although I wouldn't do this):

while(true)
{
doSomethingFirst();

if (condition) break;

doSomethingElse();
}

To me whitespace seems the most natural way to emphasize control statements,
since most whitespace is already used for that very purpose.

Jul 19 '05 #5
"Kevin Saff" <go********@kevin.saff.net> wrote
while(true)
{
doSomethingFirst();
if (condition)
break;

doSomethingElse();
}

To me whitespace seems the most natural way to emphasize control statements,
since most whitespace is already used for that very purpose.


Thanks very much for your response.
Buster
Jul 19 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

39 posts views Thread by vineoff | last post: by
2 posts views Thread by pnp | last post: by
8 posts views Thread by Nathan Sokalski | last post: by
1 post views Thread by XIAOLAOHU | last post: by
1 post views Thread by ZEDKYRIE | last post: by

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

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