
Greetings, At the moment I'm anticipating a formal review of the binary_int implementation sometime in October. This seems like a good time to suggest that anyone who's curious take a look at the pre-release version of binary_int. Anything caught now improves the likelihood that the October review will be the final review. The binary_int template allows the compile time expression of integer binary literals. Usage looks like this: unsigned int regValue = binary_int<1000,1001,0011,0000>::value There is no run-time code overhead for using this template; all overhead is at compile time. I expect these binary literals to work any place that an integer literal would work at compile (not preprocessing) time. The template is designed to allow binary values up to 64-bits to be expressed, although it has only been tested up to 32-bits to date. You'll find the template, its documentation, and a small unit test at: http://boost-consulting.com/vault/ under binary_int.zip In addition to the issue of whether the template works for you, there are four points I'm curious about: o Some compilers used to complain when the most significant bit of a binary_int was set. I've fixed that problem as well as I know how. Do any compilers still see this problem, and does it produce warnings or full fledged errors? o Does the template properly produce 64-bit values on a 64-bit compiler? The unit test only goes up to 32-bits since neither of my compilers support 64-bit compilation. o Are the names 'binary_int' and 'binary_nibble' good names? Pavel Vozenilek, who has very kindly been my Boost mentor, suggests 'bits' and 'nibble' may be better names. o There's a BOOST_WORKAROUND in the template so I can do something vaguely BOOST_STATIC_ASSERT like. Pavel suggests that the workaround would be better solved in a general form that all compilers can accept. What would be a better solution to the BOOST_WORKAROUND? Thanks for your consideration. Scott Schurr

On 9/2/05, Scott Schurr <scott_schurr@credence.com> wrote:
I expect these binary literals to work any place that an integer literal would work at compile (not preprocessing) time.
Forgive me if this has already been addressed, but is there a reason as to why a template is prefered here as opposed to a macro solution? A solution using preprocessor metaprogramming would allow one to use the value at preprocessing time as well as compile-time, making a template version unecessary, and syntactically it would be even simpler since you wouldn't need to do ::value. The call could be as simple as BOOST_BINARY_INT( (1100)(0011)(1010) ) using Boost.Preprocessor sequences. Again, I am sorry if this has already been addressed. -- -Matt Calabrese

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Matt Calabrese
I expect these binary literals to work any place that an integer literal would work at compile (not preprocessing) time.
Forgive me if this has already been addressed, but is there a reason as to why a template is prefered here as opposed to a macro solution? A solution using preprocessor metaprogramming would allow one to use the value at preprocessing time as well as compile-time, making a template version unecessary, and syntactically it would be even simpler since you wouldn't need to do ::value. The call could be as simple as BOOST_BINARY_INT( (1100)(0011)(1010) ) using Boost.Preprocessor sequences. Again, I am sorry if this has already been addressed.
The problem is that there isn't any arbitrary precision arithmetic support in the pp-lib. If there was, you could do better than that for syntax: BOOST_BINARY_INT( 1100 0011 1010 ) Regards, Paul Mensonides

On 9/2/05, Paul Mensonides <pmenso57@comcast.net> wrote:
The problem is that there isn't any arbitrary precision arithmetic support in the pp-lib. If there was, you could do better than that for syntax:
BOOST_BINARY_INT( 1100 0011 1010 )
You are under the mistaken impression that the resultant number would have to be a decimal literal and rely on Boost.Preprocessor functionality for arithmetic computations. Storing the number as a hex literal makes things much easier, since each nibble is just a hex digit. All you do is convert each nibble to hex then concatenate them all together. The fact that the literal is in hex, it has the downside that it would be more difficult to use with Boost.Preprocessor operations, but then again, the template form couldn't do that either. Even still, if you really wanted to use it with Boost.Preprocessor macros, the time could be taken to make an implementation which results in a small decimal literal. Here is a fully functional BOOST_BINARY_INT implementation I put together describing what I mean: http://www.illegal-immigration.com/Riv/boost/binary_int.hpp Example usage would be BOOST_BINARY_INT( (1100)(0101) ) to represent the hex literal 0xC5 It works exactly as I described and can be used at preprocessing time (though again, note that it is a hex literal). I do not immediately see how to implement it allowing the syntax you describe (where your nibbles are simply separated by spaces rather than using a Boost.Preprocessor sequence), so if you could, please enlighten me as I know you must be more experienced with the preprocessor (I love Boost.Preprocessor by the way). Note that compared to the template version, this implementation actually works at preprocessor time, is even shorter and arguably more elegant in implementation, you can easily append integer suffixes at the end, it doesn't allow obvious mistakes such as passing a decimal value of 65, and since it doesn't deal with complex language features such as templates you have less to worry about concerning portability. As well, if you wish to use the number as an MPL style integer constant, all you have to do is pass the resultant value as an argument to an integer constant template. As a side note, I noticed while making this that BOOST_PP_SEQ_CAT fails on sequences of size 1. While obviously no concatenations occur with a sequence of this size, logically the result should just be the single element, so I consider this an error in Boost.Preprocessor (any disagreements on that?). I had to make a workaround to account for a single nibble, here, though the resultant code is still under 60 lines. Also note that I only allowed values which are 4 binary digits long. This was just a design choice as I believe it would be confusing having nibbles in the middle that have under 4 digits. Of course, I could always make a special case that only the first nibble is allowed to be under 4 binary digits if the desire for that functionality exists. -- -Matt Calabrese

On 9/3/05, Matt Calabrese <rivorus@gmail.com> wrote:
On 9/2/05, Paul Mensonides <pmenso57@comcast.net> wrote:
The problem is that there isn't any arbitrary precision arithmetic support in the pp-lib. If there was, you could do better than that for syntax:
BOOST_BINARY_INT( 1100 0011 1010 )
I do not immediately see how to implement it allowing the syntax you describe (where your nibbles are simply separated by spaces rather than using a Boost.Preprocessor sequence), so if you could, please enlighten me as I know you must be more experienced with the preprocessor (I love Boost.Preprocessor by the way).
Nevermind, I figured out a way to do it myself with lots of macro magic. A version allowing the more simple syntax you originally alluded to is available here: http://www.illegal-immigration.com/Riv/boost/binary_literal.hpp Also, I changed the macro name to BOOST_BINARY_LITERAL Usage is as simple as: BOOST_BINARY_LITERAL( 101 0111 1010 0110 ) The first nibble is allowed to be written with under 4 explicit bits, but the remaining nibbles must use a complete 4 bits each. This was done to avoid confusion. If you wish to append standard integer suffixes, you can use the macro BOOST_SUFFIXED_BINARY_LITERAL Usage for that is: BOOST_SUFFIXED_BINARY_LITERAL( 101 0111 1010 0110, UL ) It should work for integers of any reasonable size, even well beyond 64 bits, and results in a hex literal at preprocessing time. -- -Matt Calabrese

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Matt Calabrese
Sorry Matt, I missed your immediate response, so I'll answer both now.
The problem is that there isn't any arbitrary precision arithmetic support in the pp-lib. If there was, you could do better than that for syntax:
BOOST_BINARY_INT( 1100 0011 1010 )
You are under the mistaken impression that the resultant number would have to be a decimal literal and rely on Boost.Preprocessor functionality for arithmetic computations.
Yes, you are right. I was thinking about actually reading the binary digits and *computing* the result. In other words, I was thinking about the completely general approach rather than leveraging the compatible base property of hexadecimal (or octal) and binary. However, the reason that I looked at it from that perspective is because it is possible to do arbitrary-precision arithmetic with the preprocessor (Chaos does it, for example), and I actually use binary literals as an example in the docs. With such arbitrary-precision support, you can read numbers in any base--hence my overlooking the obvious solution. :)
Storing the number as a hex literal makes things much easier, since each nibble is just a hex digit. All you do is convert each nibble to hex then concatenate them all together. The fact that the literal is in hex, it has the downside that it would be more difficult to use with Boost.Preprocessor operations
And that doesn't really matter. Binary literals, AFAICT, are rarely useful for expressing actual numbers so much as sets of flags.
but then again, the template form couldn't do that either. Even still, if you really wanted to use it with Boost.Preprocessor macros, the time could be taken to make an implementation which results in a small decimal literal
I can already do this with Chaos, except with (theoretically) millions of digits. :) However, I don't think it is that important (at this point) to do that. I haven't yet encountered a situation where it would be useful. I certainly don't mean to belittle what you've done, BTW, I'm only referring to input to pp-lib macros in bases other than decimal. Rather, it is an expression of frustration with and utter distaste for the pp-lib and the strictures under which it must operate (namely, compatibility with broken preprocessors). At one point, I tried to implement arbitrary-precision arithmetic in the pp-lib. However, arbitrary-precision arithmetic is "somewhat complex", and I failed to make it usuable on several popular preprocessors. In retrospect, I think arbitrary-precision arithmetic may have been the key reason why I started the Chaos project.
It works exactly as I described and can be used at preprocessing time (though again, note that it is a hex literal). I do not immediately see how to implement it allowing the syntax you describe (where your nibbles are simply separated by spaces rather than using a Boost.Preprocessor sequence), so if you could, please enlighten me as I know you must be more experienced with the preprocessor (I love Boost.Preprocessor by the way).
I see from your other post that you solved this problem already.
As a side note, I noticed while making this that BOOST_PP_SEQ_CAT fails on sequences of size 1. While obviously no concatenations occur with a sequence of this size, logically the result should just be the single element, so I consider this an error in Boost.Preprocessor (any disagreements on that?).
Well, my only excuse for this is that I'd have to check the length of the sequence beforehand (or at least that it is less than two elements)--which takes time. Fixed in the CVS.
Also note that I only allowed values which are 4 binary digits long. This was just a design choice as I believe it would be confusing having nibbles in the middle that have under 4 digits.
Note that one of the common uses of binary literals is as packed representations of several values. It isn't all that unusual to have a representation where the length in bits of each part are arbitrary. If I were you, I would allow such usage, but then you can't do a simple, direct mapping. You'd have to convert the input to (e.g.) a sequence of bits first, and the break it up into a mapping to hexadecimal digits. One of the advantages to doing binary literals with the preprocessor is that you *can* do this. The template mechanism cannot distinguish between 0001 and 01, but the preprocessor can. (Of course, it becomes unreasonable to allow bit groups that are larger than a byte.)
Nevermind, I figured out a way to do it myself with lots of macro magic. A version allowing the more simple syntax you originally alluded to is available here:
http://www.illegal-immigration.com/Riv/boost/binary_literal.hpp
Also, I changed the macro name to BOOST_BINARY_LITERAL
Usage is as simple as:
BOOST_BINARY_LITERAL( 101 0111 1010 0110 )
The first nibble is allowed to be written with under 4 explicit bits, but the remaining nibbles must use a complete 4 bits each. This was done to avoid confusion.
Personally, I think that you should get rid of this restriction. Allow bit group up to eight bits (256+256 macros, I know), but where each group is not supposed to represent a "nibble" or anything. I.e. BINARY_LITERAL( 1 0 1 0111 10 10 011 0 ) produces the same value as above. It isn't natural, in my opinion, to have implicit fill bits in binary literals except possibly at the beginning of the entire thing. Allowing "1010 110" and having it mean "1010 0110" isn't just confusing, it's an abomination. Regards, Paul Mensonides

On 9/5/05, Paul Mensonides <pmenso57@comcast.net> wrote:
Yes, you are right. I was thinking about actually reading the binary digits and *computing* the result. In other words, I was thinking about the completely general approach rather than leveraging the compatible base property of hexadecimal (or octal) and binary. However, the reason that I looked at it from that perspective is because it is possible to do arbitrary-precision arithmetic with the preprocessor (Chaos does it, for example), and I actually use binary literals as an example in the docs. With such arbitrary-precision support, you can read numbers in any base--hence my overlooking the obvious solution. :)
I really must take a look at Chaos sometime. On 9/5/05, Paul Mensonides <pmenso57@comcast.net> wrote:
And that doesn't really matter. Binary literals, AFAICT, are rarely useful for expressing actual numbers so much as sets of flags.
Yeah, that's pretty much the conclusion I've come to as well. On 9/5/05, Paul Mensonides <pmenso57@comcast.net> wrote:
Well, my only excuse for this is that I'd have to check the length of the sequence beforehand (or at least that it is less than two elements)--which takes time. Fixed in the CVS.
Great. On 9/5/05, Paul Mensonides <pmenso57@comcast.net> wrote:
Also note that I only allowed values which are 4 binary digits long. This was just a design choice as I believe it would be confusing having nibbles in the middle that have under 4 digits.
Note that one of the common uses of binary literals is as packed representations of several values. It isn't all that unusual to have a representation where the length in bits of each part are arbitrary. If I were you, I would allow such usage, but then you can't do a simple, direct mapping. You'd have to convert the input to (e.g.) a sequence of bits first, and the break it up into a mapping to hexadecimal digits. One of the advantages to doing binary literals with the preprocessor is that you *can* do this. The template mechanism cannot distinguish between 0001 and 01, but the preprocessor can. (Of course, it becomes unreasonable to allow bit groups that are larger than a byte.)
Yeah, I think I will do that. I also wanted to keep 4-bit sequences for clarity and to prevent people from making subtle mistakes (accidentally writing 7 1s instead of 8 1s, or something like that isn't too unreasonable and can be tough for a programmer to notice), however the more I think about it, the more I agree that I should allow representations as you describe, since the desire truely is there and it's not horribly difficult to provide the functionality. On 9/5/05, Paul Mensonides <pmenso57@comcast.net> wrote:
Allowing "1010 110" and having it mean "1010 0110" isn't just confusing, it's an abomination.
Yeah, and that's another thing that really bothered me about the template implementation. Using the preprocessor gets rid this. I must go, but I will update tomorrow. It's after 5:00 AM here and I have yet to sleep. Thanks for the feedback and suggestions. -- -Matt Calabrese

On 9/5/05, Paul Mensonides <pmenso57@comcast.net> wrote:
Also note that I only allowed values which are 4 binary digits long. This was just a design choice as I believe it would be confusing having nibbles in the middle that have under 4 digits.
Note that one of the common uses of binary literals is as packed representations of several values. It isn't all that unusual to have a representation where the length in bits of each part are arbitrary. If I were you, I would allow such usage, but then you can't do a simple, direct mapping. You'd have to convert the input to (e.g.) a sequence of bits first, and the break it up into a mapping to hexadecimal digits. One of the advantages to doing binary literals with the preprocessor is that you *can* do this. The template mechanism cannot distinguish between 0001 and 01, but the preprocessor can. (Of course, it becomes unreasonable to allow bit groups that are larger than a byte.)
Yeah, I think I will do that. I also wanted to keep 4-bit sequences for clarity and to prevent people from making subtle mistakes (accidentally writing 7 1s instead of 8 1s, or something like that isn't too unreasonable and can be tough for a programmer to notice), however the more I think about it, the more I agree that I should allow representations as you describe, since the desire truely is there and it's not horribly difficult to provide the functionality.
Sorry for the delay. I wanted to do this on Monday but I've been busy all week. After that reply, Paul emailed me his take on a solution using his Chaos preprocessor library which influenced some changes in design for my implementation using boost, though I did alter the logic a bit. Since I now allow arbitrary groupings of bits whose lengths are 8 or below, converting to octal is actually simpler than converting to hex, so the macro now yields an octal value. In addition to that, I added two extra forms: BOOST_BINARY_LITERAL_D and BOOST_SUFFIXED_BINARY_LITERAL_D, which take a an extra parameter at the start of the list which represents the while recursion depth (for more efficient use when nested inside another while call). Originally I wanted to make _S versions as well to account for the BOOST_PP_SEQ_FOLD_LEFT recursion depth "s," however I ran into some troubles since Boost.Preprocessor concatenates "s" onto BOOST_PP_SEQ_FOLD_LEFT_ with ## as opposed to BOOST_PP_CAT for SEQ_CAT and SEQ_TRANSFORM. This means that my macro call to deduce the recursion depth never expands prior to concatenation. I'm sure there is a way for my implementation to forcibly expand the macro at the level of code that my implementation uses i.e. with BOOST_PP_EXPAND or other techniques, but my previous experience with the preprocessor doesn't go very far beyond using Boost.Preprocessor to produce sequential template specializations, so perhaps Paul or someone else would be able to fill in the gap more quickly, if they wouldn't mind. Anyway, the macro is useable, efficient, and fairly elegant at the moment, so there's not really too much to complain about.You can test out this version at: http://www.illegal-immigration.com/Riv/boost/binary_literal2.hpp Again, the main change is that you can now use forms such as: BOOST_BINARY_LITERAL( 101 1000 0011101 011101 0011 ) where each group is 8 bits or less in size. -- -Matt Calabrese

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Matt Calabrese
Sorry for the delay. I wanted to do this on Monday but I've been busy all week. After that reply, Paul emailed me his take on a solution using his Chaos preprocessor library which influenced some changes in design for my implementation using boost, though I did alter the logic a bit. Since I now allow arbitrary groupings of bits whose lengths are 8 or below, converting to octal is actually simpler than converting to hex, so the macro now yields an octal value. In addition to that, I added two extra forms: BOOST_BINARY_LITERAL_D and BOOST_SUFFIXED_BINARY_LITERAL_D, which take a an extra parameter at the start of the list which represents the while recursion depth (for more efficient use when nested inside another while call). Originally I wanted to make _S versions as well to account for the BOOST_PP_SEQ_FOLD_LEFT recursion depth "s," however I ran into some troubles since Boost.Preprocessor concatenates "s" onto BOOST_PP_SEQ_FOLD_LEFT_ with ## as opposed to BOOST_PP_CAT for SEQ_CAT and SEQ_TRANSFORM. This means that my macro call to deduce the recursion depth never expands prior to concatenation.
I'm not sure what you mean here. Can you elaborate with a small example? My immediate guess at what you're referring to is something like ABC_ ## MACRO() where MACRO() isn't expanding, but I may be misreading it. As far as introducing both an _S and a _D suffixed variation--don't bother. Just deduce one of them (or both), but it isn't worth cluttering the interface with multiple variations. The pp-lib itself has this same issue in a few places, and I find my "solutions" obnoxious at best (e.g. BOOST_PP_REPEAT_FROM_TO_D_ ## z). In fact, this is one of the major design flaws of the pp-lib. Originally, it was the best I could do. Now, I can do better, but not without dropping support for quite a few preprocessors--including heavily used ones like VC. [Chaos, as usual, doesn't suffer from this problem.] A couple of other things... 1) Is there a reason why you're rolling your own COMPL instead of using BOOST_PP_COMPL? Did it fail to work correctly for some reason? 2) The pp-lib already has an BOOST_PP_IS_NULLARY. However, it is not a documented interface because it isn't portable to all (broken) preprocessors. It is, however, hacked up with workarounds for VC and older versions of Metrowerks. It should be safe to use on most preprocessors. However, the preprocessors where it won't work (that I know of) are IBM's, Sun's, and Borland's. Borland's separate command line preprocessor can handle it, but the preprocessor integrated into the compiler itself has a serious bug that prevents it. I do have an alternative implementation, thanks to Daniel James, that will work on Borland's preprocessor, but it isn't integrated into the pp-lib because IBM, Sun, and Borland all currently share the same configuration. (see quote below) Regards, Paul Mensonides
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Daniel James Sent: Sunday, August 15, 2004 1:09 PM To: boost@lists.boost.org Subject: [boost] [preprocessor] BOOST_PP_IS_UNARY for Borland
I've written an implementation of BOOST_PP_IS_UNARY which works for Borland, and hopefully any other preprocessors which the current implementation doesn't. It is:
#define EAT2(x,y)
#define IS_UNARY_CHECK(x) ~, 1 BOOST_PP_RPAREN() \ EAT2 BOOST_PP_LPAREN() ~
#define IS_UNARY(x) IS_UNARY_1(IS_UNARY_CHECK x, 0) #define IS_UNARY_1(x, y) IS_UNARY_2(x, y) #define IS_UNARY_2(x, y) y
For a non-unary argument, the expansion is simple:
IS_UNARY(x) => IS_UNARY_1(IS_UNARY_CHECK x, 0) => IS_UNARY_2(IS_UNARY_CHECK x, 0) => 0
For a unary argument, it expands like this (I might have got the expansion order slightly wrong but, hopefully, this illustrates how it works):
IS_UNARY((x)y) => IS_UNARY_1(IS_UNARY_CHECK(x)y), 0) => IS_UNARY_2(~, 1 BOOST_PP_RPAREN() EAT2 BOOST_PP_LPAREN() ~y, 0) => IS_UNARY_2(~, 1) EAT2(~y, 0) => 1
The same technique can be used for BOOST_PP_IS_NULLARY and BOOST_PP_IS_BINARY.
So, if this is used as for borland, could these marcros be made 'public'? Also, with a full working BOOST_PP_IS_UNARY, I think it should be possible to make BOOST_PP_SEQ_NIL act as an empty sequence, if I write a patch to do that would it be accepted?
Daniel

On 9/10/05, Paul Mensonides <pmenso57@comcast.net> wrote:
I'm not sure what you mean here. Can you elaborate with a small example? My immediate guess at what you're referring to is something like ABC_ ## MACRO() where MACRO() isn't expanding, but I may be misreading it.
After using AUTO_REC to deduce the recursion depth and pass it to an _S form of the BINARY_LITERAL macro, just as I am doing with the BINARY_LITERAL and BINARY_LITERAL_D macros with DEDUCE_D, I was getting errors concerning the concatenation onto BOOST_PP_SEQ_FOLD_LEFT_ for the S form from TRANSFORM. Again, though, this may be do to my own misunderstanding of the preprocessor, but I believed it wasn't working because TRANSFORM called SEQ_FOLD_LEFT_S via a direct ## operation as opposed to using CAT and was concatenating the macro I was using before it was expanded. Correct me if this was an improper assumption and if there wasa fault in my own doing. 1) Is there a reason why you're rolling your own COMPL instead of using
BOOST_PP_COMPL? Did it fail to work correctly for some reason?
Yes. If I replace that code with a call to BOOST_PP_COMPL, at least in VC++ 7.1 which is what I was testing it on, I was getting errors. Try it out by just replacing the code with a call to BOOST_PP_COMPL. If there is something I am doing wrong, please tell me. 2) The pp-lib already has an BOOST_PP_IS_NULLARY. However, it is not a
documented interface because it isn't portable to all (broken) preprocessors. It is, however, hacked up with workarounds for VC and older versions of Metrowerks. It should be safe to use on most preprocessors. However, the preprocessors where it won't work (that I know of) are IBM's, Sun's, and Borland's. Borland's separate command line preprocessor can handle it, but the preprocessor integrated into the compiler itself has a serious bug that prevents it. I do have an alternative implementation, thanks to Daniel James, that will work on Borland's preprocessor, but it isn't integrated into the pp-lib because IBM, Sun, and Borland all currently share the same configuration. (see quote below)
Perhaps then I should change back to the less-elegant yet possibly more portable way I was doing it which did not use IS_NULLARY or IS_UNARY concepts -- from the 2nd out of the 3 files I posted (binary_literal.hpp), unless you have a better solution? -- -Matt Calabrese

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Matt Calabrese
After using AUTO_REC to deduce the recursion depth and pass it to an _S form of the BINARY_LITERAL macro, just as I am doing with the BINARY_LITERAL and BINARY_LITERAL_D macros with DEDUCE_D, I was getting errors concerning the concatenation onto BOOST_PP_SEQ_FOLD_LEFT_ for the S form from TRANSFORM. Again, though, this may be do to my own misunderstanding of the preprocessor, but I believed it wasn't working because TRANSFORM called SEQ_FOLD_LEFT_S via a direct ## operation as opposed to using CAT and was concatenating the macro I was using before it was expanded. Correct me if this was an improper assumption and if there wasa fault in my own doing.
(Hmmm. I wonder why I don't have a DEDUCE_S. I'll fix that; it must have been an oversight.) The library typically directly concatenates those arguments. I.e. it assumes that they are already expanded before entry to the macro. There are several reasons for this, mostly related to encapsulation on broken preprocessors (avoiding CAT uses). In any case, what you need is a delay. Instead of #define A() SEQ_TRANSFORM_S(DEDUCE_S(), ...) ...use... #define A() B(DEDUCE_S()) #define B(s) SEQ_TRANSFORM_S(s, ...) This *should* work, but the possibility exists that it won't (on VC, see below).
1) Is there a reason why you're rolling your own COMPL instead of using
BOOST_PP_COMPL? Did it fail to work correctly for some reason?
Yes. If I replace that code with a call to BOOST_PP_COMPL, at least in VC++ 7.1 which is what I was testing it on, I was getting errors. Try it out by just replacing the code with a call to BOOST_PP_COMPL. If there is something I am doing wrong, please tell me.
It isn't you. You've just run into one of the many ways in which VC's preprocessor is broken. It is probably better to leave your workaround in place, because changing the library implementation is likely to break code. VC has a remarkable tendency to do everything out of order--picking up things at later times that should have been done far earlier. This makes that preprocessor *extremely* difficult to work with for anything that relies on expansion order. The pp-lib does do this, of course, but it bends over backward to support VC as well as it does (the pp-lib source is, IMO, more workaround than concept).
2) The pp-lib already has an BOOST_PP_IS_NULLARY. However, it is not a [...]
Perhaps then I should change back to the less-elegant yet possibly more portable way I was doing it which did not use IS_NULLARY or IS_UNARY concepts -- from the 2nd out of the 3 files I posted (binary_literal.hpp), unless you have a better solution?
That might be a good idea. IS_NULLARY and similar ilk are not as stable across preprocessors as other library primitives. They are perfectly stable on non-fundamentally-broken preprocessors, of course. However, even with the workarounds, they aren't totally stable on VC and MW < 9. (It is difficult to get anything that relies on expansion order stable on these two preprocessors particularly.) Regards, Paul Mensonides
participants (3)
-
Matt Calabrese
-
Paul Mensonides
-
Scott Schurr