Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Metaprogramming "for" loop

30 views
Skip to first unread message

Peng...@gmail.com

unread,
Feb 24, 2007, 9:32:23 PM2/24/07
to
Hi,

I have the code below this email. I want to replace the last 4 lines
with a Metaprogramming loop to get something like the following (I
don't know the syntax). Is it possible?

for type in {left_tag, right_tag, down_tag, up_tag) {
fun(type());
}


Thanks,
Peng

struct left_tag{};
struct right_tag{};
struct down_tag{};
struct up_tag{};

template <typename Dir>
void fun(Dir) { }

//Can I replace the following code with a metaprogramming "for" loop
fun(left_tag());
fun(right_tag());
fun(down_tag());
fun(up_tag());

kwikius

unread,
Feb 25, 2007, 1:24:09 AM2/25/07
to

Yes.

However in all the metaprogramming libraries I know of you need to
put the tags in some sort of tuple which is accessible to
metaprogramming. (std::tr1::tuple could be adapted for this but no std
way exists AFAIK) In my own libraries I would do something like the
following code below --->

Other libraries that do similar are boost::fusion (not released but
accessible via CVS). I think you can do similar with boost::mpl though
it is nominally only for compile time programming AFAIK and isnt
compatible with std::tr1 type_traits or std::tr1::tuple IIRC.

#include <quan/fun/vector4.hpp>
#include <quan/fun/for_each.hpp>

struct left_tag{};
struct right_tag{};
struct down_tag{};
struct up_tag{};

// some tuple with metaprogramming facilities
typedef quan::fun::vector4<left_tag,right_tag,down_tag,up_tag> tags;

// any functor with similar signature will do.

struct fun{

template <typename T>
void operator()(T const & t) const
{
std::cout << typeid(T).name() <<'\n';
}

};
int main()
{
quan::fun::for_each(tags(),fun());

}

/*
output:

struct left_tag
struct right_tag
struct down_tag
struct up_tag

*/

Piyo

unread,
Feb 25, 2007, 1:25:09 AM2/25/07
to

I am quoting one of my previous posts that may be helpful to you
regarding this. The idea is it define a tuple that has all your
structures in one place and let the template metaprogram unfold it
for you.

So in your case, you will need to define
typedef boost::tuple<left_tag,right_tag,down_tag,up_tag> stuffToProc;

then you do stuff similar to the metaprogram. Here I modified it to
call your function, fun()

// recursive case
template< int N >
class test
{
public:
static void doIt( const stuffToProc &t )
{
test<N-1>::doIt( t );
fun( t.get<N>() );
}
};

// basis case
template<>
class test<0>
{
public:
static void doIt( const stuffToProc &t )
{
fun( t.get<0>() );
}
};

then you can use it as follows:

int
main()
{
stuffToProc thisIsTheStuff;
test<4>::doit( thisIsTheStuff );
}

I was investigating a way to manufacture objects based
on an array of typeid's but I did not have the time.
I think that the problem you are describing can be
solved differently and probably easily if we can figure
out an efficient way to create arbitrary typed objects
from its typeid. When I get the chance, I'll investigate
this further since this problem keeps popping up now and
again.

HTH

> Ok so let's look at boost::tuple. You can create essentially a structure-like object with it except that the accessors are via numbers.
> (http://www.boost.org/libs/tuple/doc/tuple_users_guide.html)
>
> Then you can use a recursive template metaprogram to access each
> element in the tuple. So it would look like something like this:
>
> // for illustration purposes only
> typedef boost::tuple<int,float,double> YourTuple;
>
> // recursive case
> template< int N >
> class test
> {
> public:
> static void doIt( const YourTuple &t )
> {
> test<N-1>::doIt( t );
> reverseEndian<>( t.get<N>() );
> }
> };
>
> // basis case
> template<>
> class test<0>
> {
> public:
> static void doIt( const YourTuple &t )
> {
> reverseEndian<>( t.get<0>() );
> }
> };

kwikius

unread,
Feb 25, 2007, 2:13:41 AM2/25/07
to
On 25 Feb, 06:25, Piyo <cybermax...@yahoo.com> wrote:

<...>

Thats basically it using boost::tuple..
You can wrap the implementation in some for_each construct, which
automatically computes the size and use more template params. For
boost tuple you can get the size by tuple::length, and dont forget its
zero based so off by 1.
It should then work for different element_types and tuple lengths
too...

regards Andy Little

#include <boost/tuple/tuple.hpp>
#include <iostream>

struct left_tag{};
struct right_tag{};
struct down_tag{};
struct up_tag{};

typedef boost::tuple<left_tag,right_tag,down_tag,up_tag> stuffToProc;

struct fun{

template <typename T>
void operator()(T const & t)const
{
std::cout << typeid(T).name() <<'\n';
}
};

template< int N >
class test {
public:
template <typename T, typename F>
static void doIt( const T &t,F f )
{
test<N-1>::doIt( t ,f );
f( t. template get<N>() );
}
};

// basis case
template<>
class test<0> {
public:

template <typename T, typename F>
static void doIt( const T &t, F f )
{
f( t. template get<0>() );
}
};

// some for_each
template <typename T, typename F>
void for_each( T & t, F f)
{
test<(boost::tuples::length<T>::value -1)>::doIt(t,f);
}


int main()
{
stuffToProc thisIsTheStuff;
for_each(thisIsTheStuff ,fun());
}

regards
Andy Little


kwikius

unread,
Feb 25, 2007, 2:34:57 AM2/25/07
to
On 25 Feb, 07:13, "kwikius" <a...@servocomm.freeserve.co.uk> wrote:
> On 25 Feb, 06:25, Piyo <cybermax...@yahoo.com> wrote:
>
> <...>
>
> Thats basically it using boost::tuple..
> You can wrap the implementation in some for_each construct, which
> automatically computes the size and use more template params. For
> boost tuple you can get the size by tuple::length, and dont forget its
> zero based so off by 1.
> It should then work for different element_types and tuple lengths
> too...
>
> regards Andy Little

Oh and you can use the make_tuple function so you dont need the
explicit typedef, which is pretty close to what you want I think :

int main()
{
// stuffToProc thisIsTheStuff;
for_each(
boost::tuples::make_tuple(
left_tag(),right_tag(),up_tag(),down_tag()
)
,fun());

// or ...
left_tag lt;
right_tag rt;
down_tag dt;
up_tag ut;

using boost::tuples::make_tuple;

for_each(make_tuple(lt,rt,ut,dt),fun());


regards
Andy Little

Piyo

unread,
Feb 25, 2007, 6:32:43 PM2/25/07
to
kwikius wrote:

>
> int main()
> {
> // stuffToProc thisIsTheStuff;
> for_each(
> boost::tuples::make_tuple(
> left_tag(),right_tag(),up_tag(),down_tag()
> )
> ,fun());
>
> // or ...
> left_tag lt;
> right_tag rt;
> down_tag dt;
> up_tag ut;
>
> using boost::tuples::make_tuple;
>
> for_each(make_tuple(lt,rt,ut,dt),fun());
>
>
> regards
> Andy Little
>

Pretty sweet stuff there Andy :) I was also thinking to
suggest dropping the class and make "test" into a function
template. I wrote that original code to solve something
else but eventually didn't (I couldn't figure out some
stuff).

On a different note: you brought up the use of tr1 data
structs. Do you know of a website detailing the stuff there?
I can't seem to find one that is as clean and organized
as sgi's website of the STL stuff.

Thanks!

Jerry Coffin

unread,
Feb 25, 2007, 7:35:59 PM2/25/07
to
In article <H0pEh.523$tv...@newssvr19.news.prodigy.net>, cybermax_69
@yahoo.com says...

[ ... ]

> On a different note: you brought up the use of tr1 data
> structs. Do you know of a website detailing the stuff there?
> I can't seem to find one that is as clean and organized
> as sgi's website of the STL stuff.

I don't know of a web site, but Pete Becker's book (_The C++ Standard
Library Extensions_) is quite good.

--
Later,
Jerry.

The universe is a figment of its own imagination.

kwikius

unread,
Feb 26, 2007, 12:27:21 AM2/26/07
to
On 26 Feb, 00:35, Jerry Coffin <jcof...@taeus.com> wrote:
> In article <H0pEh.523$tv...@newssvr19.news.prodigy.net>, cybermax_69
> @yahoo.com says...
>
> [ ... ]
>
> > On a different note: you brought up the use of tr1 data
> > structs. Do you know of a website detailing the stuff there?
> > I can't seem to find one that is as clean and organized
> > as sgi's website of the STL stuff.
>
> I don't know of a web site, but Pete Becker's book (_The C++ Standard
> Library Extensions_) is quite good.

Yes, and you can find out the specs by looking at the draft C++
extensions paper:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf


regards
Andy Little

Peng...@gmail.com

unread,
Mar 14, 2007, 11:48:57 AM3/14/07
to

Could you please show me what are in the files quan/fun/vector4.hpp
quan/fun/for_each.hpp?

Thanks,
Peng

Peng...@gmail.com

unread,
Mar 14, 2007, 11:55:58 AM3/14/07
to

Are these implemented in any compiler, yet?

Tahnks,
Peng

0 new messages