#include <testing.h>

#include "sax/SaxParseInterface.h"
#include "sax/SaxComposeInterface.h"

#include "regexp/unbounded/UnboundedRegExp.h"
#include "regexp/unbounded/UnboundedRegExpElements.h"
#include "regexp/formal/FormalRegExp.h"
#include "regexp/formal/FormalRegExpElements.h"

#include "regexp/xml/UnboundedRegExp.h"

#include "factory/XmlDataFactory.hpp"

TEST_CASE ( "RegExp test", "[unit][data][regexp]" ) {
	SECTION ( "Copy construction" ) {
		{
			regexp::UnboundedRegExpSymbol < int > l1 = regexp::UnboundedRegExpSymbol < int >( 1 );
			regexp::UnboundedRegExpSymbol < int > l2 = regexp::UnboundedRegExpSymbol < int >( 2 );

			regexp::UnboundedRegExpConcatenation < int > con = regexp::UnboundedRegExpConcatenation < int >();
			con.appendElement(l1);
			con.appendElement(l2);

			regexp::UnboundedRegExpIteration < int > ite = regexp::UnboundedRegExpIteration < int >(l1);

			regexp::UnboundedRegExpAlternation < int > alt = regexp::UnboundedRegExpAlternation < int >();
			alt.appendElement(con);
			alt.appendElement(ite);

			regexp::UnboundedRegExp < int > regexp({1, 2, 3}, regexp::UnboundedRegExpStructure < int > ( alt ) );

			regexp::UnboundedRegExp < int > regexp2(regexp);

			CHECK( regexp == regexp2 );

			regexp::UnboundedRegExp < int > regexp3(std::move(regexp));

			CHECK( regexp2 == regexp3 );
		}
		{
			regexp::FormalRegExpSymbol < int > l1 = regexp::FormalRegExpSymbol < int >( 1 );
			regexp::FormalRegExpSymbol < int > l2 = regexp::FormalRegExpSymbol < int >( 2 );

			regexp::FormalRegExpConcatenation < int > con = regexp::FormalRegExpConcatenation < int >(l1, l2);

			regexp::FormalRegExpIteration < int > ite = regexp::FormalRegExpIteration < int >(l1);

			regexp::FormalRegExpAlternation < int > alt = regexp::FormalRegExpAlternation < int >(con, ite);

			regexp::FormalRegExp < int > regexp({1, 2, 3}, regexp::FormalRegExpStructure < int > ( alt ) );

			regexp::FormalRegExp < int > regexp2(regexp);

			CHECK( regexp == regexp2 );

			regexp::FormalRegExp < int > regexp3(std::move(regexp));

			CHECK( regexp2 == regexp3 );
		}
		{
			regexp::FormalRegExpSymbol < int > l1 = regexp::FormalRegExpSymbol < int >( 1 );
			regexp::FormalRegExpSymbol < int > l2 = regexp::FormalRegExpSymbol < int >( 2 );

			regexp::FormalRegExpConcatenation < int > con = regexp::FormalRegExpConcatenation < int >(l1, l2);

			regexp::FormalRegExpIteration < int > ite = regexp::FormalRegExpIteration < int >(l1);

			regexp::FormalRegExpAlternation < int > alt = regexp::FormalRegExpAlternation < int >(con, ite);

			regexp::FormalRegExp < int > regexp({1, 3}, regexp::FormalRegExpStructure < int > ( regexp::FormalRegExpEmpty < int > { } ) );

			CHECK_THROWS_AS ( regexp.setRegExp ( regexp::FormalRegExpStructure < int > ( alt ) ), exception::CommonException );
		}
	}

	SECTION ( "Xml parser" ) {
		regexp::UnboundedRegExpSymbol < int > l1 = regexp::UnboundedRegExpSymbol < int >( 1 );
		regexp::UnboundedRegExpSymbol < int > l2 = regexp::UnboundedRegExpSymbol < int >( 2 );

		regexp::UnboundedRegExpConcatenation < int > con = regexp::UnboundedRegExpConcatenation < int >();
		con.appendElement(l1);
		con.appendElement(l2);

		regexp::UnboundedRegExpIteration < int > ite = regexp::UnboundedRegExpIteration < int >(l1);

		regexp::UnboundedRegExpAlternation < int > alt = regexp::UnboundedRegExpAlternation < int >();
		alt.appendElement(con);
		alt.appendElement(ite);

		regexp::UnboundedRegExp < int > unboundedRegexp({1, 2, 3}, regexp::UnboundedRegExpStructure < int >(alt));

		regexp::UnboundedRegExp < > regexp = core::normalize < regexp::UnboundedRegExp < int > >::eval ( std::move ( unboundedRegexp ) );

		{
			ext::deque<sax::Token> tokens = factory::XmlDataFactory::toTokens(regexp);
			std::string tmp = sax::SaxComposeInterface::composeMemory ( tokens );

			ext::deque<sax::Token> tokens2 = sax::SaxParseInterface::parseMemory ( tmp );
			regexp::UnboundedRegExp < > regexp2 = factory::XmlDataFactory::fromTokens (std::move(tokens2));

			CHECK( regexp == regexp2 );
		}
		{
			std::string tmp = factory::XmlDataFactory::toString(regexp);
			regexp::UnboundedRegExp < > regexp2 = factory::XmlDataFactory::fromString (tmp);

			CHECK( regexp == regexp2 );
		}
	}

	SECTION ( "Order" ) {
		{
			regexp::UnboundedRegExpSymbol < int > s1( 1 );
			regexp::UnboundedRegExpEmpty < int > e1;
			regexp::UnboundedRegExpEpsilon < int > e2;
			regexp::UnboundedRegExpIteration < int > i1(s1);
			regexp::UnboundedRegExpConcatenation < int > a1;
			a1.appendElement(s1);
			a1.appendElement(s1);
			regexp::UnboundedRegExpAlternation < int > c1;
			c1.appendElement(s1);
			c1.appendElement(s1);

			regexp::UnboundedRegExp < int > alt1{regexp::UnboundedRegExpStructure < int >(a1)};
			regexp::UnboundedRegExp < int > con1{regexp::UnboundedRegExpStructure < int >(c1)};
			regexp::UnboundedRegExp < int > ite1{regexp::UnboundedRegExpStructure < int >(i1)};
			regexp::UnboundedRegExp < int > emp1{regexp::UnboundedRegExpStructure < int >(e1)};
			regexp::UnboundedRegExp < int > eps1{regexp::UnboundedRegExpStructure < int >(e2)};
			regexp::UnboundedRegExp < int > sym1{regexp::UnboundedRegExpStructure < int >(s1)};

			CHECK_EXCLUSIVE_OR(alt1 < con1, con1 < alt1);
			CHECK_EXCLUSIVE_OR(alt1 < ite1, ite1 < alt1);
			CHECK_EXCLUSIVE_OR(alt1 < emp1, emp1 < alt1);
			CHECK_EXCLUSIVE_OR(alt1 < eps1, eps1 < alt1);
			CHECK_EXCLUSIVE_OR(alt1 < sym1, sym1 < alt1);

			CHECK_EXCLUSIVE_OR(con1 < ite1, ite1 < con1);
			CHECK_EXCLUSIVE_OR(con1 < emp1, emp1 < con1);
			CHECK_EXCLUSIVE_OR(con1 < eps1, eps1 < con1);
			CHECK_EXCLUSIVE_OR(con1 < sym1, sym1 < con1);

			CHECK_EXCLUSIVE_OR(ite1 < emp1, emp1 < ite1);
			CHECK_EXCLUSIVE_OR(ite1 < eps1, eps1 < ite1);
			CHECK_EXCLUSIVE_OR(ite1 < sym1, sym1 < ite1);

			CHECK_EXCLUSIVE_OR(emp1 < eps1, eps1 < emp1);
			CHECK_EXCLUSIVE_OR(emp1 < sym1, sym1 < emp1);

			CHECK_EXCLUSIVE_OR(eps1 < sym1, sym1 < eps1);

			CHECK_IMPLY( alt1 < con1 && con1 < ite1, alt1 < ite1 );
			CHECK_IMPLY( alt1 < con1 && con1 < emp1, alt1 < emp1 );
			CHECK_IMPLY( alt1 < con1 && con1 < eps1, alt1 < eps1 );
			CHECK_IMPLY( alt1 < con1 && con1 < sym1, alt1 < sym1 );

			CHECK_IMPLY( alt1 < ite1 && ite1 < con1, alt1 < con1 );
			CHECK_IMPLY( alt1 < ite1 && ite1 < emp1, alt1 < emp1 );
			CHECK_IMPLY( alt1 < ite1 && ite1 < eps1, alt1 < eps1 );
			CHECK_IMPLY( alt1 < ite1 && ite1 < sym1, alt1 < sym1 );

			CHECK_IMPLY( alt1 < emp1 && emp1 < con1, alt1 < con1 );
			CHECK_IMPLY( alt1 < emp1 && emp1 < ite1, alt1 < ite1 );
			CHECK_IMPLY( alt1 < emp1 && emp1 < eps1, alt1 < eps1 );
			CHECK_IMPLY( alt1 < emp1 && emp1 < sym1, alt1 < sym1 );

			CHECK_IMPLY( alt1 < eps1 && eps1 < con1, alt1 < con1 );
			CHECK_IMPLY( alt1 < eps1 && eps1 < ite1, alt1 < ite1 );
			CHECK_IMPLY( alt1 < eps1 && eps1 < emp1, alt1 < emp1 );
			CHECK_IMPLY( alt1 < eps1 && eps1 < sym1, alt1 < sym1 );

			CHECK_IMPLY( alt1 < sym1 && sym1 < con1, alt1 < con1 );
			CHECK_IMPLY( alt1 < sym1 && sym1 < ite1, alt1 < ite1 );
			CHECK_IMPLY( alt1 < sym1 && sym1 < emp1, alt1 < emp1 );
			CHECK_IMPLY( alt1 < sym1 && sym1 < eps1, alt1 < eps1 );



			CHECK_IMPLY( con1 < alt1 && alt1 < ite1, con1 < ite1 );
			CHECK_IMPLY( con1 < alt1 && alt1 < emp1, con1 < emp1 );
			CHECK_IMPLY( con1 < alt1 && alt1 < eps1, con1 < eps1 );
			CHECK_IMPLY( con1 < alt1 && alt1 < sym1, con1 < sym1 );

			CHECK_IMPLY( con1 < ite1 && ite1 < alt1, con1 < alt1 );
			CHECK_IMPLY( con1 < ite1 && ite1 < emp1, con1 < emp1 );
			CHECK_IMPLY( con1 < ite1 && ite1 < eps1, con1 < eps1 );
			CHECK_IMPLY( con1 < ite1 && ite1 < sym1, con1 < sym1 );

			CHECK_IMPLY( con1 < emp1 && emp1 < alt1, con1 < alt1 );
			CHECK_IMPLY( con1 < emp1 && emp1 < ite1, con1 < ite1 );
			CHECK_IMPLY( con1 < emp1 && emp1 < eps1, con1 < eps1 );
			CHECK_IMPLY( con1 < emp1 && emp1 < sym1, con1 < sym1 );

			CHECK_IMPLY( con1 < eps1 && eps1 < alt1, con1 < alt1 );
			CHECK_IMPLY( con1 < eps1 && eps1 < ite1, con1 < ite1 );
			CHECK_IMPLY( con1 < eps1 && eps1 < emp1, con1 < emp1 );
			CHECK_IMPLY( con1 < eps1 && eps1 < sym1, con1 < sym1 );

			CHECK_IMPLY( con1 < sym1 && sym1 < alt1, con1 < alt1 );
			CHECK_IMPLY( con1 < sym1 && sym1 < ite1, con1 < ite1 );
			CHECK_IMPLY( con1 < sym1 && sym1 < emp1, con1 < emp1 );
			CHECK_IMPLY( con1 < sym1 && sym1 < eps1, con1 < eps1 );



			CHECK_IMPLY( ite1 < alt1 && alt1 < con1, ite1 < con1 );
			CHECK_IMPLY( ite1 < alt1 && alt1 < emp1, ite1 < emp1 );
			CHECK_IMPLY( ite1 < alt1 && alt1 < eps1, ite1 < eps1 );
			CHECK_IMPLY( ite1 < alt1 && alt1 < sym1, ite1 < sym1 );

			CHECK_IMPLY( ite1 < con1 && con1 < alt1, ite1 < alt1 );
			CHECK_IMPLY( ite1 < con1 && con1 < emp1, ite1 < emp1 );
			CHECK_IMPLY( ite1 < con1 && con1 < eps1, ite1 < eps1 );
			CHECK_IMPLY( ite1 < con1 && con1 < sym1, ite1 < sym1 );

			CHECK_IMPLY( ite1 < emp1 && emp1 < alt1, ite1 < alt1 );
			CHECK_IMPLY( ite1 < emp1 && emp1 < con1, ite1 < con1 );
			CHECK_IMPLY( ite1 < emp1 && emp1 < eps1, ite1 < eps1 );
			CHECK_IMPLY( ite1 < emp1 && emp1 < sym1, ite1 < sym1 );

			CHECK_IMPLY( ite1 < eps1 && eps1 < alt1, ite1 < alt1 );
			CHECK_IMPLY( ite1 < eps1 && eps1 < con1, ite1 < con1 );
			CHECK_IMPLY( ite1 < eps1 && eps1 < emp1, ite1 < emp1 );
			CHECK_IMPLY( ite1 < eps1 && eps1 < sym1, ite1 < sym1 );

			CHECK_IMPLY( ite1 < sym1 && sym1 < alt1, ite1 < alt1 );
			CHECK_IMPLY( ite1 < sym1 && sym1 < con1, ite1 < con1 );
			CHECK_IMPLY( ite1 < sym1 && sym1 < emp1, ite1 < emp1 );
			CHECK_IMPLY( ite1 < sym1 && sym1 < eps1, ite1 < eps1 );



			CHECK_IMPLY( emp1 < alt1 && alt1 < con1, emp1 < con1 );
			CHECK_IMPLY( emp1 < alt1 && alt1 < ite1, emp1 < ite1 );
			CHECK_IMPLY( emp1 < alt1 && alt1 < eps1, emp1 < eps1 );
			CHECK_IMPLY( emp1 < alt1 && alt1 < sym1, emp1 < sym1 );

			CHECK_IMPLY( emp1 < con1 && con1 < alt1, emp1 < alt1 );
			CHECK_IMPLY( emp1 < con1 && con1 < ite1, emp1 < ite1 );
			CHECK_IMPLY( emp1 < con1 && con1 < eps1, emp1 < eps1 );
			CHECK_IMPLY( emp1 < con1 && con1 < sym1, emp1 < sym1 );

			CHECK_IMPLY( emp1 < ite1 && ite1 < alt1, emp1 < alt1 );
			CHECK_IMPLY( emp1 < ite1 && ite1 < con1, emp1 < con1 );
			CHECK_IMPLY( emp1 < ite1 && ite1 < eps1, emp1 < eps1 );
			CHECK_IMPLY( emp1 < ite1 && ite1 < sym1, emp1 < sym1 );

			CHECK_IMPLY( emp1 < eps1 && eps1 < alt1, emp1 < alt1 );
			CHECK_IMPLY( emp1 < eps1 && eps1 < con1, emp1 < con1 );
			CHECK_IMPLY( emp1 < eps1 && eps1 < ite1, emp1 < ite1 );
			CHECK_IMPLY( emp1 < eps1 && eps1 < sym1, emp1 < sym1 );

			CHECK_IMPLY( emp1 < sym1 && sym1 < alt1, emp1 < alt1 );
			CHECK_IMPLY( emp1 < sym1 && sym1 < con1, emp1 < con1 );
			CHECK_IMPLY( emp1 < sym1 && sym1 < ite1, emp1 < ite1 );
			CHECK_IMPLY( emp1 < sym1 && sym1 < eps1, emp1 < eps1 );



			CHECK_IMPLY( eps1 < alt1 && alt1 < con1, eps1 < con1 );
			CHECK_IMPLY( eps1 < alt1 && alt1 < ite1, eps1 < ite1 );
			CHECK_IMPLY( eps1 < alt1 && alt1 < emp1, eps1 < emp1 );
			CHECK_IMPLY( eps1 < alt1 && alt1 < sym1, eps1 < sym1 );

			CHECK_IMPLY( eps1 < con1 && con1 < alt1, eps1 < alt1 );
			CHECK_IMPLY( eps1 < con1 && con1 < ite1, eps1 < ite1 );
			CHECK_IMPLY( eps1 < con1 && con1 < emp1, eps1 < emp1 );
			CHECK_IMPLY( eps1 < con1 && con1 < sym1, eps1 < sym1 );

			CHECK_IMPLY( eps1 < ite1 && ite1 < alt1, eps1 < alt1 );
			CHECK_IMPLY( eps1 < ite1 && ite1 < con1, eps1 < con1 );
			CHECK_IMPLY( eps1 < ite1 && ite1 < emp1, eps1 < emp1 );
			CHECK_IMPLY( eps1 < ite1 && ite1 < sym1, eps1 < sym1 );

			CHECK_IMPLY( eps1 < emp1 && emp1 < alt1, eps1 < alt1 );
			CHECK_IMPLY( eps1 < emp1 && emp1 < con1, eps1 < con1 );
			CHECK_IMPLY( eps1 < emp1 && emp1 < ite1, eps1 < ite1 );
			CHECK_IMPLY( eps1 < emp1 && emp1 < sym1, eps1 < sym1 );

			CHECK_IMPLY( eps1 < sym1 && sym1 < alt1, eps1 < alt1 );
			CHECK_IMPLY( eps1 < sym1 && sym1 < con1, eps1 < con1 );
			CHECK_IMPLY( eps1 < sym1 && sym1 < ite1, eps1 < ite1 );
			CHECK_IMPLY( eps1 < sym1 && sym1 < emp1, eps1 < emp1 );



			CHECK_IMPLY( sym1 < alt1 && alt1 < con1, sym1 < con1 );
			CHECK_IMPLY( sym1 < alt1 && alt1 < ite1, sym1 < ite1 );
			CHECK_IMPLY( sym1 < alt1 && alt1 < emp1, sym1 < emp1 );
			CHECK_IMPLY( sym1 < alt1 && alt1 < eps1, sym1 < eps1 );

			CHECK_IMPLY( sym1 < con1 && con1 < alt1, sym1 < alt1 );
			CHECK_IMPLY( sym1 < con1 && con1 < ite1, sym1 < ite1 );
			CHECK_IMPLY( sym1 < con1 && con1 < emp1, sym1 < emp1 );
			CHECK_IMPLY( sym1 < con1 && con1 < eps1, sym1 < eps1 );

			CHECK_IMPLY( sym1 < ite1 && ite1 < alt1, sym1 < alt1 );
			CHECK_IMPLY( sym1 < ite1 && ite1 < con1, sym1 < con1 );
			CHECK_IMPLY( sym1 < ite1 && ite1 < emp1, sym1 < emp1 );
			CHECK_IMPLY( sym1 < ite1 && ite1 < eps1, sym1 < eps1 );

			CHECK_IMPLY( sym1 < emp1 && emp1 < alt1, sym1 < alt1 );
			CHECK_IMPLY( sym1 < emp1 && emp1 < con1, sym1 < con1 );
			CHECK_IMPLY( sym1 < emp1 && emp1 < ite1, sym1 < ite1 );
			CHECK_IMPLY( sym1 < emp1 && emp1 < eps1, sym1 < eps1 );

			CHECK_IMPLY( sym1 < eps1 && eps1 < alt1, sym1 < alt1 );
			CHECK_IMPLY( sym1 < eps1 && eps1 < con1, sym1 < con1 );
			CHECK_IMPLY( sym1 < eps1 && eps1 < ite1, sym1 < ite1 );
			CHECK_IMPLY( sym1 < eps1 && eps1 < emp1, sym1 < emp1 );
		}
		{
			regexp::UnboundedRegExpSymbol < int > s1( 1 );
			regexp::UnboundedRegExpSymbol < int > s2( 2 );
			regexp::UnboundedRegExpSymbol < int > s3( 3 );

			regexp::UnboundedRegExpEmpty < int > e1;
			regexp::UnboundedRegExpEpsilon < int > e2;

			regexp::UnboundedRegExpIteration < int > i1(s1);
			regexp::UnboundedRegExpIteration < int > i2(s2);
			regexp::UnboundedRegExpIteration < int > i3(s3);

			regexp::UnboundedRegExpAlternation < int > a1;
			a1.appendElement(s1);
			a1.appendElement(s1);
			regexp::UnboundedRegExpAlternation < int > a2;
			a2.appendElement(s1);
			a2.appendElement(s2);
			regexp::UnboundedRegExpAlternation < int > a3;
			a3.appendElement(s1);
			a3.appendElement(s3);
			regexp::UnboundedRegExpAlternation < int > a4;
			a4.appendElement(s2);
			a4.appendElement(s1);
			regexp::UnboundedRegExpAlternation < int > a5;
			a5.appendElement(s2);
			a5.appendElement(s2);
			regexp::UnboundedRegExpAlternation < int > a6;
			a6.appendElement(s2);
			a6.appendElement(s3);
			regexp::UnboundedRegExpAlternation < int > a7;
			a7.appendElement(s3);
			a7.appendElement(s1);
			regexp::UnboundedRegExpAlternation < int > a8;
			a8.appendElement(s3);
			a8.appendElement(s2);
			regexp::UnboundedRegExpAlternation < int > a9;
			a9.appendElement(s3);
			a9.appendElement(s3);

			regexp::UnboundedRegExpConcatenation < int > c1;
			c1.appendElement(s1);
			c1.appendElement(s1);
			regexp::UnboundedRegExpConcatenation < int > c2;
			c2.appendElement(s1);
			c2.appendElement(s2);
			regexp::UnboundedRegExpConcatenation < int > c3;
			c3.appendElement(s1);
			c3.appendElement(s3);
			regexp::UnboundedRegExpConcatenation < int > c4;
			c4.appendElement(s2);
			c4.appendElement(s1);
			regexp::UnboundedRegExpConcatenation < int > c5;
			c5.appendElement(s2);
			c5.appendElement(s2);
			regexp::UnboundedRegExpConcatenation < int > c6;
			c6.appendElement(s2);
			c6.appendElement(s3);
			regexp::UnboundedRegExpConcatenation < int > c7;
			c7.appendElement(s3);
			c7.appendElement(s1);
			regexp::UnboundedRegExpConcatenation < int > c8;
			c8.appendElement(s3);
			c8.appendElement(s2);
			regexp::UnboundedRegExpConcatenation < int > c9;
			c9.appendElement(s3);
			c9.appendElement(s3);

			regexp::UnboundedRegExp < int > alt1{regexp::UnboundedRegExpStructure < int >(a1)};
			regexp::UnboundedRegExp < int > alt2{regexp::UnboundedRegExpStructure < int >(a2)};
			regexp::UnboundedRegExp < int > alt3{regexp::UnboundedRegExpStructure < int >(a3)};
			regexp::UnboundedRegExp < int > alt4{regexp::UnboundedRegExpStructure < int >(a4)};
			regexp::UnboundedRegExp < int > alt5{regexp::UnboundedRegExpStructure < int >(a5)};
			regexp::UnboundedRegExp < int > alt6{regexp::UnboundedRegExpStructure < int >(a6)};
			regexp::UnboundedRegExp < int > alt7{regexp::UnboundedRegExpStructure < int >(a7)};
			regexp::UnboundedRegExp < int > alt8{regexp::UnboundedRegExpStructure < int >(a8)};
			regexp::UnboundedRegExp < int > alt9{regexp::UnboundedRegExpStructure < int >(a9)};

			regexp::UnboundedRegExp < int > con1{regexp::UnboundedRegExpStructure < int >(c1)};
			regexp::UnboundedRegExp < int > con2{regexp::UnboundedRegExpStructure < int >(c2)};
			regexp::UnboundedRegExp < int > con3{regexp::UnboundedRegExpStructure < int >(c3)};
			regexp::UnboundedRegExp < int > con4{regexp::UnboundedRegExpStructure < int >(c4)};
			regexp::UnboundedRegExp < int > con5{regexp::UnboundedRegExpStructure < int >(c5)};
			regexp::UnboundedRegExp < int > con6{regexp::UnboundedRegExpStructure < int >(c6)};
			regexp::UnboundedRegExp < int > con7{regexp::UnboundedRegExpStructure < int >(c7)};
			regexp::UnboundedRegExp < int > con8{regexp::UnboundedRegExpStructure < int >(c8)};
			regexp::UnboundedRegExp < int > con9{regexp::UnboundedRegExpStructure < int >(c9)};

			regexp::UnboundedRegExp < int > ite1{regexp::UnboundedRegExpStructure < int >(i1)};
			regexp::UnboundedRegExp < int > ite2{regexp::UnboundedRegExpStructure < int >(i2)};
			regexp::UnboundedRegExp < int > ite3{regexp::UnboundedRegExpStructure < int >(i3)};

			regexp::UnboundedRegExp < int > emp1{regexp::UnboundedRegExpStructure < int >(e1)};
			regexp::UnboundedRegExp < int > eps1{regexp::UnboundedRegExpStructure < int >(e2)};

			regexp::UnboundedRegExp < int > sym1{regexp::UnboundedRegExpStructure < int >(s1)};
			regexp::UnboundedRegExp < int > sym2{regexp::UnboundedRegExpStructure < int >(s2)};
			regexp::UnboundedRegExp < int > sym3{regexp::UnboundedRegExpStructure < int >(s3)};



			CHECK(alt1 == alt1);
			CHECK(alt1 < alt2);
			CHECK(alt1 < alt3);
			CHECK(alt1 < alt4);
			CHECK(alt1 < alt5);
			CHECK(alt1 < alt6);
			CHECK(alt1 < alt7);
			CHECK(alt1 < alt8);
			CHECK(alt1 < alt9);

			CHECK(alt2 > alt1);
			CHECK(alt2 == alt2);
			CHECK(alt2 < alt3);
			CHECK(alt2 < alt4);
			CHECK(alt2 < alt5);
			CHECK(alt2 < alt6);
			CHECK(alt2 < alt7);
			CHECK(alt2 < alt8);
			CHECK(alt2 < alt9);

			CHECK(alt3 > alt1);
			CHECK(alt3 > alt2);
			CHECK(alt3 == alt3);
			CHECK(alt3 < alt4);
			CHECK(alt3 < alt5);
			CHECK(alt3 < alt6);
			CHECK(alt3 < alt7);
			CHECK(alt3 < alt8);
			CHECK(alt3 < alt9);

			CHECK(alt4 > alt1);
			CHECK(alt4 > alt2);
			CHECK(alt4 > alt3);
			CHECK(alt4 == alt4);
			CHECK(alt4 < alt5);
			CHECK(alt4 < alt6);
			CHECK(alt4 < alt7);
			CHECK(alt4 < alt8);
			CHECK(alt4 < alt9);

			CHECK(alt5 > alt1);
			CHECK(alt5 > alt2);
			CHECK(alt5 > alt3);
			CHECK(alt5 > alt4);
			CHECK(alt5 == alt5);
			CHECK(alt5 < alt6);
			CHECK(alt5 < alt7);
			CHECK(alt5 < alt8);
			CHECK(alt5 < alt9);

			CHECK(alt6 > alt1);
			CHECK(alt6 > alt2);
			CHECK(alt6 > alt3);
			CHECK(alt6 > alt4);
			CHECK(alt6 > alt5);
			CHECK(alt6 == alt6);
			CHECK(alt6 < alt7);
			CHECK(alt6 < alt8);
			CHECK(alt6 < alt9);

			CHECK(alt7 > alt1);
			CHECK(alt7 > alt2);
			CHECK(alt7 > alt3);
			CHECK(alt7 > alt4);
			CHECK(alt7 > alt5);
			CHECK(alt7 > alt6);
			CHECK(alt7 == alt7);
			CHECK(alt7 < alt8);
			CHECK(alt7 < alt9);

			CHECK(alt8 > alt1);
			CHECK(alt8 > alt2);
			CHECK(alt8 > alt3);
			CHECK(alt8 > alt4);
			CHECK(alt8 > alt5);
			CHECK(alt8 > alt6);
			CHECK(alt8 > alt7);
			CHECK(alt8 == alt8);
			CHECK(alt8 < alt9);

			CHECK(alt9 > alt1);
			CHECK(alt9 > alt2);
			CHECK(alt9 > alt3);
			CHECK(alt9 > alt4);
			CHECK(alt9 > alt5);
			CHECK(alt9 > alt6);
			CHECK(alt9 > alt7);
			CHECK(alt9 > alt8);
			CHECK(alt9 == alt9);



			CHECK(con1 == con1);
			CHECK(con1 < con2);
			CHECK(con1 < con3);
			CHECK(con1 < con4);
			CHECK(con1 < con5);
			CHECK(con1 < con6);
			CHECK(con1 < con7);
			CHECK(con1 < con8);
			CHECK(con1 < con9);

			CHECK(con2 > con1);
			CHECK(con2 == con2);
			CHECK(con2 < con3);
			CHECK(con2 < con4);
			CHECK(con2 < con5);
			CHECK(con2 < con6);
			CHECK(con2 < con7);
			CHECK(con2 < con8);
			CHECK(con2 < con9);

			CHECK(con3 > con1);
			CHECK(con3 > con2);
			CHECK(con3 == con3);
			CHECK(con3 < con4);
			CHECK(con3 < con5);
			CHECK(con3 < con6);
			CHECK(con3 < con7);
			CHECK(con3 < con8);
			CHECK(con3 < con9);

			CHECK(con4 > con1);
			CHECK(con4 > con2);
			CHECK(con4 > con3);
			CHECK(con4 == con4);
			CHECK(con4 < con5);
			CHECK(con4 < con6);
			CHECK(con4 < con7);
			CHECK(con4 < con8);
			CHECK(con4 < con9);

			CHECK(con5 > con1);
			CHECK(con5 > con2);
			CHECK(con5 > con3);
			CHECK(con5 > con4);
			CHECK(con5 == con5);
			CHECK(con5 < con6);
			CHECK(con5 < con7);
			CHECK(con5 < con8);
			CHECK(con5 < con9);

			CHECK(con6 > con1);
			CHECK(con6 > con2);
			CHECK(con6 > con3);
			CHECK(con6 > con4);
			CHECK(con6 > con5);
			CHECK(con6 == con6);
			CHECK(con6 < con7);
			CHECK(con6 < con8);
			CHECK(con6 < con9);

			CHECK(con7 > con1);
			CHECK(con7 > con2);
			CHECK(con7 > con3);
			CHECK(con7 > con4);
			CHECK(con7 > con5);
			CHECK(con7 > con6);
			CHECK(con7 == con7);
			CHECK(con7 < con8);
			CHECK(con7 < con9);

			CHECK(con8 > con1);
			CHECK(con8 > con2);
			CHECK(con8 > con3);
			CHECK(con8 > con4);
			CHECK(con8 > con5);
			CHECK(con8 > con6);
			CHECK(con8 > con7);
			CHECK(con8 == con8);
			CHECK(con8 < con9);

			CHECK(con9 > con1);
			CHECK(con9 > con2);
			CHECK(con9 > con3);
			CHECK(con9 > con4);
			CHECK(con9 > con5);
			CHECK(con9 > con6);
			CHECK(con9 > con7);
			CHECK(con9 > con8);
			CHECK(con9 == con9);


			CHECK(ite1 == ite1);
			CHECK(ite1 < ite2);
			CHECK(ite1 < ite3);

			CHECK(ite2 > ite1);
			CHECK(ite2 == ite2);
			CHECK(ite2 < ite3);

			CHECK(ite3 > ite1);
			CHECK(ite3 > ite2);
			CHECK(ite3 == ite3);

			CHECK(emp1 == emp1);

			CHECK(eps1 == eps1);

			CHECK(sym1 == sym1);
			CHECK(sym1 < sym2);
			CHECK(sym1 < sym3);

			CHECK(sym2 > sym1);
			CHECK(sym2 == sym2);
			CHECK(sym2 < sym3);

			CHECK(sym3 > sym1);
			CHECK(sym3 > sym2);
			CHECK(sym3 == sym3);
		}
	}
}
