Wong, Shin Guey | 15 Jul 05:18
Favicon

Question on the Boost Preprocessor library

Hi all,

 

This is my first email to this list; please point me out if I done anything wrong in this mail like the title format or etc…

 

I am a newbie to the Boost library. I am really interesting on the usage of the Boost preprocessor library. I would like to archive 1 of the thing but I am not sure whether it is possible with Boost preprocessor library:

            Converting the binary number to hexadecimal or decimal value

 

Eg: BIN2HEX(011) -> 0x3 or  BIN2DEC(011) -> 3

      BIN2HEX(1111) -> 0xf or  BIN2DEC(1111) -> 15

 

I had read the C-Template-Metaprogramming-Concepts-Tools-and-Techniques-from-Boost-and-Beyond-C-in-Depth-Series which tell me how to archive that using template. But what I really want is to done it with the preprocessor without using any template which will not affect the run time but only the compile time.

 

I know that I can use the loop and the arithmetic function from the Boost library but how do I get the binary number characters count, eg. COUNT(011) -> 3 or COUNT(0111) -> 4. So that I can use this count with loop and the arithmetic function to perform the conversion from binary to hexadecimal or decimal.

 

 

Thanks in advance.

Regards,
Shin Guey

 

_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Steven Watanabe | 15 Jul 07:15

Re: Question on the Boost Preprocessor library

AMDG

Wong, Shin Guey wrote:
>
> Hi all,
>
> This is my first email to this list; please point me out if I done 
> anything wrong in this mail like the title format or etc…
>
> I am a newbie to the Boost library. I am really interesting on the 
> usage of the Boost preprocessor library. I would like to archive 1 of 
> the thing but I am not sure whether it is possible with Boost 
> preprocessor library:
>
> Converting the binary number to hexadecimal or decimal value
>
> Eg: BIN2HEX(011) -> 0x3 or BIN2DEC(011) -> 3
>
> BIN2HEX(1111) -> 0xf or BIN2DEC(1111) -> 15
>
> I had read the 
>
C-Template-Metaprogramming-Concepts-Tools-and-Techniques-from-Boost-and-Beyond-C-in-Depth-Series 
> which tell me how to archive that using template. But what I really 
> want is to done it with the preprocessor without using any template 
> which will not affect the run time but only the compile time.
>
> I know that I can use the loop and the arithmetic function from the 
> Boost library but how do I get the binary number characters count, eg. 
> COUNT(011) -> 3 or COUNT(0111) -> 4. So that I can use this count with 
> loop and the arithmetic function to perform the conversion from binary 
> to hexadecimal or decimal.
>

You can't implement BIN2DEC(1111) using Boost.Preprocessor
arithmetic. The only way to do it is:
#define BIN2DEC_0 0
#define BIN2DEC_1 1
#define BIN2DEC_11 2
...
#define BIN2DEC_1111 15
...

There is a way to get BIN2HEX(1 1 1 1) for example:

#include <boost/preprocessor/control/while.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/cat.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/dec.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/eat.hpp>

#define BINARY_IS_ONE_IMPL_0
#define BINARY_IS_ONE_IMPL_1
#define BINARY_IS_ONE(x) 
BOOST_PP_IS_EMPTY(BOOST_PP_CAT(BINARY_IS_ONE_IMPL_, x))

#define BINARY_POP_FRONT_IMPL_0
#define BINARY_POP_FRONT_IMPL_1

#define BINARY_POP_FRONT_IMPL(x) BOOST_PP_CAT(BINARY_POP_FRONT_IMPL_, x)
#define BINARY_CLEAR(x) EMPTY_BINARY

#define BINARY_POP_FRONT(x) BOOST_PP_IF(BINARY_IS_ONE(x), BINARY_CLEAR, 
BINARY_POP_FRONT_IMPL)(x)

#define BINARY_IS_EMPTY_IMPL_EMPTY_BINARY
#define BINARY_IS_EMPTY(x) 
BOOST_PP_IS_EMPTY(BOOST_PP_CAT(BINARY_IS_EMPTY_IMPL_, x))

#define BINARY_SIZE_IMPL(n, x) (BINARY_POP_FRONT(BOOST_PP_TUPLE_ELEM(2, 
0, x)), n)
#define BINARY_SIZE_IMPL_PRED(n, x) 
BOOST_PP_NOT(BINARY_IS_ONE(BOOST_PP_TUPLE_ELEM(2, 0, x)))
#define BINARY_SIZE(x) BOOST_PP_TUPLE_ELEM(2, 1, 
BOOST_PP_WHILE(BINARY_SIZE_IMPL_PRED, BINARY_SIZE_IMPL, (x, 1)))

#define BINARY_FRONT_IMPL_0 0, ~
#define BINARY_FRONT_IMPL_1 1, ~
#define BINARY_FRONT_IMPL(x, y) x
#define BINARY_FRONT(x) BOOST_PP_CAT(BINARY_FRONT_IMPL, 
(BOOST_PP_CAT(BINARY_FRONT_IMPL_, x)))

#define BINARY_TO_HEX_IMPL_0000 0
#define BINARY_TO_HEX_IMPL_0001 1
#define BINARY_TO_HEX_IMPL_0010 2
#define BINARY_TO_HEX_IMPL_0011 3
#define BINARY_TO_HEX_IMPL_0100 4
#define BINARY_TO_HEX_IMPL_0101 5
#define BINARY_TO_HEX_IMPL_0110 6
#define BINARY_TO_HEX_IMPL_0111 7
#define BINARY_TO_HEX_IMPL_1000 8
#define BINARY_TO_HEX_IMPL_1001 9
#define BINARY_TO_HEX_IMPL_1010 A
#define BINARY_TO_HEX_IMPL_1011 B
#define BINARY_TO_HEX_IMPL_1100 C
#define BINARY_TO_HEX_IMPL_1101 D
#define BINARY_TO_HEX_IMPL_1110 E
#define BINARY_TO_HEX_IMPL_1111 F

#define BINARY_GET1(x) (BINARY_FRONT(x))
#define BINARY_GET2(x) (BINARY_FRONT(x))BINARY_GET1(BINARY_POP_FRONT(x))
#define BINARY_GET3(x) (BINARY_FRONT(x))BINARY_GET2(BINARY_POP_FRONT(x))
#define BINARY_GET4(x) (BINARY_FRONT(x))BINARY_GET3(BINARY_POP_FRONT(x))

#define BINARY_EVAL(x) x
#define BINARY_EMPTY
#define BINARY_POP1(x) BINARY_EVAL(BINARY_POP_FRONT BINARY_EMPTY(x))
#define BINARY_POP2(x) BINARY_POP1(BINARY_POP_FRONT(x))
#define BINARY_POP3(x) BINARY_POP2(BINARY_POP_FRONT(x))
#define BINARY_POP4(x) BINARY_POP3(BINARY_POP_FRONT(x))
#define BINARY_TO_HEX_IMPL(n, result) 
(BINARY_POP4(BOOST_PP_TUPLE_ELEM(2, 0, result)), 
BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, result), 
BOOST_PP_CAT(BINARY_TO_HEX_IMPL_, 
BOOST_PP_SEQ_CAT(BINARY_GET4(BOOST_PP_TUPLE_ELEM(2, 0, result))))))
#define BINARY_RESULT(n, result) /**/
#define BINARY_TO_HEX_IMPL_SHORT_CIRCUIT(n, result) 
BOOST_PP_IF(BINARY_TO_HEX_PRED(n, result), BINARY_TO_HEX_IMPL, 
BINARY_RESULT)(n, result)

#define BINARY_TO_HEX_PRED(n, x) 
BOOST_PP_NOT(BINARY_IS_EMPTY(BOOST_PP_TUPLE_ELEM(2, 0, x)))
#define BINARY_PAD_TO_4(x) BOOST_PP_REPEAT(BOOST_PP_MOD(BOOST_PP_SUB(4, 
BOOST_PP_MOD(BINARY_SIZE(x), 4)), 4), 0 BOOST_PP_TUPLE_EAT(3), ~) x
#define BINARY_TO_HEX(val) BOOST_PP_TUPLE_ELEM(2, 1, 
BOOST_PP_WHILE(BINARY_TO_HEX_PRED, BINARY_TO_HEX_IMPL_SHORT_CIRCUIT, 
(BINARY_PAD_TO_4(val), 0x)))

BINARY_TO_HEX(1 0 1 0 0 1)

In Christ,
Steven Watanabe
boost_www | 16 Jul 09:01
Favicon

Several questions on C++

Hello

Sorry, I have several questions on C++ instead of any boost library.
But I believe the boost guys could easily give me help. :-)

1) I found code fragment like this, esp. in macro definitions:

do {      \
          \
// ...    \
} while(0)

Why is the do/while clause needed here?

2) I found large amount of code like this in a class implementation:

AClass::func()
{
	this->func1();
}

Why is 'this->' needed?

Thanks for any help.

B/Rgds
Max

_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Nat Goodspeed | 16 Jul 17:40
Favicon

Re: Several questions on C++

boost_www wrote:

> 1) I found code fragment like this, esp. in macro definitions:
> 
> do {      \
>           \
> // ...    \
> } while(0)
> 
> Why is the do/while clause needed here?

That's a macro idiom that dates back to classic C. It packages a 
compound statement { stmt1; stmt2; } as if it were a single statement.

If you write

#define YOURMACRO(arg) { stmt1; stmt2; }

and a subsequent coder writes this:

if (some_condition)
     YOURMACRO(1);
else
     std::cout << "Whoops, error.\n";

he or she will get a nasty surprise. It works to drop the semicolon 
after YOURMACRO(1), but that imposes a new requirement: some macros must 
be followed by semicolons, others must NOT be followed by semicolons, 
and the coder must know something about the macro's implementation to 
use it correctly.

If you write

#define YOURMACRO(arg) do { stmt1; stmt2; } while (0)

then it's appropriate (required) to write a semicolon after the macro 
invocation, and subsequent coders can do that consistently without 
needing to know which kind of macro this is.

> 2) I found large amount of code like this in a class implementation:
> 
> AClass::func()
> {
> 	this->func1();
> }
> 
> Why is 'this->' needed?

There are a few different reasons.

1. Some people write that as a stylistic preference, since it clarifies 
that you're referencing a data member rather than a local variable.

2. In some IDEs, when you write "this->", the IDE pops up a list of 
members from which to choose.

3. In some arcane scenarios such as a template subclass derived from a 
template base class, the language sometimes requires 
this->baseClassMember (though I believe MSVC still permits a plain 
baseClassMember reference as an extension).

But if you ask any more such questions on this list, the moderator might 
yell at both of us. ;-)
boost_www | 17 Jul 03:47
Favicon

Re: Several questions on C++

hello Nat,

Thanks you very much for your explanation!

for 1), I never heard of that idiom. In fact, after playing with C++
for more thant 10 years, I am still keeping finding interesting corners
of the language. :)

What I get from your information is that, the do/while clause is 
a MUST-HAVE and is obviously intentional.

for 2), it seems that 'this->' is a question of coding style and generally
we could omit it.

I really appreciate your help! and I believe the moderator of the list
will not yell to us for such topic. :-)

B/Rgds
Max

> 1) I found code fragment like this, esp. in macro definitions:
> 
> do {      \
>           \
> // ...    \
> } while(0)
> 
> Why is the do/while clause needed here?

That's a macro idiom that dates back to classic C. It packages a 
compound statement { stmt1; stmt2; } as if it were a single statement.

If you write

#define YOURMACRO(arg) { stmt1; stmt2; }

and a subsequent coder writes this:

if (some_condition)
     YOURMACRO(1);
else
     std::cout << "Whoops, error.\n";

he or she will get a nasty surprise. It works to drop the semicolon 
after YOURMACRO(1), but that imposes a new requirement: some macros must 
be followed by semicolons, others must NOT be followed by semicolons, 
and the coder must know something about the macro's implementation to 
use it correctly.

If you write

#define YOURMACRO(arg) do { stmt1; stmt2; } while (0)

then it's appropriate (required) to write a semicolon after the macro 
invocation, and subsequent coders can do that consistently without 
needing to know which kind of macro this is.

> 2) I found large amount of code like this in a class implementation:
> 
> AClass::func()
> {
> 	this->func1();
> }
> 
> Why is 'this->' needed?

There are a few different reasons.

1. Some people write that as a stylistic preference, since it clarifies 
that you're referencing a data member rather than a local variable.

2. In some IDEs, when you write "this->", the IDE pops up a list of 
members from which to choose.

3. In some arcane scenarios such as a template subclass derived from a 
template base class, the language sometimes requires 
this->baseClassMember (though I believe MSVC still permits a plain 
baseClassMember reference as an extension).

But if you ask any more such questions on this list, the moderator might 
yell at both of us. ;-)
_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org

_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Marshall Clow | 17 Jul 04:26

Re: Several questions on C++

At 9:47 AM +0800 7/17/08, boost_www wrote:
>hello Nat,
>
>Thanks you very much for your explanation!
>
>for 1), I never heard of that idiom. In fact, after playing with C++
>for more thant 10 years, I am still keeping finding interesting corners
>of the language. :)
>
>What I get from your information is that, the do/while clause is
>a MUST-HAVE and is obviously intentional.

Absolutely.

>for 2), it seems that 'this->' is a question of coding style and generally
>we could omit it.

Generally, but not always.
If you want to call a member function (_especially_ in templated/library code),
then you should qualify it with "this->", because you don't know if 
there will be
a function named "func1" available when the code is compiled.
--

-- 
-- Marshall

Marshall Clow     Idio Software   <mailto:marshall <at> idio.com>

It is by caffeine alone I set my mind in motion.
It is by the beans of Java that thoughts acquire speed,
the hands acquire shaking, the shaking becomes a warning.
It is by caffeine alone I set my mind in motion.
Max | 17 Jul 07:30
Favicon

Re: Several questions on C++

Hello Marshall

Thanks.

With your additional point, the things are getting more clearer.

B/Rgds
Max

----- Original Message ---- 
From: Marshall Clow
To: boost-users <at> lists.boost.org
Sent: 2008-07-17 10:26:23
Subject: Re: [Boost-users] Several questions on C++

>
At 9:47 AM +0800 7/17/08, boost_www wrote:
>hello Nat,
>
>Thanks you very much for your explanation!
>
>for 1), I never heard of that idiom. In fact, after playing with C++
>for more thant 10 years, I am still keeping finding interesting corners
>of the language. :)
>
>What I get from your information is that, the do/while clause is
>a MUST-HAVE and is obviously intentional.

Absolutely.

>for 2), it seems that 'this->' is a question of coding style and generally
>we could omit it.

Generally, but not always.
If you want to call a member function (_especially_ in templated/library code),
then you should qualify it with "this->", because you don't know if 
there will be
a function named "func1" available when the code is compiled.
--

-- 
-- Marshall

Marshall Clow     Idio Software   <mailto:marshall <at> idio.com>

It is by caffeine alone I set my mind in motion.
It is by the beans of Java that thoughts acquire speed,
the hands acquire shaking, the shaking becomes a warning.
It is by caffeine alone I set my mind in motion.
_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org

_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
John Femiani | 16 Jul 19:33
Favicon

Re: Several questions on C++


> 
> 1) I found code fragment like this, esp. in macro definitions:
> 
> do {      \
>           \
> // ...    \
> } while(0)
> 
> Why is the do/while clause needed here?

Probably so the statements inside the do...while are in their own block,
with its own scope. If simple curly braces were used, then sometimes it
would break 'if' statements in a weird way, so using do {} while(0) is
more robust.

Example:
#define FOO { ... }

if (cond)
   FOO;  //<--- breaks
else
   FOO;

> 
> 2) I found large amount of code like this in a class implementation:
> 
> AClass::func()
> {
> 	this->func1();
> }
> 
> Why is 'this->' needed?
> 

Probably because the class is a template with a template base class, so
explicitly using this-> is one way to make sure that g++ recognizes
func1 as an inheritted member function. Another possiblity is that
typeing '->' triggers the autocomplete function in some editors, so
typing 'this->' provides them with a convenient way to recall & type the
correct function name within the scope of 'this'.
boost_www | 17 Jul 03:49
Favicon

Re: Several questions on C++

Hello John 

Also many thanks to you for your explanation.

B/Rgds
Max

----- Original Message ---- 
From: John Femiani
To: boost-users <at> lists.boost.org
Sent: 2008-07-17 01:36:03
Subject: Re: [Boost-users] Several questions on C++

>

> 
> 1) I found code fragment like this, esp. in macro definitions:
> 
> do {      \
>           \
> // ...    \
> } while(0)
> 
> Why is the do/while clause needed here?

Probably so the statements inside the do...while are in their own block,
with its own scope. If simple curly braces were used, then sometimes it
would break 'if' statements in a weird way, so using do {} while(0) is
more robust.

Example:
#define FOO { ... }

if (cond)
   FOO;  //<--- breaks
else
   FOO;

> 
> 2) I found large amount of code like this in a class implementation:
> 
> AClass::func()
> {
> 	this->func1();
> }
> 
> Why is 'this->' needed?
> 

Probably because the class is a template with a template base class, so
explicitly using this-> is one way to make sure that g++ recognizes
func1 as an inheritted member function. Another possiblity is that
typeing '->' triggers the autocomplete function in some editors, so
typing 'this->' provides them with a convenient way to recall & type the
correct function name within the scope of 'this'.
_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org

_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Joel Falcou | 15 Jul 09:39
Gravatar

Re: Question on the Boost Preprocessor library

Wong, Shin Guey a écrit :
> I had read the 
>
C-Template-Metaprogramming-Concepts-Tools-and-Techniques-from-Boost-and-Beyond-C-in-Depth-Series 
> which tell me how to archive that using template. But what I really want 
> is to done it with the preprocessor without using any template which 
> will not affect the run time but only the compile time.

You are aware that tempalte meta-programming WILL result in compile-time 
expansion fo the resulting constant do you ? Why did you reject this 
solution ?

Gmane