#include <catch2/catch.hpp> #include <alib/compare> #include <alib/tree> namespace { class RegExpElement : public ext::BaseNode < RegExpElement > { public: virtual RegExpElement * clone ( ) const & = 0; virtual RegExpElement * clone ( ) && = 0; }; class RegExpAlternation : public ext::VararyNode < RegExpElement > { public: RegExpAlternation ( RegExpElement && left, RegExpElement && right ) : VararyNode < RegExpElement > ( ) { pushBackChild ( std::move ( left ) ); pushBackChild ( std::move ( right ) ); } RegExpElement * clone ( ) const & override { return new RegExpAlternation ( * this ); } RegExpElement * clone ( ) && override { return new RegExpAlternation ( std::move ( * this ) ); } }; class RegExpConcatenation : public ext::BinaryNode < RegExpElement > { public: RegExpConcatenation ( RegExpElement && left, RegExpElement && right ) : BinaryNode < RegExpElement > ( std::move ( left ), std::move ( right ) ) { } RegExpElement * clone ( ) const & override { return new RegExpConcatenation ( * this ); } RegExpElement * clone ( ) && override { return new RegExpConcatenation ( std::move ( * this ) ); } }; class RegExpIteration : public ext::UnaryNode < RegExpElement > { public: RegExpIteration ( RegExpElement && element ) : UnaryNode < RegExpElement > ( std::move ( element ) ) { } RegExpIteration ( const RegExpElement & element ) : UnaryNode < RegExpElement > ( ext::move_copy ( element ) ) { } RegExpElement * clone ( ) const & override { return new RegExpIteration ( * this ); } RegExpElement * clone ( ) && override { return new RegExpIteration ( std::move ( * this ) ); } }; class RegExpSymbol : public ext::NullaryNode < RegExpElement > { char m_symbol; public: RegExpSymbol ( char symbol ) : m_symbol ( symbol ) { } RegExpElement * clone ( ) const & override { return new RegExpSymbol ( * this ); } RegExpElement * clone ( ) && override { return new RegExpSymbol ( std::move ( * this ) ); } char getSymbol ( ) const { return m_symbol; } }; class RegExpEpsilon : public ext::NullaryNode < RegExpElement > { public: RegExpElement * clone ( ) const & override { return new RegExpEpsilon ( * this ); } RegExpElement * clone ( ) && override { return new RegExpEpsilon ( std::move ( * this ) ); } }; class RegExpEmpty : public ext::NullaryNode < RegExpElement > { public: RegExpElement * clone ( ) const & override { return new RegExpEmpty ( * this ); } RegExpElement * clone ( ) && override { return new RegExpEmpty ( std::move ( * this ) ); } }; /* class UnrankedTreeNode : public ext::VararyNode < UnrankedTreeNode, ext::BaseNode < UnrankedTreeNode > > { char m_symbol; public: UnrankedTreeNode ( char symbol, ext::ptr_vector < UnrankedTreeNode > c ) : VararyNode < UnrankedTreeNode, ext::BaseNode < UnrankedTreeNode > > ( std::move ( c ) ), m_symbol ( symbol ) { } char getSymbol ( ) const { return m_symbol; } }; class UnrankedTree { UnrankedTreeNode root; }; class RankedTreeNode : public ext::FixedaryNode < RankedTreeNode, ext::BaseNode < RankedTreeNode > > { char m_symbol; unsigned m_arity; public: RankedTreeNode ( char symbol, unsigned arity, ext::ptr_vector < RankedTreeNode > c ) : FixedaryNode < RankedTreeNode, ext::BaseNode < RankedTreeNode > > ( std::move ( c ) ), m_symbol ( symbol ), m_arity ( arity ) { if ( getChildren ( ).size ( ) != m_arity ) throw "Arity != size"; } char getSymbol ( ) const { return m_symbol; } }; class RankedTree { RankedTreeNode root; };*/ } TEST_CASE ( "TreeBase", "[unit][std][container]" ) { SECTION ( "RegExps" ) { RegExpIteration iter = RegExpEmpty ( ); CHECK ( iter.getChild ( ).getParent ( ) == & iter ); RegExpIteration iter2 = iter; RegExpIteration iter3 = iter2; CHECK ( iter3.getChild ( ).getParent ( ) == & iter3 ); iter3 = iter; RegExpIteration iter4 = RegExpEpsilon ( ); iter3 = iter4; CHECK ( iter3.getChild ( ).getParent ( ) == & iter3 ); RegExpSymbol s ( 'x' ); const RegExpSymbol & sr = s; sr.getChildren ( ); RegExpAlternation alter ( std::move ( iter ), std::move ( iter2 ) ); for ( const RegExpElement & element : alter.getChildren ( ) ) { CHECK ( element.getParent ( ) == & alter ); } } /* SECTION ( "RankedTree" ) { RankedTreeNode node ( 'a', 1, { RankedTreeNode ( 'b', 1, { RankedTreeNode ( 'c', 0, { } ) } ) } ); const RankedTreeNode & cnode = node; for ( const RankedTreeNode & child : cnode.getChildren ( ) ) CHECK ( child.getParent ( ) == & cnode ); } SECTION ( "UnrankedTree" ) { }*/ }