/*
 * Pair.h
 *
 * Created on: Apr 1, 2013
 * Author: Jan Travnicek
 */

#pragma once

#include <alib/pair>
#include <core/xmlApi.hpp>

namespace core {

template < typename T, typename R >
struct xmlApi < std::pair < T, R > > {
	static std::pair < T, R > parse ( ext::deque < sax::Token >::iterator & input );
	static bool first ( const ext::deque < sax::Token >::const_iterator & input );
	static std::string xmlTagName ( );
	static void compose ( ext::deque < sax::Token > & output, const std::pair < T, R > & input );
};

template < typename T, typename R >
std::pair < T, R > xmlApi < std::pair < T, R > >::parse ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );

	T first = core::xmlApi < T >::parse ( input );
	R second = core::xmlApi < R >::parse ( input );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) );

	return std::make_pair ( std::move ( first ), std::move ( second ) );
}

template < typename T, typename R >
bool xmlApi < std::pair < T, R > >::first ( const ext::deque < sax::Token >::const_iterator & input ) {
	return sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );
}

template < typename T, typename R >
std::string xmlApi < std::pair < T, R > >::xmlTagName ( ) {
	return "Pair";
}

template < typename T, typename R >
void xmlApi < std::pair < T, R > >::compose ( ext::deque < sax::Token > & output, const std::pair < T, R > & input ) {
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT );

	core::xmlApi < typename std::decay < T >::type >::compose ( output, input.first );
	core::xmlApi < R >::compose ( output, input.second );

	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT );
}

template < typename T, typename R >
struct xmlApi < ext::pair < T, R > > {
	static ext::pair < T, R > parse ( ext::deque < sax::Token >::iterator & input );
	static bool first ( const ext::deque < sax::Token >::const_iterator & input );
	static std::string xmlTagName ( );
	static void compose ( ext::deque < sax::Token > & output, const ext::pair < T, R > & input );
};

template < typename T, typename R >
ext::pair < T, R > xmlApi < ext::pair < T, R > >::parse ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );

	T first = core::xmlApi < T >::parse ( input );
	R second = core::xmlApi < R >::parse ( input );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) );

	return ext::make_pair ( std::move ( first ), std::move ( second ) );
}

template < typename T, typename R >
bool xmlApi < ext::pair < T, R > >::first ( const ext::deque < sax::Token >::const_iterator & input ) {
	return xmlApi < std::pair < T, R > >::first ( input );
}

template < typename T, typename R >
std::string xmlApi < ext::pair < T, R > >::xmlTagName ( ) {
	return xmlApi < std::pair < T, R > >::xmlTagName ( );
}

template < typename T, typename R >
void xmlApi < ext::pair < T, R > >::compose ( ext::deque < sax::Token > & output, const ext::pair < T, R > & input ) {
	xmlApi < std::pair < T, R > >::compose ( output, input );
}

} /* namespace core */

