/*
 * ObjectsVariant.h
 *
 * Created on: Sep 27, 2017
 * Author: Jan Travnicek
 */

#ifndef _STRING_OBJECTS_VARIANT_H_
#define _STRING_OBJECTS_VARIANT_H_

#include <alib/variant>
#include <core/stringApi.hpp>

#include <container/ContainerFromStringLexer.h>

namespace core {

template < class ... Types >
struct stringApi < ext::variant < Types ... > > {
	static ext::variant < Types ... > parse ( std::istream & input );
	static bool first ( std::istream & input );
	static void compose ( std::ostream & output, const ext::variant < Types ... > & container );

private:
	class VariantStringApiCallback {
		std::ostream & m_out;
	
	public:
		VariantStringApiCallback ( std::ostream & out ) : m_out ( out ) {
		}

		template < class ValueType >
		void operator ( ) ( const ValueType & value ) {
			stringApi < ValueType >::compose ( m_out, value );
		}

		void operator ( ) ( ) {
			m_out << "void";
		}
	};
};

template < class ... Types >
ext::variant < Types ... > stringApi < ext::variant < Types ... > >::parse ( std::istream & /* input */ ) {
	throw exception::CommonException("parsing BarSymbol from string not implemented");
}

template < class ... Types >
bool stringApi < ext::variant < Types ... > >::first ( std::istream & /* input */ ) {
	return false;
}

template < class ... Types >
void stringApi < ext::variant < Types ... > >::compose ( std::ostream & output, const ext::variant < Types ... > & container ) {
	container.template call < void > ( VariantStringApiCallback ( output ) );
}

} /* namespace core */

#endif /* _STRING_OBJECTS_VARIANT_H_ */