
Hello all: Is there a way I can check at compile-time and class-scope if a macro has been called and expanded (at least one time) from within a member function? For example: #define X(...) ... // Some macro definition -- the macro parameters could be anything needed to implement is_macro_called. struct is_macro_X_called { ... }; // Some implementation -- this could be a template or something else. So that: struct z { void f() { X(...); // Macro called from within a member function. } // Detect at class-scope and a compile-time that the macro was called. static const bool is_macro_X_called::value; // Evaluates to true. }; Instead: struct z { void f() { // X(...); // Macro not called. } static const bool is_macro_X_called::value; // Evaluates to false. }; I do not know how to program this. However, could for example the macro X() instantiate a template with some special template parameter that can then be inspected at compile-time by a is_macro_called metafunction? Thank you very much. Lorenzo

AMDG Lorenzo Caminiti wrote:
Is there a way I can check at compile-time and class-scope if a macro has been called and expanded (at least one time) from within a member function?
For example:
#define X(...) ... // Some macro definition -- the macro parameters could be anything needed to implement is_macro_called.
struct is_macro_X_called { ... }; // Some implementation -- this could be a template or something else.
So that:
struct z { void f() { X(...); // Macro called from within a member function. }
// Detect at class-scope and a compile-time that the macro was called. static const bool is_macro_X_called::value; // Evaluates to true. };
Instead:
struct z { void f() { // X(...); // Macro not called. }
static const bool is_macro_X_called::value; // Evaluates to false. };
I do not know how to program this. However, could for example the macro X() instantiate a template with some special template parameter that can then be inspected at compile-time by a is_macro_called metafunction?
How do you prevent someone from defining the member function out of line? Even if you could do it, it seems prone to subtle bugs. In Christ, Steven Watanabe

How do you prevent someone from defining the member function out of line? Even if you could do it, it seems prone to subtle bugs.
On Sat, Apr 3, 2010 at 4:44 PM, Steven Watanabe <watanabesj@gmail.com> wrote: - I understand but I would be interested in a solution even if it had limitations. In this specific case, even if the solution was to only work when the member function is defined inline within the class, I would still be interested in it. However, even for inlined member functions, personally I could not come up with any code that I can program within the member function definition scope which has an effect that can be inspected at compile-time at the class definition scope...

AMDG Lorenzo Caminiti wrote:
On Sat, Apr 3, 2010 at 4:44 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
How do you prevent someone from defining the member function out of line? Even if you could do it, it seems prone to subtle bugs.
- I understand but I would be interested in a solution even if it had limitations. In this specific case, even if the solution was to only work when the member function is defined inline within the class, I would still be interested in it.
However, even for inlined member functions, personally I could not come up with any code that I can program within the member function definition scope which has an effect that can be inspected at compile-time at the class definition scope...
Even if it could be done on some compilers, it wouldn't be portable because there's a good chance that the compiler won't try to compile the member functions until it's finished with the class body. Try compiling this class C { void f() { int i = ::test; } static const int i = ::test; }; The first error is likely to be for the class member rather than inside f. In Christ, Steven Watanabe

Why would it matter if the function is compiled before or after the class? The preprocessor will expand the counter value to 1 after PP_UPDATE_COUNTER() at preprocessing time thus regardless of which order the preprocessed code will actually be compiled. However, this approach will not work for me because the #include cannot be programmed within the macro. Therefore, I will have to rely on the macro callers to explicitly indicate if they are calling the macro by using the #include... Is there a way I can do this without using #instructions programmed outside the macro definition? Thanks a lot. Lorenzo On 4/4/10, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Lorenzo Caminiti wrote:
On Sat, Apr 3, 2010 at 4:44 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
How do you prevent someone from defining the member function out of line? Even if you could do it, it seems prone to subtle bugs.
- I understand but I would be interested in a solution even if it had limitations. In this specific case, even if the solution was to only work when the member function is defined inline within the class, I would still be interested in it.
However, even for inlined member functions, personally I could not come up with any code that I can program within the member function definition scope which has an effect that can be inspected at compile-time at the class definition scope...
Even if it could be done on some compilers, it wouldn't be portable because there's a good chance that the compiler won't try to compile the member functions until it's finished with the class body.
Try compiling this class C { void f() { int i = ::test; } static const int i = ::test; };
The first error is likely to be for the class member rather than inside f.
In Christ, Steven Watanabe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Sent from my mobile device

AMDG Lorenzo Caminiti wrote:
Why would it matter if the function is compiled before or after the class? The preprocessor will expand the counter value to 1 after PP_UPDATE_COUNTER() at preprocessing time thus regardless of which order the preprocessed code will actually be compiled.
If the compiler handled the functions as they were defined, there's a semi-portable ADL hack that would work.
However, this approach will not work for me because the #include cannot be programmed within the macro. Therefore, I will have to rely on the macro callers to explicitly indicate if they are calling the macro by using the #include...
Is there a way I can do this without using #instructions programmed outside the macro definition?
No there isn't. In Christ, Steven Watanabe

Lorenzo Caminiti wrote:
Is there a way I can do this without using #instructions programmed outside the macro definition?
As I said, I don't see how to do it in pure C++. But if we go away from pure C++ macro, if you use a code generator / custom preprocessor (modifying boost.wave?), it seems quite feasable, and in a very portable manner. Personnaly I think a code generator would do the trick without difficulties (use boost.spirit to roll it quick!). Eg : struct X { TRACK(NameOfTheMacroToTrack) fn() { NameOfTheMacroToTrack(X,Y,Z)) } TRACKEND(NameOfTheMacroToTrack) }; Seems ok, isn't it? I think with only the first TRACK it is even possible to do it easily. - Be sure to ignore comments thought -. Best regards, Pierre Morcello

Lorenzo Caminiti wrote:
Is there a way I can do this without using #instructions programmed outside the macro definition?
As I said, I don't see how to do it in pure C++. But if we go away from pure C++ macro, if you use a code generator / custom preprocessor (modifying boost.wave?), it seems quite feasable, and in a very portable manner. Personnaly I think a code generator would do the trick without difficulties (use boost.spirit to roll it quick!).
Eg : struct X { TRACK(NameOfTheMacroToTrack)
fn() { NameOfTheMacroToTrack(X,Y,Z)) }
TRACKEND(NameOfTheMacroToTrack) };
Seems ok, isn't it? I think with only the first TRACK it is even possible to do it easily. - Be sure to ignore comments thought -.
FWIW, Wave allows to add your own #pragma directives easily (as long as they follow the format #pragma wave option[(values)] where [...] means 'optional'. See libs/wave/samples/preprocess_pragma_output for an (unrelated) example showing how to define your own #pragma. Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com

De: Lorenzo Caminiti <lorcaminiti@gmail.com> Objet: [boost] [mpl] is_macro_called À: boost@lists.boost.org Date: Samedi 3 avril 2010, 13h25 Hello all:
Is there a way I can check at compile-time and class-scope if a macro has been called and expanded (at least one time) from within a member function?
For example:
#define X(...) ... // Some macro definition -- the macro parameters could be anything needed to implement is_macro_called.
struct is_macro_X_called { ... }; // Some implementation -- this could be a template or something else.
So that:
struct z { void f() { X(...); // Macro called from within a member function. }
// Detect at class-scope and a compile-time that the macro was called. static const bool is_macro_X_called::value; // Evaluates to true. };
Instead:
struct z { void f() { // X(...); // Macro not called. }
static const bool is_macro_X_called::value; // Evaluates to false. };
I do not know how to program this. However, could for example the macro X() instantiate a template with some special template parameter that can then be inspected at compile-time by a is_macro_called metafunction?
Thank you very much. Lorenzo
Hello, I don't know how to do that compile time without macros. I wonder if it is possible with mpl. Anyway, maybe the following is enough for your need? [code] #include <iostream> #include <boost/preprocessor/slot/counter.hpp> #include <boost/type_traits/is_same.hpp> #define MACRO_Example(X) \ std::cout<<X<<std::endl; struct X { // at the beginning of the class. template <int Y> class MacroWasUsedHelper{}; typedef MacroWasUsedHelper<BOOST_PP_COUNTER> Before; void writeMe() { // if you comment the 2 next lines, the counter will be 0. MACRO_Example("Me"); #include BOOST_PP_UPDATE_COUNTER() } // at the end of the class declaration typedef MacroWasUsedHelper<BOOST_PP_COUNTER> After; // now you just have to compare the 2 types "Before" and "After" as you wish. the following will be 'boost::true_type' only if it was not used. typedef boost::is_same<Before, After>::type undetected; }; [/code] The elements like "typedef MacroWasUsedHelper<BOOST_PP_COUNTER> After;" can be put into a macro easily. Only the "#include BOOST_PP_UPDATE_COUNTER()" seems necessary to remain (as long as we use pure C++). Here you got compile time evaluation. It was also possible to use directly functions returning constant (BOOST_PP_COUNTER) instead of template programming. Hope this helps, Best Regards, Pierre Morcello
participants (4)
-
Hartmut Kaiser
-
Lorenzo Caminiti
-
Pierre Morcello
-
Steven Watanabe