|
Boost : |
Subject: [boost] [scope_exit] capture list syntax for scope_exit and local_function
From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2009-01-14 06:55:03
gmane wrote:
> The following errors were found. Fix them, and submit again:
> You seem to be top-posting. Don't do that.
apparently gmane bug.
Hi,
My current implementation uses ref/cref/val prefixes to pass arguments.
It's not consistent with C++0x lambda capture list syntax.
scope_exit: (ref a)(cref b)(val c)
c++0x: [&a, &b, c]
I have a proof-of-concept implementation for
BOOST_SCOPE_EXIT( (&a)(&b)(c) )
{
std::cout << a << '\n' << b << '\n' << c << '\n';
}
BOOST_SCOPE_EXIT_END
It does not support passing by reference of classes with overloaded
unary operator& but they are rather rare and we can tell users to
use reference_wrapper to pass them.
Also, it does indirect function call. Gcc 3.4 and 4.2 don't optimize
it away even with -O3 but Intel 10.1 does (though, it generates a body
of the function even with -Os).
What do you think?
#include <iostream>
#include <boost/mpl/if.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits/is_function.hpp>
template<class T> inline T& deref(T* p, boost::false_type) { return *p; }
template<class T> inline T& deref(T& r, boost::true_type) { return r; }
void foo(int a, long const b, char const c)
{
int &a_ref_test();
int &b_ref_test();
int c_ref_test();
typedef boost::is_function<typeof(&a_ref_test)> is_not_ref_0;
typedef boost::is_function<typeof(&b_ref_test)> is_not_ref_1;
typedef boost::is_function<typeof( c_ref_test)> is_not_ref_2;
typedef typeof(deref(&a, is_not_ref_0())) value_t_0;
typedef typeof(deref(&b, is_not_ref_1())) value_t_1;
typedef typeof(deref( c, is_not_ref_2())) value_t_2;
typedef boost::mpl::if_<
is_not_ref_0,
boost::call_traits<value_t_0>::param_type,
value_t_0
>::type param_t_0;
typedef boost::mpl::if_<
is_not_ref_1,
boost::call_traits<value_t_1>::param_type,
value_t_1
>::type param_t_1;
typedef boost::mpl::if_<
is_not_ref_2,
boost::call_traits<value_t_2>::param_type,
value_t_2
>::type param_t_2;
struct params_t {
value_t_0 &a;
value_t_1 &b;
value_t_2 c;
params_t(param_t_0 &a, param_t_1 &b, param_t_2 c)
: a(a), b(b), c(c)
{}
void invoke(void (*f)(param_t_0 &a, param_t_1 &b, param_t_2 c))
{
f( deref(&a, is_not_ref_0()),
deref(&b, is_not_ref_1()),
deref( c, is_not_ref_2())
);
}
};
params_t params(
deref(&a, is_not_ref_0()),
deref(&b, is_not_ref_1()),
deref( c, is_not_ref_2())
);
void* p = ¶ms;
struct guard_t {
params_t* params;
guard_t(void* p)
: params((params_t*)p)
{}
~guard_t()
{
params->invoke(&guard_t::body);
}
static void body(param_t_0 &a, param_t_1 &b, param_t_2 c)
{
std::cout << a << '\n' << b << '\n' << c << '\n';
}
} guard(p);
}
int main()
{
foo(0, 1, '2');
}
Thanks,
Alex
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk