Watching Herb Sutter's talk about atomics at C++ and beyond I glimpsed at his idea of an easy to use lock/unlock mechanism that may or may not come in a future standard of the language.
The mechanism looks likes:
atomic{
// code here
}
Not wanting to wait for a future standard I tried implementing this myself, what I've come up with is this:
#define CONCAT_IMPL(A, B) A ## B
#define CONCAT(A, B) CONCAT_IMPL(A, B)
# define atomic(a) { \
static_assert(std::is_same<decltype(a), std::mutex>::value,"Argument must be of type std::mutex !");\
struct CONCAT(atomic_impl_, __LINE__)\
{\
std::function<void()> func;\
std::mutex* impl;\
CONCAT(atomic_impl_, __LINE__)(std::mutex& b)\
{ \
impl = &b;\
impl->lock();\
}\
CONCAT(~atomic_impl_, __LINE__)()\
{ \
func();\
impl->unlock(); \
}\
} CONCAT(atomic_impl_var_, __LINE__)(a);\
CONCAT(atomic_impl_var_, __LINE__).func = [&]()
and usage:
std::mutex mut;
atomic(mut){
// code here
};}
The problem, obviously, is the }; which I'd like to remove.
Is this possible in any way?
You can do this with the trick of defining variables inside an if statement.
template <typename M>
struct atomic_guard_ {
explicit atomic_guard_(M& m) : lock(m) {}
atomic_guard_(M const&) =delete; // Since we unfortunately have to use uniform
atomic_guard_(M&&) =delete; // initialization, make it at least a little safe
operator bool() const { return false; }
std::lock_guard<M> lock;
};
#define atomic(m) \
if (atomic_guard_<std::decay<decltype(m)>::type> _{m}) {} else
int main()
{
std::mutex m;
atomic(m) {
std::cout << "a\n";
}
atomic(m) // this works too, but I think this is ok
std::cout << "b\n";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With