0

I am implementing a container class that ensures uniqueness among the elements and restricts insertion and deletion to only the end only. Somewhat like a stack of unique elements or an ordered set with functions like push and pop. And it must also have a fixed maximum size.

template <class T, int max_size>
class FixedSizedUniqueStack
{
    std::vector<T> m_vec;
    std::unordered_set<T> m_uset;
public:
    FixedSizedUniqueStack():m_vec(max_size),m_uset(){}
    bool push(T x)
    {
        bool success = true;
        if( m_uset.insert(x).second ) m_vec.push_back(x);
        else success = false;
        return success;
    }
    void pop()
    {
        if(m_vec.size() > 0)
        {
            m_uset.erase(m_vec.back());
            m_vec.pop_back();
        }
    }
    T back()
    {
        return m_vec.back();
    }
};

1 Answers1

0
#include <vector>
#include <unordered_set>
#include <initializer_list>
template <class T, int max_size>
class FixedSizedUniqueStack:  public std::initializer_list<T>
{
protected:
    std::vector<T> m_vec;
    std::unordered_set<T> m_uset;
public:
    FixedSizedUniqueStack():m_vec(),m_uset(){}
    FixedSizedUniqueStack( const FixedSizedUniqueStack &x)
    {
        m_vec = x.m_vec;
        m_uset = x.m_uset;
    }
    FixedSizedUniqueStack& operator= ( const FixedSizedUniqueStack &x)
    {
        if (this != &x)
        {
            m_vec = x.m_vec;
            m_uset = x.m_uset;
        }
        return *this;
    }
    auto size() const -> decltype(m_vec.size())
    {
        return m_vec.size();
    }
    int push(const std::initializer_list<T>& il)
    {
        int errors = 0;
        for (auto x: il)
        {
            if( push(x) )
            {
                errors++;
            }
        }
        return errors;
    }
    int push(const T& x)
    {
        int error =0;
        if(m_vec.size() < max_size)
        {
            if( x < start)
            {
                error  = 1;
            }
            else if( x > stop)
            {
                error = 2;
            }
            else
            {
                if( m_uset.insert(x).second ) m_vec.push_back(x);
                else error = 3;
            }
        }
        else
        {
            error = 4;
        }
        return error;
    }
    void pop()
    {
        if(!m_vec.empty())
        {
            m_uset.erase(m_vec.back());
            m_vec.pop_back();
        }
    }
    T back()
    {
        return m_vec.back();
    }
    auto cbegin() const -> decltype(m_vec.cbegin())
    {
        return m_vec.cbegin();
    }
    auto cend() const -> decltype(m_vec.cend())
    {
        return m_vec.cend();
    }

    auto begin() const -> decltype(m_vec.begin())
    {
        return m_vec.begin();
    }
    auto end() const -> decltype(m_vec.end())
    {
        return m_vec.end();
    }

    auto empty() ->decltype(m_vec.empty())
    {
        return m_vec.empty();
    }