Best C++ macro for creating a new scope - c++

I have a macro
#define SCOPE_GUARD(GUARD, NAME, ...) \
for(bool __once = true; __once; /* nothing */) \
for(GUARD NAME (__VA_ARGS__); __once; __once = false)
using something like this:
SCOPE_GUARD(std::unique_lock, lock, (some_mutex))
do_some();
or
SCOPE_GUARD(std::unique_ptr<char>, buff, (new char[BUFFER_SIZE])) {
*buff.get() = 0;
GetSomeDescription(buff.get(), BUFFER_SIZE);
Log(buff.get);
}
Are there similar(better) implementation of the macro, which is optimized by multiple compilers correctly.
P.S. Macro should be one, without finally macro like BOOST_SCOPE_EXIT_END (can redefine by if (...)).
EDIT
Simple scoupe in using codestyle is very huge.
{
std::unique_lock lock (some_mutex);
do_some();
}
but I want using some like this
SCOPE_GUARD(std::unique_lock, lock, (some_mutex)) do_some();

You can do an awful lot with C++ templates and lambda expressions. It might be worthwhile to explore using them. For example, instead of using the SCOPE_GUARD macro, you could do something like this:
template <typename G, typename F, typename... A>
inline auto scope_guard(G&&, F&& f, A&&... args)
-> decltype(std::forward<F>(f)(std::forward<A>(args)...))
{
return std::forward<F>(f)(std::forward<A>(args)...);
}
scope_guard(std::unique_lock<std::mutex>(m), do_something);
scope_guard(std::unique_lock<std::mutex>(m), [&]() {
do_something1();
do_something2();
do_something3();
});
If I were using straight macros, mine would probably look something like this:
#define UNWRAP(...) __VA_ARGS__
#define SCOPE_GUARD(X, Y) do { X; UNWRAP Y; } while (0)
SCOPE_GUARD(std::unique_lock<std::mutex> lock(m), (do_something()));
SCOPE_GUARD(std::unique_lock<std::mutex> lock(m), (
do_something1();
do_something2();
do_something3();
));

I think this is what you're looking for:
#define PROTECTED_BY(m) for(std::unique_lock<decltype(m)> _lock_(m) ; _lock_ ; _lock_.unlock())
complete use case:
#include <iostream>
#include <mutex>
#define PROTECTED_BY(m) for(std::unique_lock<decltype(m)> _lock_(m) ; _lock_ ; _lock_.unlock())
using namespace std;
int main()
{
mutex m;
PROTECTED_BY(m)
{
cout << "Hello World" << endl;
}
return 0;
}

Related

How to use __VA_ARGS__ in C or CPP [duplicate]

I hava a macro to call static function for each args.
For example:
#define FOO(X) X::do();
#define FOO_1(X,Y) X::do(); Y::do();
My question is that I need to use foo with variable number of arguments, is it possible to use __VA_ARGS__ ?
Like the line below:
#define FOO(...) __VA_ARGS__::do() ?
Thanks
Macro expansion does not work like argument pack expansion with variadic templates. What you have will expand to:
X,Y::do();
And not to
X::do(); Y::do();
As you hoped. But in C++11 you could use variadic templates. For instance, you could do what you want this way:
#include <iostream>
struct X { static void foo() { std::cout << "X::foo()" << std::endl; }; };
struct Y { static void foo() { std::cout << "Y::foo()" << std::endl; }; };
struct Z { static void foo() { std::cout << "Z::foo()" << std::endl; }; };
int main()
{
do_foo<X, Y, Z>();
}
All you need is this (relatively simple) machinery:
namespace detail
{
template<typename... Ts>
struct do_foo;
template<typename T, typename... Ts>
struct do_foo<T, Ts...>
{
static void call()
{
T::foo();
do_foo<Ts...>::call();
}
};
template<typename T>
struct do_foo<T>
{
static void call()
{
T::foo();
}
};
}
template<typename... Ts>
void do_foo()
{
detail::do_foo<Ts...>::call();
}
Here is a live example.
You cannot do this directly, __VA_ARGS__ is always treated as a single unit consisting of all the parameters separated by a comma. The preprocessor provides no built-in way to find the number of parameters, to separate them or to loop over them.
This answer to a similar question shows the basic solution using the preprocessor: Find out how many items there are in your argument list and pass it on to a macro that does take this exact amount of parameters.
I’d recommend not to do this but instead use Andy Prowls C++11 solution or even restructure your code so you don’t need this at all.
Actually you can partially workaround this.
You can directly and freely extract every member of neither __VA_ARGS__ nor variadic templates of C++11. But you can have the very first element. For example let's say we have a macro named OUT(...) and we want to produce std::cout << A << B << C ... where A, B, C are the variadic arguments of macro. Try this:
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define BAR(...) GET_3_OF(__VA_ARGS__)
int main()
{
std::cout << BAR(1,2,3,4,5);
return 0;
}
This is of course not the solution you are after. But you can augment the number of GET_N_OF to do what you want. Note that SEPERATOR is << so that we MACRO can write 1 << 2 << 3 and so on.
Now, we have a problem in this code. Please change BAR(1,2,3,4,5) with BAR(1) You will see that it is giving an error. This is because it was expecting 3 arguments, although it is not problem to have more arguments (because it is variadic) we are having extra SEPERATOR. So in order to solve this problem instead of using BAR(...) use GET_N_OF(...) (since you know the number of arguments):
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define GET_4_OF(element1, ...) element1 SEPERATOR GET_3_OF(__VA_ARGS__)
#define GET_5_OF(element1, ...) element1 SEPERATOR GET_4_OF(__VA_ARGS__)
int main()
{
std::cout << GET_5_OF(1,2,3,4,5);
std::cout << GET_1_OF(1);
return 0;
}
Please note that if you do not know what you are doing do not use MACROs at all! My response was just to share fun MACRO code that may be beneficial for you. I always discourage the usage of MACROs until they are remarkably necessary.

Macro to make std::pair with fixed types

I'm trying to do something like this:
#define SOME_PAIR(x, y) std::make_pair<bool, std::string>(x, y)
So that what the programmer has to write is simply:
return SOME_PAIR(true, "Amazing");
But it looks like i'm doing something wrong, as 'no instance of function template "std::make_pair" matches the argument list'.
What can i do to make this (or something similar to this) work?
Compiler: VC110
IDE: VS2012
OS: Win7x64
EDIT: The following code(thanks to jxh) makes it work perfectly:
#define SOME_PAIR(x, y) std::make_pair(bool(x), std::string(y))
And thus my lamda function ends up being really neat:
boot.init("log", [&](){
return INIT_PAIR(log.loaded, "Could not open log config file");
});
You can "cast" the arguments and allow type deduction to instantiate the right template function:
#define SOME_PAIR(x, y) std::make_pair(bool(x), std::string(y))
Did you forget
#include <utility>
in the file which invokes the macro? The compilation is failing at the point where the macro is expanded.
The following worked for me.
g++ -std=c+0x -Wall -Wextra pair.cpp
#include <iostream>
#include <string>
#include <utility>
#define PAIR(x, y) std::make_pair<bool, std::string>(x, y)
int main(int, char* []) {
auto p = PAIR(true, "abc");
std::cout << p.first << " " << p.second << std::endl;
return 0;
}
Why you don't use templates for it? It will work for most types (not just bool and string). Something like:
#include <iostream>
template<class T1, class T2>
inline std::pair<T1, T2> SOME_PAIR(T1 t1, T2 t2) {
return std::make_pair(t1, t2);
}
int main() {
std::pair<bool, std::string> p = SOME_PAIR(true,"hello");
return 0;
}

How to extract __VA_ARGS__?

I hava a macro to call static function for each args.
For example:
#define FOO(X) X::do();
#define FOO_1(X,Y) X::do(); Y::do();
My question is that I need to use foo with variable number of arguments, is it possible to use __VA_ARGS__ ?
Like the line below:
#define FOO(...) __VA_ARGS__::do() ?
Thanks
Macro expansion does not work like argument pack expansion with variadic templates. What you have will expand to:
X,Y::do();
And not to
X::do(); Y::do();
As you hoped. But in C++11 you could use variadic templates. For instance, you could do what you want this way:
#include <iostream>
struct X { static void foo() { std::cout << "X::foo()" << std::endl; }; };
struct Y { static void foo() { std::cout << "Y::foo()" << std::endl; }; };
struct Z { static void foo() { std::cout << "Z::foo()" << std::endl; }; };
int main()
{
do_foo<X, Y, Z>();
}
All you need is this (relatively simple) machinery:
namespace detail
{
template<typename... Ts>
struct do_foo;
template<typename T, typename... Ts>
struct do_foo<T, Ts...>
{
static void call()
{
T::foo();
do_foo<Ts...>::call();
}
};
template<typename T>
struct do_foo<T>
{
static void call()
{
T::foo();
}
};
}
template<typename... Ts>
void do_foo()
{
detail::do_foo<Ts...>::call();
}
Here is a live example.
You cannot do this directly, __VA_ARGS__ is always treated as a single unit consisting of all the parameters separated by a comma. The preprocessor provides no built-in way to find the number of parameters, to separate them or to loop over them.
This answer to a similar question shows the basic solution using the preprocessor: Find out how many items there are in your argument list and pass it on to a macro that does take this exact amount of parameters.
I’d recommend not to do this but instead use Andy Prowls C++11 solution or even restructure your code so you don’t need this at all.
Actually you can partially workaround this.
You can directly and freely extract every member of neither __VA_ARGS__ nor variadic templates of C++11. But you can have the very first element. For example let's say we have a macro named OUT(...) and we want to produce std::cout << A << B << C ... where A, B, C are the variadic arguments of macro. Try this:
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define BAR(...) GET_3_OF(__VA_ARGS__)
int main()
{
std::cout << BAR(1,2,3,4,5);
return 0;
}
This is of course not the solution you are after. But you can augment the number of GET_N_OF to do what you want. Note that SEPERATOR is << so that we MACRO can write 1 << 2 << 3 and so on.
Now, we have a problem in this code. Please change BAR(1,2,3,4,5) with BAR(1) You will see that it is giving an error. This is because it was expecting 3 arguments, although it is not problem to have more arguments (because it is variadic) we are having extra SEPERATOR. So in order to solve this problem instead of using BAR(...) use GET_N_OF(...) (since you know the number of arguments):
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define GET_4_OF(element1, ...) element1 SEPERATOR GET_3_OF(__VA_ARGS__)
#define GET_5_OF(element1, ...) element1 SEPERATOR GET_4_OF(__VA_ARGS__)
int main()
{
std::cout << GET_5_OF(1,2,3,4,5);
std::cout << GET_1_OF(1);
return 0;
}
Please note that if you do not know what you are doing do not use MACROs at all! My response was just to share fun MACRO code that may be beneficial for you. I always discourage the usage of MACROs until they are remarkably necessary.

STL function / Boost function typedef errors

I'm trying to figure out how I can switch between boost functions and c++11 functions depending on what the platform I'm compiling it on has available. I know that c++ doesn't have template aliasing (pre-c++11) so I wrote the following, but I can't understand the error message or why it's not working:
#define FUNCTION_Boost
#if defined(FUNCTION_Boost)
#include <boost/function.hpp>
#elif defined(FUNCTION_STL)
#include <functional>
#endif
template<typename Res, typename... ArgTypes>
struct function {
#if defined(FUNCTION_Boost)
typedef boost::function<Res(ArgTypes...)> type;
#elif defined(FUNCTION_STL)
typedef std::function<Res(ArgTypes...)> type;
#endif
};
// In instantiation of ‘function<void()>’:
// error: function returning a function
void foo(function<void ()>::type f) {
f();
}
// this works fine
void bar(boost::function<void ()> f) {
f();
}
no need to define one more function... everything could be done using using ;)
#define USE_BOOST_FUNCTION
#ifdef USE_BOOST_FUNCTION
# include <boost/function.hpp>
# define FUNCTION_NS boost
# else
# include <functional>
# define FUNCTION_NS std
# endif
#include <iostream>
namespace test {
using FUNCTION_NS::function;
}
int main()
{
test::function<void()> f = [](){ std::cout << __PRETTY_FUNCTION__ << std::endl; };
f();
return 0;
}
I have the impression that this code does not do what you think it does:
typename function<void ()>::type
binds "void ()" as Res just creating a function that returns a function.
what about:
...
void foo(typename function<void >::type f) {
f();
}
...
?
You can get something similar to the aliasing you are trying to get with boost::type_traits and boost::type_traits::function_traits specially. That said, I suspect that if you want a simple and portable solution, then the easiest to do is to use boost and wait for better times with C++ compilers and STL support for C++11.

Can you use assert to test type defintions in C++?

Can I use assert to enforce type definitions. Suppose there is a variable, double d, how can you use assert to assert that d is a double? If assert is not applicable (which I am betting isn't), is there another option? I am specifically looking to test for implicit type casting during debugging, while benefiting from the functionality of assert and #define NDEBUG.
P.S
Obviously I would want to use this for any type definition, just using double as an example here. The solution should be cross platform compatible and be compatible with C++03.
I like to add error checking to my class setters. For example, suppose there is a class, MyClass, with a private member variable, x:
void MyClass::setX(double input)
{
// assert x is double
x = input;
}
It's really a compile time check, so you should use static asserts for this.
Here is an example using boost's static asserts and type traits.
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
template<typename T>
void some_func() {
BOOST_STATIC_ASSERT( (boost::is_same<double, T>::value) );
}
TEST(type_check) {
some_func<double>();
}
I assume you mean in terms of a template anyway.
You can use the == operator defined in the type_info class to test for a specific type definition.
#include <assert.h>
#include <iostream>
#include <typeinfo>
int main ()
{
double a = 0;
std::cout << typeid(a).name() << std::endl;
assert(typeid(a)==typeid(double));
assert(typeid(a)==typeid(int)); // FAIL
}
Or borrowing from another SO answer using templates and try/catch:
#include <assert.h>
#include <iostream>
#include <typeinfo>
template <typename X, typename A>
inline void Assert(A assertion)
{
if( !assertion ) throw X();
}
#ifdef NDEBUG
const bool CHECK_ASSERT = false;
#else
const bool CHECK_ASSERT = true;
#endif
struct Wrong { };
int main ()
{
double a = 0;
std::cout << typeid(a).name() << std::endl;
assert(typeid(a)==typeid(double));
Assert<Wrong>(!CHECK_ASSERT || typeid(a)==typeid(double));
try
{
//assert(typeid(a)==typeid(int)); // FAIL and Abort()
Assert<Wrong>(!CHECK_ASSERT || typeid(a)==typeid(int)); // FALL
}
catch (Wrong)
{
std::cerr <<"Exception, not an int" <<std::endl;
}
}
You should be able to compare using std::is_same and using decltype. You can even use std::static_assert to move the check to compile time. I've seen it happen in libc++ :)
Note these are C++11 features, so you'll need to have a compiler that supports decltype
Given the current definition of the code, a way to check at compile time whether both are of the same type is:
template< typename T, typename U >
void assert_same_type( T const&, U const& )
{
int error[ sizeof( T ) ? -1 : -2 ]; // error array of negative size, dependent on T otherwise some implementations may cause an early error message even when they shouldn't
}
template< typename T >
void assert_same_type( T&, T& ){}
void MyClass::setX(double input)
{
assert_same_type( x, input ); // If the fallback case is instantiated then a compile time error will arise of trying to declare an array of negative size.
x = input;
}
You can create a template function, then overload the argument type for double like this:
#include <cassert>
template<class T>
bool is_double(T) { return false; }
bool is_double(double) { return true; }
int main() {
int i = 1;
double d = 3.14;
assert( is_double(d) );
assert( is_double(i) ); // fails
}
That would give a run-time error. You can generate a compile time error by simply defining a function that takes a double reference:
void is_double(double&) { }
void MyClass::setX(double input)
{
is_double(x); // assert x is double
x = input;
}