/*
 * Alternation.h
 *
 *  Created on: Nov 23, 2013
 *      Author: Martin Zak
 */

#ifndef ALTERNATION_H_
#define ALTERNATION_H_

#include <vector>
#include "RegExpElement.h"

namespace regexp {

/**
 * Represents alternation operator in the regular expression. Contains list of RegExpElement
 * as operands of the operator.
 */
class Alternation: public RegExpElement, public std::element<Alternation, RegExpElement::visitor_type> {
protected:
	/**
	 * @copydoc RegExpElement::clone() const
	 */
	virtual RegExpElement* clone() const;

	std::vector<RegExpElement*> elements;
public:
	Alternation();
	Alternation(const Alternation& other);
	Alternation(Alternation&& other) noexcept;
	Alternation& operator =(const Alternation& other);
	Alternation& operator =(Alternation&& other) noexcept;
	virtual ~Alternation() noexcept;

	/**
	 * @return list of operands
	 */
	std::vector<RegExpElement*>& getElements();

	/**
	 * @return list of operands
	 */
	const std::vector<RegExpElement*>& getElements() const;

	virtual bool operator<(const RegExpElement&) const;
	virtual bool operator==(const RegExpElement&) const;
	virtual bool operator>(const RegExpElement&) const;

	virtual bool operator<(const Concatenation&) const;
	virtual bool operator<(const Alternation&) const;
	virtual bool operator==(const Alternation&) const;
	
	/**
	 * @copydoc RegExpElement::operator>>() const
	 */
	virtual void operator>>(std::ostream& out) const;

	/**
	 * @copydoc RegExpElement::getAlphabet() const
	 */
	virtual void getAlphabet( std::set<alphabet::Symbol> & alphabet ) const;
	
	/**
	 * @copydoc RegExpElement::containsEmptyString() const
	 */
	virtual bool containsEmptyString() const;

	/**
	 * @copydoc RegExpElement::isEmpty() const
	 */
	virtual bool isEmpty() const;
};

} /* namespace regexp */

#endif /* ALTERNATION_H_ */