I'm trying to do something like that:
#define VERIFY_EXPECTATIONS \
BOOST_MPL_ASSERT((expectation1)); \
BOOST_MPL_ASSERT((expectation2)); \
BOOST_MPL_ASSERT((expectation3))
and when writing VERIFY_EXPECTATIONS; in line, say 42, I get an error about a conflicting declaration of mpl_assertion_in_line_42.
I understand what is happening (BOOST_MPL_ASSERT uses an identifier that depends on the line where the macro is invoked) but my question is: is there a known workaround to do this kind of things?
Edit:
More precisely, the expectations look like that:
#define TEST_SOME_SET_OF_PREDICATES(Arg) \
BOOST_MPL_ASSERT ((some_predicate<Arg>)); \
BOOST_MPL_ASSERT_NOT((some_other_predicate<Arg>))
TEST_SOME_SET_OF_PREDICATES(some_type);
TEST_SOME_SET_OF_PREDICATES(some_other_type);
I have implemented the predicates and I want to test them with several types.
Note:
I'm not very interested in the following:
template <typename Arg>
struct compound_predicate : boost::mpl::and_<
some_predicate<Arg>,
boost::mpl::not_<some_other_predicate<Arg> >
> {};
BOOST_MPL_ASSERT((compound_predicate<some_type>));
BOOST_MPL_ASSERT((compound_predicate<some_other_type>));
because when an assertion fails, we don't know which of the expectations was wrong.
The solution suggested by Praetorian would be the following:
template <typename Arg>
struct expectations {
BOOST_MPL_ASSERT ((some_predicate<Arg>));
BOOST_MPL_ASSERT_NOT((some_other_predicate<Arg>));
};
and then instantiate expectations with some_type and some_other_type. I would have to implement a macro that declares an object of type expectations<Arg> with a different identifier at each call. It looks a little bit like reimplementing (some part of) static assertions.
Any other ideas?
Related
I am trying to define a macro that behaves differently when used in a function context vs a class body or namespace. The purpose of this is to selectively include BOOST_LOG_NAMED_SCOPE (or achieve equivalent behavior) in the LOG_CONTEXT macro referenced here.
I have tried two approaches:
Using BOOST_PP_IF along with a preprocessor function to test whether e.g. __func__ is non-empty.
The output of g++ -E on a basic source file still contains the literal text __func__ in both global and function scope so that probably rules out any approach targeting the preprocessing phase.
Using something like sizeof(__func__) to select a specialized template that implements behavior similar to BOOST_LOG_NAMED_SCOPE. I can re-use the boost::log::attributes::named_scope::sentry object from boost log, but I'm stuck trying to figure out how to instantiate it conditionally in a function context, or at least in a way that works everywhere. The following construction seems to work fine in class definitions and functions, but fails with a "multiple definition" error when linking together multiple translation units that include a header with a LOG_CONTEXT at global or namespace scope:
#include <boost/log/attributes/named_scope.hpp>
#include <type_traits>
namespace logging {
namespace attrs = boost::log::attributes;
namespace detail {
// Default no-op on construction when not in a function.
template<typename ScopeTraits, bool InFunction>
class named_scope_helper
{};
// Specialization when in a function.
template<typename ScopeTraits>
class named_scope_helper<ScopeTraits, true> :
public attrs::named_scope::sentry
{
public:
named_scope_helper() BOOST_NOEXCEPT
: sentry(
ScopeTraits::scope_name(),
ScopeTraits::filename(),
ScopeTraits::lineno() )
{}
};
template<size_t N>
class not_1 : public std::true_type
{};
template<>
class not_1<1> : public std::false_type
{};
#define LOGGING_LOG_IN_FUNCTION \
::logging::detail::not_1<sizeof(__func__)>::value
} // namespace detail
} // namespace logging
// scope_name_t/filename_t are required since attrs::named_scope::sentry
// requires string literals.
#define LOG_CONTEXT( name_ ) \
struct __logging_log_scope_traits__ \
{ \
using scope_name_t = const char (&)[sizeof(name_)]; \
static scope_name_t scope_name() \
{ return name_; } \
using filename_t = const char (&)[sizeof(__FILE__)]; \
static filename_t filename() \
{ return __FILE__; } \
static size_t lineno() \
{ return __LINE__; } \
}; \
::logging::detail::named_scope_helper< \
__logging_log_scope_traits__, LOGGING_LOG_IN_FUNCTION> \
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_log_named_scope_sentry_);
My normal workaround for this would be to use static in the declaration of the _log_named_scope_sentry_, but that defeats the purpose.
I could add another macro that is strictly for non-execution contexts, but wanted to investigate this approach first since it would be an interesting trick to have. How can I proceed on one of the two approaches I've started above, or is there another option I haven't considered?
A general solution would be preferred but I'm only really concerned with GCC and Clang.
The context of my situation is pretty hard to explain exhaustively here but : I am using an external toolset (lib, bins, etc.) which generates some c++ code from a proprietary IDL file. For a given type T, it generates a T_Result class. The generated code is then integrated to my project.
Now, I am trying to generate a type based on the type of a template parameter.
#define GENTYPE(x) x ## _Result
// class coming from generated includes. Copied here for clarity.
class int_Result
{};
template < class T >
class Connector
{
GENTYPE(T) _result;
public:
};
int main()
{
Connector<int> t;
/* ... */
}
Of course, this does not work because the c-preprocessor uses the T value as it, so the GENTYPE macro is expanded inside the Connector class as T_Result instead of the wanted int_Result class.
One could use #define to produce the whole class but then very difficult to maintain, debug, etc.
Does anyone knows a trick to achieve this goal ?
Instead of a macro generating Connector, we use a macro to generate a traits class that maps T to T_result. Then Connector just uses that traits class.
template<class T>struct result_type;
#define MRT(T) \
template<>struct result_type<T>{ \
using type = GENTYPE(T); \
}
template<class T>using result_t=typename result_type<T>::type;
now simply do a MRT(int); to make result_t<int> be to int_result. The macro must be used before the first use of result_t<int>. Failure to do MRT(int) makes result_t<int> an error.
This assumes C++11 support: it is 2015.
In Connector just do result_t<T> _result;
Use of MRT is optional, as a strait
template<>struct result_type<int>{ using type=GENTYPE(int); };
or even
template<>struct result_type<int>{ using type=int_result; };
isn't all that verbose, and reduces the number of layers of macros. It does violate DRY (don't repeat yourself) however.
The following works just-fine in MSVC2008 and MSVC2010:
class Foo {
public:
static void FuncA(void) {
FuncB(); // "FuncB()" NOT DECLARED YET? WORKS, MSVC2008
}
static void FuncB(void);
};
Yes, this is kinda weird: FuncA() calls FuncB(), even though (at that point) FuncB() is not-yet-declared. However, MSVC2008 and MSVC2010 thinks this is fine.
Apparently, gcc doesn't think this is fine -- FuncB was not declared in this scope.
ISSUE: I have a bunch of these, and it would be a "pain" to declare them, and later define them. Further, it would be hard to "order" them properly so each only calls functions after those were declared. But, I'm guessing I need to declare-first-then-define-later?
Are the rules different for whether these functions are template-or-not, or defined within a template-class or not?
Specifically, I've noticed Microsoft is very "late-compiling" where it accepts tons of inter-coupled code, and LATER resolves (at compile, when the template-parameterization is triggered), while gcc seems to want to compile now when it "sees" the code (an initial pass for correctness, and again during parameterization/invocation).
(This problem shows up as we port our Microsoft code to Linux/gcc.)
===UPDATE===
The following are "alternate" scenarios that we have (in this code-porting effort), and would your answer change based on any of these?
// Alternate-Scenario-B
class Foo2 {
public:
template<typename SOME_TYPE>
static void FuncA(const SOME_TYPE& some_type) {
FuncB(some_type); // "FuncB()" NOT DECLARED YET? WORKS, MSVC2008
}
template<typename SOME_TYPE>
static void FuncB(const SOME_TYPE& some_type);
};
...and:
// Alternate-Scenario-C
template<typename SOME_TYPE>
class Foo3 {
public:
static void FuncA(const SOME_TYPE& some_type) {
FuncB(some_type); // "FuncB()" NOT DECLARED YET? WORKS, MSVC2008
}
static void FuncB(const SOME_TYPE& some_type);
};
===UPDATE+2===
Thanks for the comments, where consensus seems that this is valid C++ code, and should work (as #Adam suggested, a function "defined-inline" should behave as if it were defined after the class, and should be able to call functions defined in the class interface after that inline definition).
MORE INFORMATION:
Yes, I really have this compile error from the first example in the FuncA() inline implementation:
'FuncB' is not a member of 'Foo'
...using:
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
(Recall that this works on MSVC2008/MSVC2010).
I realize now that my code-example (above) is insufficient (the above example does not show this error on gcc), here are some more details:
Foo has a base-class (I don't think that should matter)
Foo defines an internal enum which is passed through these funcs (I don't think this matters)
these functions are "expanded" through a macro (I think significant -- see below)
there are fifty-six (56) of these functions (I think significant -- see below)
A more complete code example would be (and I am not proud of this):
#define FOO_FUNCS(CLASS_NAME,CLASS_ENUM) \
static void FuncA(CLASS_ENUM value_enum) { \
FuncB(value_enum); /*PROBLEM*/ \
} \
static void FuncB(CLASS_ENUM value_enum) { \
FuncC(value_enum); \
} \
/*...THERE ARE 56 FUNCS IN THIS MACRO, THREE LINES EACH...*/
class Foo : public FooParent {
public:
enum FooEnum { FOO_ONE, FOO_TWO };
FOO_FUNCS(Foo,FooEnum) // EXPAND THE 56 FUNCS
};
CODE INTENT: The FooParent base class has implementation that is intended to be "shared" by (many) derived classes. The derived classes define their own enum values. Functions that used these enum values were implemented through a macro (because the FooParent is not a template<>, and cannot rely upon the derived-enum).
Curious behavior:
If the FooA(){FooB();} nesting references a function defined "later" by only a "few-lines", then gcc compiles fine. However, if the yet-to-be-declared function is much later, like Foo2(){Foo53();}, then gcc concludes that Foo53() is not a member of the class (but it is).
Here's what I think is going on:
There seems to be an issue with lots-of-code (for 56 functions) that are physically on "one-line". If I take these functions out of the macro, AND if I remove \ escape-line-endings, then gcc compiles fine.
Thus, I think the (code-porting) answer is:
don't use a preprocessor-macro
make a FooParentBase<> template class derived from FooParent, from which we derive Foo, which requires the typename Foo::enum as a template-parameter
I'm fine with these changes (I didn't like the macro), but I find it weird that gcc seems to have an issue here.
Are there other suggestions for how to fix this? (Is the above re-factoring what you would do?)
All three of your scenarios are correct and compile with both g++ and clang.
Your code looks perfectly legal to me. Inline definitions within a class definition are supposed to be treated equivalent to declarations with an inline definition immediately following the class definition (by which time the declaration of FuncB() would be available).
My version of GCC accepts this code as valid (all three examples you post, assuming I provide trivial implementations of each FuncB(), of course).
~$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
...
I believe more information is needed here. Perhaps post your version of GCC and the specific error message you're seeing.
========REPLY TO LATER UPDATE=======
I've tried your latest example with 70 functions in the macro, and it's still working for me in gcc 4.6.3. Here is the test I tried (with the macro shortened in the obvious way):
#include <iostream>
using std::cout;
struct FooParent {
static void Func71( int ) {
cout << "Called\n";
}
};
#define FOO_FUNCS(CLASS_NAME,CLASS_ENUM) \
static void Func1(CLASS_ENUM value_enum) { \
Func2(value_enum); /PROBLEM/ \
} \
static void Func2(CLASS_ENUM value_enum) { \
Func3(value_enum); \
} \
/* Functions Func3...Func69 snipped */ \
static void Func70(CLASS_ENUM value_enum) { \
Func71(value_enum); \
} \
/...THERE ARE 70 FUNCS IN THIS MACRO, THREE LINES EACH.../
class Foo : public FooParent {
public:
enum FooEnum { FOO_ONE, FOO_TWO };
FOO_FUNCS(Foo,FooEnum) // EXPAND THE 70 FUNCS
};
int main() {
Foo::Func1(Foo::FOO_ONE);
}
I have
namespace src {
struct src_bar;
void src_baz();
template<class T> class src_qux;
}
which I'd like to reference as
namespace dst {
struct dst_bar;
void dst_baz();
template<class T> class dst_qux;
}
meaning that I'd like to "rename" or "alias" or "relabel" names from src.
For dst_bar one can of course use namespace dst { typedef src_bar dst_bar; }. Is there some (non-macro) equivalent allowing me to rename src::src_baz as dst::dst_baz and src::src_qux as dst::dst_qux?
Unless I'm mistaken, neither a using statement nor a namespace alias can accomplish the other two. Writing templated forwarding functions for dst_baz() is a possibility but requires knowledge of the arity of src_baz. Template typedefs could have dst_qux<T>::type be src_qux<T> but the indirection adds verbosity.
FWIW, my use case is taking C names like somepackage_someportion_somefuncA and providing a namespaced-friendly version somepackage::someportion::somefuncA so that other folks can employ using somepackage::someportion for brevity.
For functions you will have to manually forward the requests. For non-template types you can just typedef. For template types, y can use the new using feature of c++11 To create a typedef-style alias for a template, if your compiler supports it, or else you are basically out of luck.
No, you cannot "rename" something so that it no longer uses its original name.
However, you can get the same effect via trickery.
First, import the header for the defines you want to corral inside a namespace block:
namespace foo {
#include "src_stuff.h"
}
Now you have foo::src::src_bar and friends.
Then, use typedef liberally:
namespace bar {
typedef foo::src::src_bar dst_bar;
}
Voila, you've got a bar::dst_bar which is the same as src::src_bar would have been. If you don't care about the definitions remaining available under the old names in addition, skip the first step and just make typedefs for convenience. That's what they're for, after all.
If usage of macros is an acceptable option for you then here is one solution:
// declare this macro in some common file
#define CREATE(SCOPE) \
namespace SCOPE { \
struct SCOPE## _bar; \
void SCOPE## _baz(); \
template<class T> class SCOPE## _qux; \
}
Usage:
CREATE(src);
CREATE(dst);
I'm trying to write a macro to make a specific usage of callbacks in C++ easier. All my callbacks are member functions and will take this as first argument and a second one whose type inherits from a common base class.
The usual way to go is:
register_callback(boost::bind(&my_class::member_function, this, _1));
I'd love to write:
register_callback(HANDLER(member_function));
Note that it will always be used within the same class.
Even if typeof is considered as a bad practice, it sounds like a pretty solution to the lack of __class__ macro to get the current class name.
The following code works:
typedef typeof(*this) CLASS;
boost::bind(& CLASS :: member_function, this, _1)(my_argument);
but I can't use this code in a macro which will be given as argument to register_callback.
I've tried:
#define HANDLER(FUN) \
boost::bind(& typeof(*this) :: member_function, this, _1);
which doesn't work for reasons I don't understand. Quoting GCC documentation:
A typeof-construct can be used anywhere a typedef name could be used.
My compiler is GCC 4.4, and even if I'd prefer something standard, GCC-specific solutions are accepted.
Your problem might be that typeof yields my_class&. It appears to work with boost::remove_reference:
#include <boost/bind.hpp>
#include <boost/type_traits.hpp>
#include <iostream>
struct X
{
void foo(int i) { std::cout << i << '\n'; }
void bar() {boost::bind(&boost::remove_reference<typeof(*this)>::type::foo, this, _1)(10); }
};
int main()
{
X x;
x.bar();
}
It might be more portable to use BOOST_TYPEOF, and in C++0x decltype