Raw File
slang-array-view.h
#ifndef SLANG_CORE_ARRAY_VIEW_H
#define SLANG_CORE_ARRAY_VIEW_H

#include "slang-common.h"

namespace Slang
{

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ConstArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    template<typename T>
    class ConstArrayView
    {
    public:
        typedef ConstArrayView ThisType;

        SLANG_FORCE_INLINE const T* begin() const { return m_buffer; }
        
        SLANG_FORCE_INLINE const T* end() const { return m_buffer + m_count; }
        
        SLANG_FORCE_INLINE Count getCount() const { return m_count; }

        SLANG_FORCE_INLINE const T& operator [](Index idx) const
        {
            SLANG_ASSERT(idx >= 0 && idx < m_count);
            return m_buffer[idx];
        }
        
        SLANG_FORCE_INLINE const T* getBuffer() const { return m_buffer; }
        
        template<typename T2>
        Index indexOf(const T2& val) const
        {
            for (Index i = 0; i < m_count; i++)
            {
                if (m_buffer[i] == val)
                    return i;
            }
            return -1;
        }

        template<typename T2>
        Index lastIndexOf(const T2& val) const
        {
            for (Index i = m_count - 1; i >= 0; i--)
            {
                if (m_buffer[i] == val)
                    return i;
            }
            return -1;
        }

        template<typename Func>
        Index findFirstIndex(const Func& predicate) const
        {
            for (Index i = 0; i < m_count; i++)
            {
                if (predicate(m_buffer[i]))
                    return i;
            }
            return -1;
        }

        template<typename Func>
        Index findLastIndex(const Func& predicate) const
        {
            for (Index i = m_count - 1; i >= 0; i--)
            {
                if (predicate(m_buffer[i]))
                    return i;
            }
            return -1;
        }

        bool containsMemory(const ThisType& rhs) const
        {
            return rhs.getBuffer() >= getBuffer() && rhs.end() <= end(); 
        }

        bool operator==(const ThisType& rhs) const
        {
            if (&rhs == this)
            {
                return true;
            }
            const Count count = getCount();
            if (count != rhs.getCount())
            {
                return false;
            }
            const T* thisEle = getBuffer();
            const T* rhsEle = rhs.getBuffer();
            for (Index i = 0; i < count; ++i)
            {
                if (thisEle[i] != rhsEle[i])
                {
                    return false;
                }
            }
            return true;
        }
        SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }

        ThisType head(Index index) const 
        {
            SLANG_ASSERT(index >= 0 && index <= m_count);
            return ThisType(m_buffer, index); 
        }
        ThisType tail(Index index) const
        {
            SLANG_ASSERT(index >= 0 && index <= m_count);
            return ThisType(m_buffer + index, m_count - index);
        }

        ConstArrayView() :
            m_buffer(nullptr),
            m_count(0)
        {
        }

        ConstArrayView(const T* buffer, Count count) :
            m_buffer(const_cast<T*>(buffer)),
            m_count(count)
        {
        }

    protected:
        ConstArrayView(T* buffer, Count count) :
            m_buffer(buffer),
            m_count(count)
        {
        }

        T* m_buffer;        ///< Note that this isn't const, as is used for derived class ArrayView also
        Count m_count;
    };

    template<typename T>
    ConstArrayView<T> makeConstArrayViewSingle(const T& obj)
    {
        return ConstArrayView<T>(&obj, 1);
    } 

    template<typename T>
    ConstArrayView<T> makeConstArrayView(const T* buffer, Count count)
    {
        return ConstArrayView<T>(buffer, count);
    }

    template<typename T, size_t N>
    ConstArrayView<T> makeConstArrayView(const T (&arr)[N])
    {
        return ConstArrayView<T>(arr, Index(N));
    }


    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    template<typename T>
    class ArrayView: public ConstArrayView<T>
    {
    public:
        typedef ArrayView ThisType;

        typedef ConstArrayView<T> Super;
        
        using Super::m_buffer;
        using Super::m_count;

        using Super::begin;
        T* begin() { return m_buffer; }

        using Super::end;
        T* end() { return m_buffer + m_count; }
        
        using Super::head;
        using Super::tail;

        using Super::operator[];
        inline T& operator [](Index idx)
        {
            SLANG_ASSERT(idx >= 0 && idx < m_count);
            return m_buffer[idx];
        }

        using Super::getBuffer;
        inline T* getBuffer() { return m_buffer; }

        ThisType head(Index index)
        {
            SLANG_ASSERT(index >= 0 && index <= m_count);
            return ThisType(m_buffer, index);
        }
        ThisType tail(Index index)
        {
            SLANG_ASSERT(index >= 0 && index <= m_count);
            return ThisType(m_buffer + index, m_count - index);
        }

        ArrayView() : Super() {}
        ArrayView(T* buffer, Index size) :Super(buffer, size) {}
    };

    template<typename T>
    ArrayView<T> makeArrayViewSingle(T& obj)
    {
        return ArrayView<T>(&obj, 1);
    } 
        
    template<typename T>
    ArrayView<T> makeArrayView(T* buffer, Count count)
    {
        return ArrayView<T>(buffer, count);
    }

    template<typename T, size_t N>
    ArrayView<T> makeArrayView(T (&arr)[N])
    {
        return ArrayView<T>(arr, Count(N));
    }


}

#endif
back to top