Metaprogramming "for" loop

Discussion in 'C++' started by PengYu.UT@gmail.com, Feb 25, 2007.

  1. Guest

    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());
     
    , Feb 25, 2007
    #1
    1. Advertising

  2. kwikius Guest

    On 25 Feb, 02:32, "" <> wrote:
    > 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());


    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

    */
     
    kwikius, Feb 25, 2007
    #2
    1. Advertising

  3. Piyo Guest

    wrote:
    > 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());
    >


    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>() );
    > }
    > };
     
    Piyo, Feb 25, 2007
    #3
  4. kwikius Guest

    On 25 Feb, 06:25, Piyo <> 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, Feb 25, 2007
    #4
  5. kwikius Guest

    On 25 Feb, 07:13, "kwikius" <> wrote:
    > On 25 Feb, 06:25, Piyo <> 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
     
    kwikius, Feb 25, 2007
    #5
  6. Piyo Guest

    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!
     
    Piyo, Feb 25, 2007
    #6
  7. Jerry Coffin Guest

    In article <H0pEh.523$>, 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.
     
    Jerry Coffin, Feb 26, 2007
    #7
  8. kwikius Guest

    On 26 Feb, 00:35, Jerry Coffin <> wrote:
    > In article <H0pEh.523$>, 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
     
    kwikius, Feb 26, 2007
    #8
  9. Guest

    On Feb 25, 1:24 am, "kwikius" <> wrote:
    > On 25 Feb, 02:32, "" <> wrote:
    >
    >
    >
    > > 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());

    >
    > 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
    >
    > */


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

    Thanks,
    Peng
     
    , Mar 14, 2007
    #9
  10. Guest

    On Feb 26, 12:27 am, "kwikius" <> wrote:
    > On 26 Feb, 00:35, Jerry Coffin <> wrote:
    >
    > > In article <H0pEh.523$>, 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


    Are these implemented in any compiler, yet?

    Tahnks,
    Peng
     
    , Mar 14, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave
    Replies:
    0
    Views:
    622
  2. Dave
    Replies:
    12
    Views:
    590
    Mike Hewson
    Dec 26, 2003
  3. Sarah Thompson
    Replies:
    2
    Views:
    387
    Sumit Rajan
    Apr 23, 2004
  4. ticapix
    Replies:
    1
    Views:
    488
    Neelesh Bodas
    Jul 6, 2007
  5. Isaac Won
    Replies:
    9
    Views:
    397
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page