#ifndef SLANG_CORE_ARRAY_VIEW_H #define SLANG_CORE_ARRAY_VIEW_H #include "slang-common.h" namespace Slang { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ConstArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!! template 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 Index indexOf(const T2& val) const { for (Index i = 0; i < m_count; i++) { if (m_buffer[i] == val) return i; } return -1; } template 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 Index findFirstIndex(const Func& predicate) const { for (Index i = 0; i < m_count; i++) { if (predicate(m_buffer[i])) return i; } return -1; } template 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(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 ConstArrayView makeConstArrayViewSingle(const T& obj) { return ConstArrayView(&obj, 1); } template ConstArrayView makeConstArrayView(const T* buffer, Count count) { return ConstArrayView(buffer, count); } template ConstArrayView makeConstArrayView(const T (&arr)[N]) { return ConstArrayView(arr, Index(N)); } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! template class ArrayView: public ConstArrayView { public: typedef ArrayView ThisType; typedef ConstArrayView 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 ArrayView makeArrayViewSingle(T& obj) { return ArrayView(&obj, 1); } template ArrayView makeArrayView(T* buffer, Count count) { return ArrayView(buffer, count); } template ArrayView makeArrayView(T (&arr)[N]) { return ArrayView(arr, Count(N)); } } #endif