A question to preprocessor gurus

Hi all, The MS preprocessor has the __COUNTER__ extension that expands to the next integer every time when used. Can something like this be achieved in a portable manner, maybe with the help of Boost.Preprocessor library? Thanks, Arkadiy

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Arkadiy Vertleyb
The MS preprocessor has the __COUNTER__ extension that expands to the next integer every time when used. Can something like this be achieved in a portable manner, maybe with the help of Boost.Preprocessor library?
The best you can do in standard C++ is __LINE__. If you need varying numbers all in the same place (i.e. the same header), you can manually keep track of a counter. It is also possible to hijack the #include mechanism to provide a different number each time a file is included or something like that. In any case, the ways of doing it are a lot more heavyweight than __COUNTER__, but a lot more standard too. Regards, Paul Mensonides

In fact I belive that __COUNTER__ was introduced because the solution with __LINE__ did not worked when you compile with Edit & Continue ON. In that case the __LINE__ was in fact a variable. Jan "Paul Mensonides" <pmenso57@comcast.net> wrote in message news:200404200944.i3K9iuO1023897@milliways.osl.iu.edu...
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Arkadiy Vertleyb
The MS preprocessor has the __COUNTER__ extension that expands to the next integer every time when used. Can something like this be achieved in a portable manner, maybe with the help of Boost.Preprocessor library?
The best you can do in standard C++ is __LINE__. If you need varying numbers all in the same place (i.e. the same header), you can manually keep track of a counter. It is also possible to hijack the #include mechanism to provide a different number each time a file is included or something like that. In any case, the ways of doing it are a lot more heavyweight than __COUNTER__, but a lot more standard too.
Regards, Paul Mensonides
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

"Paul Mensonides" <pmenso57@comcast.net> wrote
The MS preprocessor has the __COUNTER__ extension that expands to the next integer every time when used. Can something like this be achieved in a portable manner, maybe with the help of Boost.Preprocessor library?
The best you can do in standard C++ is __LINE__. If you need varying numbers all in the same place (i.e. the same header), you can manually keep track of a counter. It is also possible to hijack the #include mechanism to provide a different number each time a file is included or something like that. In any case, the ways of doing it are a lot more heavyweight than __COUNTER__, but a lot more standard too.
Actually I don't need to have many things on the same line, but I do want to handle inclusions from several headers... Maybe it's somehow possible to generate a unique number from the header file name? Or use this #include mechanism you mentioned? Thanks, Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote: [snip __COUNTER__ macro question]
Actually I don't need to have many things on the same line, but I do want to handle inclusions from several headers... Maybe it's somehow possible to generate a unique number from the header file name? Or use this #include mechanism you mentioned?
__FILE__/__LINE__ combination is unique across multile TUs. But it is AFAIK impossible to translate it into numeric value (preprocessor sees string as one token) and const char* cannot be used as template parameter. Though you can name headers as hdr1.hpp, hdr2.hpp, ... and extract the unique header number via __FILE__[sizeof(__FILE__) - 6] hack to get its ASCII code. /Pavel

[mailto:boost-bounces@lists.boost.org] On Behalf Of Arkadiy Vertleyb
Actually I don't need to have many things on the same line, but I do want to handle inclusions from several headers... Maybe it's somehow possible to generate a unique number from the header file name? Or use this #include mechanism you mentioned?
It depends on what exactly you need the value for. Boost.Preprocessor contains a mechanism that is capable of storing/setting a value (technically, more than one): #define BOOST_PP_VALUE 1 #include BOOST_PP_ASSIGN_SLOT(1) BOOST_PP_SLOT(1) // 1 #define BOOST_PP_VALUE BOOST_PP_SLOT(1) + 1 #include BOOST_PP_ASSIGN_SLOT(1) BOOST_PP_SLOT(1) // 2 // etc. Doing the incrementation manually is tedious, so you'd want to make a separate file just to do that (and I'd recommend also defining a macro that expands to that filename just so it is really obvious that you're using the #include mechanism in an abnormal way): # // detail/counter.hpp # ifndef DETAIL_COUNTER_HPP # define DETAIL_COUNTER_HPP # # include <boost/preprocessor/slot/slot.hpp> # # define BOOST_PP_VALUE 1 # include BOOST_PP_ASSIGN_SLOT(1) # # else # # define BOOST_PP_VALUE BOOST_PP_SLOT(1) + 1 # include BOOST_PP_ASSIGN_SLOT(1) # # endif # // counter.hpp # ifndef COUNTER_HPP # define COUNTER_HPP # # define COUNTER BOOST_PP_SLOT(1) # define NEXT() "detail/update.hpp" # # endif And then use it like this: #include "counter.hpp" #include NEXT() COUNTER // 1 #include NEXT() COUNTER // 2 #include NEXT() COUNTER // 3 // etc. It is better, IMO, to do the update immediately before using the value rather than immediately after because that localizes mistakes. If, on the other hand, you don't need to use the resulting value as a macro argument (which is unlikely), you can encapsulate the above process to only a single header inclusion: #include COUNTER() // 1 #include COUNTER() // 2 #include COUNTER() // 3 // etc. Do that help? Regards, Paul Mensonides

Hi Paul, "Paul Mensonides" <pmenso57@comcast.net> wrote
And then use it like this:
#include "counter.hpp"
#include NEXT() COUNTER // 1
#include NEXT() COUNTER // 2
#include NEXT() COUNTER // 3
// etc.
This solution almost works for me except I hoped to completely hide the unique number genereation mechanism behind a macro, so that my users are not aware of this, like: REGISTER(...) // 1 is used REGISTER(...) // 2 is used etc. As I understand I can't use #include inside a macro, so looks like I am out of luck here... Regards, Arkadiy
participants (4)
-
Arkadiy Vertleyb
-
Jan Bares
-
Paul Mensonides
-
Pavel Vozenilek