#include <ostream>
#include <iostream>
#include <string>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/mpl/replace.hpp>
#include <boost/fusion/container.hpp>
#include <boost/fusion/sequence.hpp>
#include <typeinfo>
using namespace std;
template<class DERIVED_TYPE>
struct HaveChildren
{
friend ostream& operator<< (ostream& streamReceiver, const HaveChildren<DERIVED_TYPE>& streamSender)
{
DERIVED_TYPE const& RealStreamSender = static_cast<DERIVED_TYPE const&>(streamSender);
streamReceiver << RealStreamSender.children;
return streamReceiver ;
}
};
template<typename... CHILDREN_TYPES>
struct childrenListType : public boost::fusion::vector<CHILDREN_TYPES...>
{
childrenListType(CHILDREN_TYPES&&... args) : boost::fusion::vector<CHILDREN_TYPES...>(forward<CHILDREN_TYPES>(args)...) {}
friend ostream& operator<< (ostream& streamReceiver, const childrenListType<CHILDREN_TYPES...>& streamSender)
{
for_each(streamSender, [&](const auto& child)
{
streamReceiver << child;
});
return streamReceiver;
}
};
struct stringAndSpace :HaveChildren<stringAndSpace>
{
struct space
{
space() {}
friend ostream& operator<< (ostream& streamReceiver, const space& streamSender)
{
return streamReceiver << " ";
}
};
const childrenListType<string, space> children;
template<typename STRING_VALUE_TYPE>
stringAndSpace(STRING_VALUE_TYPE&& value) :children(std::forward<STRING_VALUE_TYPE >(value), {}) {}
};
struct MyChildrenNeedsSpaceWithReplacer : HaveChildren<MyChildrenNeedsSpaceWithReplacer>
{
typedef childrenListType<string, string, string, string> context;
typedef boost::mpl::replace< context, string, stringAndSpace >::type replacedContext;
const replacedContext children;
MyChildrenNeedsSpaceWithReplacer() : children( "this" ,"sentence" , "needs" , "spaces")
{
std::cout << endl << "The children type is:" << endl <<typeid(children).name() << endl;
}
};
struct MyChildrenNeedsSpace : HaveChildren<MyChildrenNeedsSpace>
{
typedef childrenListType<string, string, string, string> context;
const context children;
MyChildrenNeedsSpace() : children("this", "sentence", "needs", "spaces")
{
std::cout << endl << "The children type is:" << endl << typeid(children).name() << endl;
}
};
int main(int argc, char* argv[])
{
cout << "First we output the class where the strings do not get replaced with strings AND spaces" << endl;
cout << "Output:"<< endl << MyChildrenNeedsSpace () ;
cout << endl << endl << "Now we output the class where I try to inject spaces between the words. " << endl;
cout << "Output:" <<endl << MyChildrenNeedsSpaceWithReplacer();
int i; cin >> i;
return 0;
}
;