How can I use the Boost preprocessor to statically initialize an array with string and pointer pairs as shown below
#include <string>
struct Node;
struct Port
{
Port(std::string name_, Node* owner_): name(name_), owner(owner_)
{
}
std::string name;
Node* owner;
};
struct Node
{
// TODO: replace with Port port[4] = { REPEAT_SEQ(RX, 4) };
Port port[4] = {{"RX_0", this}, {"RX_1", this}, {"RX_2", this}, {"RX_3", this}};
};
int main()
{
Node node;
}
The problem is that some nodes have lots of ports and writing these port name and owner pointer pairs is tedious and error prone.
I'd like to automate it with the Boost Preprocessor, for example REPEAT_SEQ(RX, 4)
Ok turns out your problem is not so simple. Whole problem is caused that is is not so easy to construct an array of types which are not default construable.
Solution with a use of Boost preprocessor is bad idea.
It is best to use meta programing to address this issue.
Here is a tool which helps construct an array:
template <typename F, size_t... Is>
auto help_genarate_array(F&& f, std::index_sequence<Is...>)
{
return std::array { f(Is)... };
}
template <size_t N, typename F>
auto genarate_array(F&& f)
{
return help_genarate_array(std::forward<F>(f), std::make_index_sequence<N>());
}
With this tool you can initialize now array like this:
struct Node {
std::array<Port, 4> port;
Node()
: port { genarate_array<4>([this](auto i) { return Port { std::format("RX_{}", i), this }; }) }
{
}
};