S
seguso
Hello,
For the sake of efficiency, I have chosen C++ as the language for a
"Free Adventure Construction Kit" I am developing (http://fack.sf.net).
I am looking for a way to simulate list comprehensions a-la
Haskell/Python, in order to make the logic of my code more readable.
Any way to do that would be welcome, even if this means to use macros.
Here is the code I would like to make more readable (the line marked
with ***):
list<pt<layer_lit> >
perform_lighting ( const list<pt<layer_unlit_0> > unlit_layers,
const set<string> & on_lights,
const map<set<string>, rational_number >& precomputed_factors)
{
// BEGIN grouping declarations here to keep the logic readable
list<pt<layer_unlit_0> >::const_iterator iter;
pt<layer_unlit_0> u;
list<light>::const_iterator iter2;
light l;
list<pt<layer_surf> > li;
list<pt<layer_unlit_1> > unlit1;
list<pt<layer_unlit_1> >::const_iterator iter3;
pt<layer_unlit_1> u2;
map<set<string>, rational_number>::const_iterator norm_factor;
pt<layer_surf> sum;
list<pt<layer_lit> > ret;
// END
foreach3(u, unlit_layers, iter){
// BEGIN *** li = [ l.surf for l in u->on_and_off_lights
// if contains(on_lights, l.name) ]
li.clear();
foreach3(l, u->on_and_off_lights, iter2){
if (contains(on_lights, l.name) ){
li.push_back(l.surf); }}
// END
u2 = pt<layer_unlit_1>(new layer_unlit_1(li, u->y_walkbehind));
unlit1.push_back(u2);}
norm_factor = precomputed_factors.find(on_lights);
//assert(norm_factor != on_lights.end()); // @@ why doesn't this
compile?
foreach3(u2, unlit1, iter3){
sum = sum_each_pixel( u2->on_lights);
normalize_layer(*sum, norm_factor->second);
ret.push_back( pt<layer_lit>(new layer_lit(sum,
u2->y_walkbehind) )); }
return ret;
}
For reference, here are the auxiliary functions and macros I am using:
#define foreach3(i, l,iter) for((iter) = (l).begin(), i = *iter; \\
(iter) != (l).end(); (iter)++, i = *iter)
#define pt shared_ptr // boost::shared_ptr
/// test whether a set of X contains a given X.
template<class Set>
bool
contains(Set s,
typename Set::key_type i)
{
// BEGIN decl
typename Set::const_iterator x;
// END
x = s.find(i);
return x != s.end();
}
Thanks for any hint,
For the sake of efficiency, I have chosen C++ as the language for a
"Free Adventure Construction Kit" I am developing (http://fack.sf.net).
I am looking for a way to simulate list comprehensions a-la
Haskell/Python, in order to make the logic of my code more readable.
Any way to do that would be welcome, even if this means to use macros.
Here is the code I would like to make more readable (the line marked
with ***):
list<pt<layer_lit> >
perform_lighting ( const list<pt<layer_unlit_0> > unlit_layers,
const set<string> & on_lights,
const map<set<string>, rational_number >& precomputed_factors)
{
// BEGIN grouping declarations here to keep the logic readable
list<pt<layer_unlit_0> >::const_iterator iter;
pt<layer_unlit_0> u;
list<light>::const_iterator iter2;
light l;
list<pt<layer_surf> > li;
list<pt<layer_unlit_1> > unlit1;
list<pt<layer_unlit_1> >::const_iterator iter3;
pt<layer_unlit_1> u2;
map<set<string>, rational_number>::const_iterator norm_factor;
pt<layer_surf> sum;
list<pt<layer_lit> > ret;
// END
foreach3(u, unlit_layers, iter){
// BEGIN *** li = [ l.surf for l in u->on_and_off_lights
// if contains(on_lights, l.name) ]
li.clear();
foreach3(l, u->on_and_off_lights, iter2){
if (contains(on_lights, l.name) ){
li.push_back(l.surf); }}
// END
u2 = pt<layer_unlit_1>(new layer_unlit_1(li, u->y_walkbehind));
unlit1.push_back(u2);}
norm_factor = precomputed_factors.find(on_lights);
//assert(norm_factor != on_lights.end()); // @@ why doesn't this
compile?
foreach3(u2, unlit1, iter3){
sum = sum_each_pixel( u2->on_lights);
normalize_layer(*sum, norm_factor->second);
ret.push_back( pt<layer_lit>(new layer_lit(sum,
u2->y_walkbehind) )); }
return ret;
}
For reference, here are the auxiliary functions and macros I am using:
#define foreach3(i, l,iter) for((iter) = (l).begin(), i = *iter; \\
(iter) != (l).end(); (iter)++, i = *iter)
#define pt shared_ptr // boost::shared_ptr
/// test whether a set of X contains a given X.
template<class Set>
bool
contains(Set s,
typename Set::key_type i)
{
// BEGIN decl
typename Set::const_iterator x;
// END
x = s.find(i);
return x != s.end();
}
Thanks for any hint,