#include <iostream>
#include <string>
#include <array>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;


// ...code from http://w...content-available-to-author-only...t.org/doc/libs/1_60_0/libs/spirit/example/qi/boost_array.cpp here
////////////////////////////////////////////////////////////////////////////////////////////////

namespace detail
{
	template <typename T>
	struct adapt_array;

	template <typename T, std::size_t N>
	struct adapt_array<std::array<T, N> >
	{
		typedef std::array<T, N> array_type;

		adapt_array(array_type& arr)
			: arr_(arr), current_(0) {}

		// expose a push_back function compatible with std containers
		bool push_back(typename array_type::value_type const& val)
		{
			// if the array is full, we need to bail out
			// returning false will fail the parse
			if (current_ >= N)
				return false;

			arr_[current_++] = val;
			return true;
		}

		array_type& arr_;
		std::size_t current_;
	};
}

namespace result_of
{
	template <typename T>
	struct adapt_array;

	template <typename T, std::size_t N>
	struct adapt_array<std::array<T, N> >
	{
		typedef detail::adapt_array<std::array<T, N> > type;
	};
}

template <typename T, std::size_t N>
inline detail::adapt_array<std::array<T, N> >
adapt_array(std::array<T, N>& arr)
{
	return detail::adapt_array<std::array<T, N> >(arr);
}


// specialize Spirit's container specific customization points for our adaptor
namespace boost { namespace spirit { namespace traits
{
    template <typename T, std::size_t N>
     struct is_container<::detail::adapt_array<std::array<T, N> > >
       : boost::mpl::true_
     {};

    template <typename T, std::size_t N>
    struct container_value<::detail::adapt_array<std::array<T, N> > >
    {
        typedef T type;     // value type of container
    };

    template <typename T, std::size_t N>
    struct push_back_container<
		::detail::adapt_array<std::array<T, N> >, T>
    {
        static bool call(::detail::adapt_array<std::array<T, N> >& c
          , T const& val)
        {
            return c.push_back(val);
        }
    };
}}}


// test

typedef result_of::adapt_array<std::array<double, 6> >::type AdaptedArrayType;

struct StructWithArray
{
	StructWithArray()
		: adaptedAry_(ary_)
	{}

	double dummy_; // see http://stackoverflow.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct
	std::array<double, 6> ary_;
	AdaptedArrayType adaptedAry_;
};

BOOST_FUSION_ADAPT_STRUCT(
	StructWithArray
	,
	(double, dummy_)
	(AdaptedArrayType, adaptedAry_)
	)

	template <typename Iterator, typename Skipper>
struct StructWithArrayParser
	: qi::grammar<Iterator, StructWithArray(), Skipper>
{
	StructWithArrayParser() : StructWithArrayParser::base_type(start)
	{
		using qi::double_;

		arrayLine %= double_ > double_ > double_ > double_ > double_ > double_;
		start %= double_ > arrayLine;
	}

	qi::rule<Iterator, AdaptedArrayType(), Skipper> arrayLine;
	qi::rule<Iterator, StructWithArray(), Skipper> start;
};

int main() {
	std::string arrayStr = "0 1 2 3 4 5 6";
	std::string::const_iterator it = arrayStr.begin();
	std::string::const_iterator endIt = arrayStr.end();
	StructWithArrayParser<std::string::const_iterator, ascii::space_type> grammar;
	StructWithArray structWithArray;
	bool ret = phrase_parse(it, endIt, grammar, ascii::space, structWithArray);
	std::cout << ret << " " << structWithArray.ary_[0] << " " << structWithArray.ary_[5];
	return 0;
}
