|
Boost : |
Subject: Re: [boost] [scope_exit] capture list syntax for scope_exit and local_function
From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2009-01-16 07:03:50
Alexander Nasonov <alnsn <at> yandex.ru> writes:
> 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
Hi,
I managed to fix gcc ICEs and to get rid of indirect function call
by following my previous code more closely. And I love the new code
and the new syntax, they'll make a transition to c++0x much smoother.
I have a couple of things in my TODO list but they can wait for
the next release.
See my commit to trunk:
https://svn.boost.org/trac/boost/changeset/50620
I appreciate if people can run regression tests, especially on Windows
because I don't use Windows at the moment.
The sooner we get results for supported compilers/platforms the bigger
is change that release managers will approve it for *this* release.
Note that I missed status/Jamfile.v2. Before running regression.py,
please make sure that scope_exit entry is in the file or add it
manually. I'll commit as soon as I get back to home.
Below you can find a human-readable expansion of the ScopeExit
block quoted above.
Thanks,
Alex
#include <boost/typeof/typeof.hpp>
#if defined(__GNUC__) && !defined(__ICC)
#define TPL_WORKAROUND
#endif
#if defined(TPL_WORKAROUND)
// What are you testing, BOOST_SCOPE_EXIT or BOOST_SCOPE_EXIT_TPL?
//#define TYPENAME
#define TYPENAME typename
#else
#define TYPENAME
#endif
typedef void (*ref_tag)(int&);
typedef void (*val_tag)(int );
template<class T, class Tag> struct member;
template<class T>
struct member<T,ref_tag>
{
T& value;
#if !defined(TPL_WORKAROUND)
member(T& ref) : value(ref) {}
#endif
};
template<class T>
struct member<T,val_tag>
{
T value;
#if !defined(TPL_WORKAROUND)
member(T& val) : value(val) {}
#endif
};
template<class T>
struct wrapper
{
typedef T type;
};
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TEMPLATE(wrapper, 1)
template<class T> wrapper<T> wrap(T&);
template<class T> inline T& deref(T* p, void (*)(int&)) { return *p; }
template<class T> inline T& deref(T& r, void (*)(int )) { return r; }
// TODO: Change return type of deref to member<T,tag> and get rid of wrap
#include <iostream>
// What are you testing, BOOST_SCOPE_EXIT or BOOST_SCOPE_EXIT_TPL?
//typedef int A; typedef int B;
template<class A, class B>
void foo(A& a, B const& b)
{
char c = 0;
// Input: (&a)(&b)(c)
typedef void (*tag_0)(int &a);
typedef void (*tag_1)(int &b);
typedef void (*tag_2)(int c);
#if defined(BOOST_TYPEOF_NATIVE)
// Note: BOOST_TYPEOF_KEYWORD should not strip const
// if deref returns T const&
typedef BOOST_TYPEOF_KEYWORD(deref(&a, (tag_0)0)) capture_t_0;
typedef BOOST_TYPEOF_KEYWORD(deref(&b, (tag_1)0)) capture_t_1;
typedef BOOST_TYPEOF_KEYWORD(deref( c, (tag_2)0)) capture_t_2;
#else
struct wrapped_t_0 : BOOST_TYPEOF(wrap(deref(&a, (tag_0)0))) {};
struct wrapped_t_1 : BOOST_TYPEOF(wrap(deref(&b, (tag_1)0))) {};
struct wrapped_t_2 : BOOST_TYPEOF(wrap(deref( c, (tag_2)0))) {};
typedef TYPENAME wrapped_t_0::type capture_t_0;
typedef TYPENAME wrapped_t_1::type capture_t_1;
typedef TYPENAME wrapped_t_2::type capture_t_2;
#endif
struct params_t {
typedef capture_t_0 param_t_0;
typedef capture_t_1 param_t_1;
typedef capture_t_2 param_t_2;
member<param_t_0,tag_0> param_0;
member<param_t_1,tag_1> param_1;
member<param_t_2,tag_2> param_2;
#if !defined(TPL_WORKAROUND)
params_t(param_t_0& a0, param_t_1& a1, param_t_2& a2)
: param_0(a0), param_1(a1), param_2(a2)
{}
#endif
}
params
#if defined(TPL_WORKAROUND)
= { { deref(&a, (tag_0)0) },
{ deref(&b, (tag_1)0) },
{ deref( c, (tag_2)0) } };
#else
( deref(&a, (tag_0)0),
deref(&b, (tag_1)0),
deref( c, (tag_2)0) );
#endif
void* p = ¶ms; // real code uses Watanabe's trick
struct guard_t {
params_t* params_;
guard_t(void* p)
: params_((params_t*)p)
{}
~guard_t()
{
guard_t::body( params_->param_0.value,
params_->param_1.value,
params_->param_2.value );
}
// TODO: don't pass c by value
static void body( TYPENAME params_t::param_t_0 &a,
TYPENAME params_t::param_t_1 &b,
TYPENAME params_t::param_t_2 c )
{
// user's code
std::cout << a << '\n' << b << '\n' << c << '\n';
}
} guard(p);
}
int main()
{
int i = 0;
foo(i, 1u);
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk