subset.hpp

Back to Miscellaneous stuff

pastel/sys/

#ifndef PASTELSYS_SUBSET_HPP
#define PASTELSYS_SUBSET_HPP

#include "pastel/sys/subset.h"
#include "pastel/sys/ensure.h"

namespace Pastel
{

    inline Subset::Subset()
        : data_()
        , elements_()
    {
    }

    inline Subset::Subset(integer size, integer elements)
        : data_()
        , elements_(elements)
    {
        ENSURE_OP(size, >=, 0);
        ENSURE_OP(elements, >=, 0);
        ENSURE_OP(size, <=, elements);

        setSize(size);
    }

    inline void Subset::swap(Subset& that)
    {
        data_.swap(that.data_);
        std::swap(elements_, that.elements_);
    }

    inline void Subset::first()
    {
        integer size = data_.size();
        for (integer i = 0;i < size;++i)
        {
            data_[i] = i;
        }
    }

    inline bool Subset::next()
    {
        integer size = data_.size();

        if (size == 0)
        {
            return false;
        }

        if (data_[size - 1] + 1 < elements_)
        {
            ++data_[size - 1];
        }
        else
        {
            integer j = size - 2;
            while(j >= 0)
            {
                if (data_[j] + 1 < data_[j + 1])
                {
                    break;
                }

                --j;
            }

            if (j == -1)
            {
                // This is the last data_.
                return false;
            }

            integer value = data_[j] + 1;
            while(j < size)
            {
                data_[j] = value;
                ++value;
                ++j;
            }
        }

        return true;
    }

    inline void Subset::setSize(integer size)
    {
        ENSURE_OP(size, <=, elements_);

        data_.clear();
        data_.reserve(size);

        for (integer i = 0;i < size;++i)
        {
            data_.push_back(i);
        }
    }

    inline void Subset::setSize(integer size, integer elements)
    {
        ENSURE_OP(size, >=, 0);
        ENSURE_OP(elements, >=, 0);
        ENSURE_OP(size, <=, elements);

        elements_ = elements;
        setSize(size);
    }

    inline integer Subset::size() const
    {
        return data_.size();
    }

    inline integer Subset::elements() const
    {
        return elements_;
    }

    inline integer Subset::operator[](integer index) const
    {

        PENSURE2(index >= 0 && index < size(), index, size());
        return data_[index];
    }

}

#endif