#ifndef _INCLUDED_FIRSTSET_
#define _INCLUDED_FIRSTSET_

#include <set>
#include <iosfwd>

#include "../element/element.h"

class FirstSet: private std::set<Element const *>
{
    using Inherit = std::set<Element const *>;

    friend std::ostream &operator<<(std::ostream &out, FirstSet const &fset);

    bool d_epsilon;             // true if epsilon (the empty set indicator) 
                                // is in {First}

    protected:
        using Baseclass = std::set<Element const *>;
        FirstSet(Element const **begin, Element const **end);

    public:
        using Inherit::find;
        using Inherit::begin;
        using Inherit::end;
        using Inherit::size;

        FirstSet();
        FirstSet(Element const *terminal);

        FirstSet &operator+=(FirstSet const &other);
        FirstSet &operator+=(std::set<Element const *> const &terminalSet);

        bool empty() const;
        bool hasEpsilon() const;
        bool operator==(FirstSet const &other) const;

        size_t setSize() const;

        void addEpsilon();
        void rmEpsilon();

        std::set<Element const *> const &set() const;

    private:
        std::ostream &insert(std::ostream &out) const;
};

#include "firstset.f"

#endif
