#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;
}
;