0

I want to iterate in compile time over struct and write to output number of iteration. Just to mention - in real case I will pass some more parameters in data.

#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>

struct MyStruct
{
    int x;
    int y;
};

BOOST_FUSION_ADAPT_STRUCT(
    MyStruct,
    (int, x)
    (int, y)    
    )

#define PRINT(unused, number, data) \
    std::cout << number << std::endl;

int main()
{
    MyStruct s;

    std::cout << boost::fusion::size(s) << std::endl;
    //line below works - it iterate and write output
    BOOST_PP_REPEAT(2, PRINT, "here I will pass my data")

    //this won't compile 
    //BOOST_PP_REPEAT(boost::fusion::size(s), PRINT, "here i will pass my data")
}

How to fix problematic line so it will work when I will add more members in structure? I need solution for C++03 :(

Adrian
  • 71
  • 12
  • Size function should be computed in the preprocessor stage, which is currently not the situation. Why don't you use fusion::for_each instead? – Curve25519 Jul 29 '15 at 19:58
  • In real case I want to build simple switch - each case is created by BOOST_PP_REPEAT - fusion::for_each looks. But if you may show switch statement with boost::fusion::for_each - then I can use it :) (just show in addition how to loads more than one parameter so I could use that in case statement (like std::cout << param1 << param2) – Adrian Jul 29 '15 at 20:18

2 Answers2

2

Instead of using BOOST_PP_REPEAT, you can use the boost::fusion::for_each which goes through every element. example:

#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>

struct MyStruct {
    int x;
    int y;
};

BOOST_FUSION_ADAPT_STRUCT(
    MyStruct,
    (int, x)
    (int, y)
)

template<typename Data>
struct PrintWithData {
    PrintWithData(Data data) : data(data) {}

    template<typename T>
    operator()(const T& thingToBePrinted)
    {
        std::cout << thingToBePrinted << std::endl;
    }

    Data data;
};

int main()
{
    MyStruct s;
    //this will compile
    boost::fusion::for_each(s, PrintWithData<std::string>("here I will pass my data"));
}
Curve25519
  • 584
  • 4
  • 17
  • This solution work, but it if I understand correctly it is adding one more call - to operator(). I want use this solution to create swich case and this solution may be a bit slower than just creating swich by compiler. I voted this as good solution but is it possible to use boost_pp_repeat with fusion::size - in std::cout case it is working? – Adrian Jul 29 '15 at 21:22
  • 1
    It's making two calls to operator(), one for each element (but there's only one compiled, with [T=int]). It will probably inline this function for you, so it's not that bad. As i said in the comment, in order to use `boost_pp_repeat` the depth must be computed at preprocessor time, while fusion::size is computed at compile time. It's simply can't be done. – Curve25519 Jul 30 '15 at 18:01
0

Here is exact solution for this problem (asked more general question later, and found answear which solve this problem too): https://stackoverflow.com/a/31713778/4555790

Community
  • 1
  • 1
Adrian
  • 71
  • 12