/*
 * RegExpIterate.h
 *
 *  Created on: 17. 10. 2014
 *	  Author: Jan Travnicek
 */

#pragma once

#include "regexp/formal/FormalRegExpIteration.h"
#include "regexp/unbounded/UnboundedRegExpIteration.h"

#include <regexp/formal/FormalRegExp.h>
#include <regexp/unbounded/UnboundedRegExp.h>

namespace regexp {

namespace transform {

/**
 * Implements iteration of regular expression.
 *
 */
class RegExpIterate {
public:
	/**
	 * Implements iteration of regular expression.
	 *
	 * \tparam SymbolType the type of symbols in the regular expression
	 *
	 * \param regexp the regexp to iterate
	 *
	 * \return regexp describing @p regexp *
	 */
	template < class SymbolType >
	static regexp::FormalRegExp < SymbolType > iterate(const regexp::FormalRegExp < SymbolType > & regexp);

	/**
	 * \override
	 */
	template < class SymbolType >
	static regexp::FormalRegExpStructure < SymbolType > iterate(const regexp::FormalRegExpStructure < SymbolType > & regexp);

	/**
	 * \override
	 */
	template < class SymbolType >
	static regexp::UnboundedRegExp < SymbolType > iterate(const regexp::UnboundedRegExp < SymbolType > & regexp);

	/**
	 * \override
	 */
	template < class SymbolType >
	static regexp::UnboundedRegExpStructure < SymbolType > iterate(const regexp::UnboundedRegExpStructure < SymbolType > & regexp);
};

template < class SymbolType >
regexp::FormalRegExp < SymbolType > RegExpIterate::iterate(const regexp::FormalRegExp < SymbolType > & regexp) {
	return regexp::FormalRegExp < SymbolType >(RegExpIterate::iterate(regexp.getRegExp()));
}

template < class SymbolType >
regexp::FormalRegExpStructure < SymbolType > RegExpIterate::iterate(const regexp::FormalRegExpStructure < SymbolType > & regexp) {
	return regexp::FormalRegExpStructure < SymbolType >(regexp::FormalRegExpIteration < SymbolType > (regexp.getStructure()));
}

template < class SymbolType >
regexp::UnboundedRegExp < SymbolType > RegExpIterate::iterate(const regexp::UnboundedRegExp < SymbolType > & regexp) {
	return regexp::UnboundedRegExp < SymbolType >(RegExpIterate::iterate(regexp.getRegExp()));
}

template < class SymbolType >
regexp::UnboundedRegExpStructure < SymbolType > RegExpIterate::iterate(const regexp::UnboundedRegExpStructure < SymbolType > & regexp) {
	return regexp::UnboundedRegExpStructure < SymbolType >(regexp::UnboundedRegExpIteration < SymbolType > (regexp.getStructure()));
}

} /* namespace transform */

} /* namespace regexp */

