From 9b3e768bceae562deeb330067f3ef5febc2e5244 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 11 Feb 2020 16:16:43 -0500 Subject: Small improvements around List (#1216) * * Improved fastRemoveAt * Fixed off by one bug * Fixed const safeness with List<> * Made List begin and end const safe. * Revert to previous RefPtr usage. * Fix bug with casting. * Tabs -> spaces. Small fixes/improvements to List. * Improve comment on List. * hasContent -> isNonEmpty --- source/core/slang-list.h | 1005 +++++++++++++++++---------------- source/slang/slang-check-decl.cpp | 8 +- source/slang/slang-check-overload.cpp | 7 +- source/slang/slang-lexer.cpp | 8 +- source/slang/slang-lexer.h | 24 +- source/slang/slang-syntax.h | 37 +- 6 files changed, 549 insertions(+), 540 deletions(-) diff --git a/source/core/slang-list.h b/source/core/slang-list.h index 0affbfd66..28180ce4f 100644 --- a/source/core/slang-list.h +++ b/source/core/slang-list.h @@ -15,22 +15,22 @@ namespace Slang { - template - class Initializer - { - - }; - - template - class Initializer - { - public: - static void initialize(T* buffer, int size) - { - for (int i = 0; i + class Initializer + { + + }; + + template + class Initializer + { + public: + static void initialize(T* buffer, int size) + { + for (int i = 0; i class Initializer { @@ -43,126 +43,136 @@ namespace Slang } }; - template - class AllocateMethod - { - public: - static inline T* allocateArray(Index count) - { - TAllocator allocator; - T * rs = (T*)allocator.allocate(count * sizeof(T)); - Initializer::value>::initialize(rs, count); - return rs; - } - static inline void deallocateArray(T* ptr, Index count) - { - TAllocator allocator; - if (!std::is_trivially_destructible::value) - { - for (Index i = 0; i < count; i++) - ptr[i].~T(); - } - allocator.deallocate(ptr); - } - }; - - template - class AllocateMethod - { - public: - static inline T* allocateArray(Index count) - { - return new T[count]; - } - static inline void deallocateArray(T* ptr, Index /*bufferSize*/) - { - delete [] ptr; - } - }; - - - template - class List - { + template + class AllocateMethod + { + public: + static inline T* allocateArray(Index count) + { + TAllocator allocator; + T * rs = (T*)allocator.allocate(count * sizeof(T)); + Initializer::value>::initialize(rs, count); + return rs; + } + static inline void deallocateArray(T* ptr, Index count) + { + TAllocator allocator; + if (!std::is_trivially_destructible::value) + { + for (Index i = 0; i < count; i++) + ptr[i].~T(); + } + allocator.deallocate(ptr); + } + }; + + template + class AllocateMethod + { + public: + static inline T* allocateArray(Index count) + { + return new T[count]; + } + static inline void deallocateArray(T* ptr, Index /*bufferSize*/) + { + delete [] ptr; + } + }; + + // List is container of values of a type held consecutively in memory (much like std::vector) + // + // Note that in this implementation, the underlying memory is backed via an allocation of T[capacity] + // This means that all values have to be in a valid state *even if they are not used* (ie indices >= m_count must be valid) + // + // Also note this implementation does not necessarily 'initialize' an element which is no longer used, + // and this may lead to surprising behavior. Say the list contains a single smart pointer, and the last element is removed (say with removeLast). + // The smart pointer will *not* be released. The smart pointer will be released if the that index is used (via say an add) or + // the List goes out of scope. + template + class List + { private: static const Index kInitialCount = 16; - public: - List() - : m_buffer(nullptr), m_count(0), m_capacity(0) - { - } - template - List(const T& val, Args... args) - { - _init(val, args...); - } - List(const List& list) - : m_buffer(nullptr), m_count(0), m_capacity(0) - { - this->operator=(list); - } - List(List&& list) - : m_buffer(nullptr), m_count(0), m_capacity(0) - { - this->operator=(static_cast&&>(list)); - } - static List makeRepeated(const T& val, Index count) - { - List rs; - rs.setCount(count); - for (Index i = 0; i < count; i++) - rs[i] = val; - return rs; - } - ~List() - { + public: + List() + : m_buffer(nullptr), m_count(0), m_capacity(0) + { + } + template + List(const T& val, Args... args) + { + _init(val, args...); + } + List(const List& list) + : m_buffer(nullptr), m_count(0), m_capacity(0) + { + this->operator=(list); + } + List(List&& list) + : m_buffer(nullptr), m_count(0), m_capacity(0) + { + this->operator=(static_cast&&>(list)); + } + static List makeRepeated(const T& val, Index count) + { + List rs; + rs.setCount(count); + for (Index i = 0; i < count; i++) + rs[i] = val; + return rs; + } + ~List() + { _deallocateBuffer(); - } - List& operator=(const List& list) - { - clearAndDeallocate(); - addRange(list); - return *this; - } - - List& operator=(List&& list) - { + } + List& operator=(const List& list) + { + clearAndDeallocate(); + addRange(list); + return *this; + } + + List& operator=(List&& list) + { // Could just do a swap here, and memory would be freed on rhs dtor _deallocateBuffer(); - m_count = list.m_count; - m_capacity = list.m_capacity; - m_buffer = list.m_buffer; - - list.m_buffer = nullptr; - list.m_count = 0; - list.m_capacity = 0; - return *this; - } - - // TODO(JS): These should be made const safe but some other code depends on this behavior for now. - T* begin() const { return m_buffer; } - T* end() const { return m_buffer + m_count; } - - const T& getFirst() const - { - SLANG_ASSERT(m_count > 0); - return m_buffer[0]; - } + m_count = list.m_count; + m_capacity = list.m_capacity; + m_buffer = list.m_buffer; + + list.m_buffer = nullptr; + list.m_count = 0; + list.m_capacity = 0; + return *this; + } - const T& getLast() const - { - SLANG_ASSERT(m_count > 0); - return m_buffer[m_count-1]; - } + const T* begin() const { return m_buffer; } + const T* end() const { return m_buffer + m_count; } + + T* begin() { return m_buffer; } + T* end() { return m_buffer + m_count; } + const T& getFirst() const + { + SLANG_ASSERT(m_count > 0); + return m_buffer[0]; + } + T& getFirst() { SLANG_ASSERT(m_count > 0); return m_buffer[0]; } + const T& getLast() const + { + SLANG_ASSERT(m_count > 0); + return m_buffer[m_count - 1]; + } + T& getLast() { SLANG_ASSERT(m_count > 0); @@ -175,180 +185,177 @@ namespace Slang m_count--; } - inline void swapWith(List& other) - { - T* buffer = m_buffer; - m_buffer = other.m_buffer; - other.m_buffer = buffer; - - auto bufferSize = m_capacity; - m_capacity = other.m_capacity; - other.m_capacity = bufferSize; - - auto count = m_count; - m_count = other.m_count; - other.m_count = count; - } - - T* detachBuffer() - { - T* rs = m_buffer; - m_buffer = nullptr; - m_count = 0; - m_capacity = 0; - return rs; - } - - inline ArrayView getArrayView() const - { - return ArrayView(m_buffer, m_count); - } - - inline ArrayView getArrayView(Index start, Index count) const - { + inline void swapWith(List& other) + { + T* buffer = m_buffer; + m_buffer = other.m_buffer; + other.m_buffer = buffer; + + auto bufferSize = m_capacity; + m_capacity = other.m_capacity; + other.m_capacity = bufferSize; + + auto count = m_count; + m_count = other.m_count; + other.m_count = count; + } + + T* detachBuffer() + { + T* rs = m_buffer; + m_buffer = nullptr; + m_count = 0; + m_capacity = 0; + return rs; + } + + inline ArrayView getArrayView() const + { + return ArrayView(m_buffer, m_count); + } + + inline ArrayView getArrayView(Index start, Index count) const + { SLANG_ASSERT(start >= 0 && count >= 0 && start + count <= m_count); - return ArrayView(m_buffer + start, count); - } - - void add(T&& obj) - { - if (m_capacity < m_count + 1) - { - Index newBufferSize = kInitialCount; - if (m_capacity) - newBufferSize = (m_capacity << 1); - - reserve(newBufferSize); - } - m_buffer[m_count++] = static_cast(obj); - } - - void add(const T& obj) - { - if (m_capacity < m_count + 1) - { - Index newBufferSize = kInitialCount; - if (m_capacity) - newBufferSize = (m_capacity << 1); - - reserve(newBufferSize); - } - m_buffer[m_count++] = obj; - - } + return ArrayView(m_buffer + start, count); + } + + void _maybeReserveForAdd() + { + if (m_capacity <= m_count) + { + Index newBufferSize = kInitialCount; + if (m_capacity) + newBufferSize = (m_capacity << 1); + + reserve(newBufferSize); + } + } + + void add(T&& obj) + { + _maybeReserveForAdd(); + m_buffer[m_count++] = static_cast(obj); + } + + void add(const T& obj) + { + _maybeReserveForAdd(); + m_buffer[m_count++] = obj; + } Index getCount() const { return m_count; } Index getCapacity() const { return m_capacity; } - const T* getBuffer() const { return m_buffer; } + const T* getBuffer() const { return m_buffer; } T* getBuffer() { return m_buffer; } - void insert(Index idx, const T& val) { insertRange(idx, &val, 1); } + void insert(Index idx, const T& val) { insertRange(idx, &val, 1); } - void insertRange(Index idx, const T* vals, Index n) - { - if (m_capacity < m_count + n) - { + void insertRange(Index idx, const T* vals, Index n) + { + if (m_capacity < m_count + n) + { Index newBufferCount = kInitialCount; - while (newBufferCount < m_count + n) - newBufferCount = newBufferCount << 1; - - T* newBuffer = _allocate(newBufferCount); - if (m_capacity) - { - /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) - { - memcpy(newBuffer, buffer, sizeof(T) * id); - memcpy(newBuffer + id + n, buffer + id, sizeof(T) * (_count - id)); - } - else*/ - { - for (Index i = 0; i < idx; i++) - newBuffer[i] = m_buffer[i]; - for (Index i = idx; i < m_count; i++) - newBuffer[i + n] = T(static_cast(m_buffer[i])); - } - _deallocateBuffer(); - } - m_buffer = newBuffer; - m_capacity = newBufferCount; - } - else - { - /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) - memmove(buffer + id + n, buffer + id, sizeof(T) * (_count - id)); - else*/ - { - for (Index i = m_count; i > idx; i--) - m_buffer[i + n - 1] = static_cast(m_buffer[i - 1]); - } - } - /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) - memcpy(buffer + id, vals, sizeof(T) * n); - else*/ - for (Index i = 0; i < n; i++) - m_buffer[idx + i] = vals[i]; - - m_count += n; - } - - //slower than original edition - //void Add(const T & val) - //{ - // InsertRange(_count, &val, 1); - //} - - void insertRange(Index id, const List& list) { insertRange(id, list.m_buffer, list.m_count); } - - void addRange(ArrayView list) { insertRange(m_count, list.getBuffer(), list.Count()); } + while (newBufferCount < m_count + n) + newBufferCount = newBufferCount << 1; + + T* newBuffer = _allocate(newBufferCount); + if (m_capacity) + { + /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) + { + memcpy(newBuffer, buffer, sizeof(T) * id); + memcpy(newBuffer + id + n, buffer + id, sizeof(T) * (_count - id)); + } + else*/ + { + for (Index i = 0; i < idx; i++) + newBuffer[i] = m_buffer[i]; + for (Index i = idx; i < m_count; i++) + newBuffer[i + n] = T(static_cast(m_buffer[i])); + } + _deallocateBuffer(); + } + m_buffer = newBuffer; + m_capacity = newBufferCount; + } + else + { + /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) + memmove(buffer + id + n, buffer + id, sizeof(T) * (_count - id)); + else*/ + { + for (Index i = m_count; i > idx; i--) + m_buffer[i + n - 1] = static_cast(m_buffer[i - 1]); + } + } + /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) + memcpy(buffer + id, vals, sizeof(T) * n); + else*/ + for (Index i = 0; i < n; i++) + m_buffer[idx + i] = vals[i]; + + m_count += n; + } + + void insertRange(Index id, const List& list) { insertRange(id, list.m_buffer, list.m_count); } + + void addRange(ArrayView list) { insertRange(m_count, list.getBuffer(), list.Count()); } void addRange(const T* vals, Index n) { insertRange(m_count, vals, n); } - void addRange(const List& list) { insertRange(m_count, list.m_buffer, list.m_count); } + void addRange(const List& list) { insertRange(m_count, list.m_buffer, list.m_count); } - void removeRange(Index idx, Index count) - { + void removeRange(Index idx, Index count) + { SLANG_ASSERT(idx >= 0 && idx <= m_count); - const Index actualDeleteCount = ((idx + count) >= m_count)? (m_count - idx) : count; - for (Index i = idx + actualDeleteCount; i < m_count; i++) - m_buffer[i - actualDeleteCount] = static_cast(m_buffer[i]); - m_count -= actualDeleteCount; - } + const Index actualDeleteCount = ((idx + count) >= m_count)? (m_count - idx) : count; + for (Index i = idx + actualDeleteCount; i < m_count; i++) + m_buffer[i - actualDeleteCount] = static_cast(m_buffer[i]); + m_count -= actualDeleteCount; + } - void removeAt(Index id) { removeRange(id, 1); } + void removeAt(Index id) { removeRange(id, 1); } - void remove(const T& val) - { + void remove(const T& val) + { Index idx = indexOf(val); - if (idx != -1) - removeAt(idx); - } - - void reverse() - { - for (Index i = 0; i < (m_count >> 1); i++) - { - swapElements(m_buffer, i, m_count - i - 1); - } - } - - void fastRemove(const T& val) - { + if (idx != -1) + removeAt(idx); + } + + void reverse() + { + for (Index i = 0; i < (m_count >> 1); i++) + { + swapElements(m_buffer, i, m_count - i - 1); + } + } + + void fastRemove(const T& val) + { Index idx = indexOf(val); - fastRemoveAt(idx); - } + if (idx >= 0) + { + fastRemoveAt(idx); + } + } - void fastRemoveAt(Index idx) - { - if (idx != -1 && m_count - 1 != idx) - { - m_buffer[idx] = _Move(m_buffer[m_count - 1]); - } - m_count--; - } + void fastRemoveAt(Index idx) + { + SLANG_ASSERT(idx >= 0 && idx < m_count); + // We do not test for idx == m_count - 1 (ie the move is to current index). With the assumption that any reasonable move implementation + // tests and ignores this case + if (idx != m_count - 1) + { + m_buffer[idx] = _Move(m_buffer[m_count - 1]); + } + m_count--; + } - void clear() { m_count = 0; } + void clear() { m_count = 0; } void clearAndDeallocate() { @@ -356,233 +363,239 @@ namespace Slang m_count = m_capacity = 0; } - void reserve(Index size) - { - if(size > m_capacity) - { - T* newBuffer = _allocate(size); - if (m_capacity) - { - /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) - memcpy(newBuffer, buffer, _count * sizeof(T)); - else*/ - { - for (Index i = 0; i < m_count; i++) - newBuffer[i] = static_cast(m_buffer[i]); + void reserve(Index size) + { + if(size > m_capacity) + { + T* newBuffer = _allocate(size); + if (m_capacity) + { + /*if (std::has_trivial_copy_assign::value && std::has_trivial_destructor::value) + memcpy(newBuffer, buffer, _count * sizeof(T)); + else*/ + { + for (Index i = 0; i < m_count; i++) + newBuffer[i] = static_cast(m_buffer[i]); // Default-initialize the remaining elements for(Index i = m_count; i < size; i++) { new(newBuffer + i) T(); } - } - _deallocateBuffer(); - } - m_buffer = newBuffer; - m_capacity = size; - } - } - - void growToCount(Index count) - { + } + _deallocateBuffer(); + } + m_buffer = newBuffer; + m_capacity = size; + } + } + + void growToCount(Index count) + { Index newBufferCount = Index(1) << Math::Log2Ceil(count); - if (m_capacity < newBufferCount) - { - reserve(newBufferCount); - } - m_count = count; - } - - void setCount(Index count) - { - reserve(count); - m_count = count; - } - - void unsafeShrinkToCount(Index count) { m_count = count; } - - void compress() - { - if (m_capacity > m_count && m_count > 0) - { - T* newBuffer = _allocate(m_count); - for (Index i = 0; i < m_count; i++) - newBuffer[i] = static_cast(m_buffer[i]); - - _deallocateBuffer(); - m_buffer = newBuffer; - m_capacity = m_count; - } - } - - SLANG_FORCE_INLINE T& operator [](Index idx) const - { - SLANG_ASSERT(idx >= 0 && idx <= m_count); - return m_buffer[idx]; - } + if (m_capacity < newBufferCount) + { + reserve(newBufferCount); + } + m_count = count; + } + + void setCount(Index count) + { + reserve(count); + m_count = count; + } - template + void unsafeShrinkToCount(Index count) { m_count = count; } + + void compress() + { + if (m_capacity > m_count && m_count > 0) + { + T* newBuffer = _allocate(m_count); + for (Index i = 0; i < m_count; i++) + newBuffer[i] = static_cast(m_buffer[i]); + + _deallocateBuffer(); + m_buffer = newBuffer; + m_capacity = 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 T& operator [](Index idx) + { + SLANG_ASSERT(idx >= 0 && idx < m_count); + return m_buffer[idx]; + } + + template Index findFirstIndex(const Func& predicate) const - { - for (Index i = 0; i < m_count; i++) - { - if (predicate(m_buffer[i])) - return i; - } - return (Index)-1; - } - - template - Index findLastIndex(const Func& predicate) const - { - for (Index i = m_count; i > 0; i--) - { - if (predicate(m_buffer[i-1])) - return i-1; - } - return (Index)-1; - } - - template + { + for (Index i = 0; i < m_count; i++) + { + if (predicate(m_buffer[i])) + return i; + } + return -1; + } + + template Index indexOf(const T2& val) const - { - for (Index i = 0; i < m_count; i++) - { - if (m_buffer[i] == val) - return i; - } - return (Index)-1; - } - - template + { + for (Index i = 0; i < m_count; i++) + { + if (m_buffer[i] == val) + 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; + } + + template Index lastIndexOf(const T2& val) const - { - for (Index i = m_count; i > 0; i--) - { - if(m_buffer[i-1] == val) - return i-1; - } - return (Index)-1; - } - - void sort() - { - sort([](const T& t1, const T& t2){return t1 < t2;}); - } + { + for (Index i = m_count - 1; i >= 0; i--) + { + if(m_buffer[i] == val) + return i; + } + return -1; + } + + void sort() + { + sort([](const T& t1, const T& t2){return t1 < t2;}); + } bool contains(const T& val) const { return indexOf(val) != Index(-1); } - template - void sort(Comparer compare) - { - //insertionSort(buffer, 0, _count - 1); - //quickSort(buffer, 0, _count - 1, compare); - std::sort(m_buffer, m_buffer + m_count, compare); - } - - template - void forEach(IterateFunc f) const - { - for (Index i = 0; i< m_count; i++) - f(m_buffer[i]); - } - - template - void quickSort(T* vals, Index startIndex, Index endIndex, Comparer comparer) - { + template + void sort(Comparer compare) + { + //insertionSort(buffer, 0, _count - 1); + //quickSort(buffer, 0, _count - 1, compare); + std::sort(m_buffer, m_buffer + m_count, compare); + } + + template + void forEach(IterateFunc f) const + { + for (Index i = 0; i < m_count; i++) + f(m_buffer[i]); + } + + template + void quickSort(T* vals, Index startIndex, Index endIndex, Comparer comparer) + { static const Index kMinQSortSize = 32; - if(startIndex < endIndex) - { - if (endIndex - startIndex < kMinQSortSize) - insertionSort(vals, startIndex, endIndex, comparer); - else - { + if(startIndex < endIndex) + { + if (endIndex - startIndex < kMinQSortSize) + insertionSort(vals, startIndex, endIndex, comparer); + else + { Index pivotIndex = (startIndex + endIndex) >> 1; Index pivotNewIndex = partition(vals, startIndex, endIndex, pivotIndex, comparer); - quickSort(vals, startIndex, pivotNewIndex - 1, comparer); - quickSort(vals, pivotNewIndex + 1, endIndex, comparer); - } - } + quickSort(vals, startIndex, pivotNewIndex - 1, comparer); + quickSort(vals, pivotNewIndex + 1, endIndex, comparer); + } + } - } - template + } + template Index partition(T* vals, Index left, Index right, Index pivotIndex, Comparer comparer) - { - T pivotValue = vals[pivotIndex]; - swapElements(vals, right, pivotIndex); + { + T pivotValue = vals[pivotIndex]; + swapElements(vals, right, pivotIndex); Index storeIndex = left; - for (Index i = left; i < right; i++) - { - if (comparer(vals[i], pivotValue)) - { - swapElements(vals, i, storeIndex); - storeIndex++; - } - } - swapElements(vals, storeIndex, right); - return storeIndex; - } - template - void insertionSort(T* vals, Index startIndex, Index endIndex, Comparer comparer) - { - for (Index i = startIndex + 1; i <= endIndex; i++) - { - T insertValue = static_cast(vals[i]); + for (Index i = left; i < right; i++) + { + if (comparer(vals[i], pivotValue)) + { + swapElements(vals, i, storeIndex); + storeIndex++; + } + } + swapElements(vals, storeIndex, right); + return storeIndex; + } + template + void insertionSort(T* vals, Index startIndex, Index endIndex, Comparer comparer) + { + for (Index i = startIndex + 1; i <= endIndex; i++) + { + T insertValue = static_cast(vals[i]); Index insertIndex = i - 1; - while (insertIndex >= startIndex && comparer(insertValue, vals[insertIndex])) - { - vals[insertIndex + 1] = static_cast(vals[insertIndex]); - insertIndex--; - } - vals[insertIndex + 1] = static_cast(insertValue); - } - } - - inline void swapElements(T* vals, Index index1, Index index2) - { - if (index1 != index2) - { - T tmp = static_cast(vals[index1]); - vals[index1] = static_cast(vals[index2]); - vals[index2] = static_cast(tmp); - } - } - - template + while (insertIndex >= startIndex && comparer(insertValue, vals[insertIndex])) + { + vals[insertIndex + 1] = static_cast(vals[insertIndex]); + insertIndex--; + } + vals[insertIndex + 1] = static_cast(insertValue); + } + } + + inline void swapElements(T* vals, Index index1, Index index2) + { + if (index1 != index2) + { + T tmp = static_cast(vals[index1]); + vals[index1] = static_cast(vals[index2]); + vals[index2] = static_cast(tmp); + } + } + + template Index binarySearch(const T2& obj, Comparer comparer) - { + { Index imin = 0, imax = m_count - 1; - while (imax >= imin) - { + while (imax >= imin) + { Index imid = (imin + imax) >> 1; - int compareResult = comparer(m_buffer[imid], obj); - if (compareResult == 0) - return imid; - else if (compareResult < 0) - imin = imid + 1; - else - imax = imid - 1; - } - return -1; - } - - template - int binarySearch(const T2& obj) - { - return binarySearch(obj, - [](T & curObj, const T2 & thatObj)->int - { - if (curObj < thatObj) - return -1; - else if (curObj == thatObj) - return 0; - else - return 1; - }); - } + int compareResult = comparer(m_buffer[imid], obj); + if (compareResult == 0) + return imid; + else if (compareResult < 0) + imin = imid + 1; + else + imax = imid - 1; + } + return -1; + } + + template + int binarySearch(const T2& obj) + { + return binarySearch(obj, + [](T & curObj, const T2 & thatObj)->int + { + if (curObj < thatObj) + return -1; + else if (curObj == thatObj) + return 0; + else + return 1; + }); + } private: - T* m_buffer; ///< A new T[N] allocated buffer. NOTE! All elements up to capacity are in some valid form for T. + T* m_buffer; ///< A new T[N] allocated buffer. NOTE! All elements up to capacity are in some valid form for T. Index m_capacity; ///< The total capacity of elements Index m_count; ///< The amount of elements @@ -605,27 +618,27 @@ namespace Slang add(val); _init(args...); } - }; - - template - T calcMin(const List& list) - { - T minVal = list.getFirst(); - for (Index i = 1; i < list.getCount(); i++) - if (list[i] < minVal) - minVal = list[i]; - return minVal; - } - - template - T calcMax(const List& list) - { - T maxVal = list.getFirst(); - for (Index i = 1; i< list.getCount(); i++) - if (list[i] > maxVal) - maxVal = list[i]; - return maxVal; - } + }; + + template + T calcMin(const List& list) + { + T minVal = list.getFirst(); + for (Index i = 1; i < list.getCount(); i++) + if (list[i] < minVal) + minVal = list[i]; + return minVal; + } + + template + T calcMax(const List& list) + { + T maxVal = list.getFirst(); + for (Index i = 1; i< list.getCount(); i++) + if (list[i] > maxVal) + maxVal = list[i]; + return maxVal; + } } #endif diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index f8df46ff7..a37d80ae8 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -2559,7 +2559,7 @@ namespace Slang } funcDecl->ReturnType = resultType; - for (auto & para : funcDecl->GetParameters()) + for (auto& para : funcDecl->GetParameters()) { ensureDecl(para, DeclCheckState::ReadyForReference); } @@ -2779,11 +2779,7 @@ namespace Slang // subscript(uint index) -> T { get; } // - bool anyAccessors = false; - for(auto accessorDecl : decl->getMembersOfType()) - { - anyAccessors = true; - } + bool anyAccessors = decl->getMembersOfType().isNonEmpty(); if(!anyAccessors) { diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index dc013b781..20d1af09a 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -440,11 +440,8 @@ namespace Slang // A call may yield an l-value, and we should take a look at the candidate to be sure if(auto subscriptDeclRef = candidate.item.declRef.as()) { - for(auto setter : subscriptDeclRef.getDecl()->getMembersOfType()) - { - callExpr->type.IsLeftValue = true; - } - for(auto refAccessor : subscriptDeclRef.getDecl()->getMembersOfType()) + const auto& decl = subscriptDeclRef.getDecl(); + if (decl->getMembersOfType().isNonEmpty() || decl->getMembersOfType().isNonEmpty()) { callExpr->type.IsLeftValue = true; } diff --git a/source/slang/slang-lexer.cpp b/source/slang/slang-lexer.cpp index 6d13a053d..9b3bed88e 100644 --- a/source/slang/slang-lexer.cpp +++ b/source/slang/slang-lexer.cpp @@ -12,18 +12,18 @@ namespace Slang { - Token TokenReader::GetEndOfFileToken() + Token TokenReader::getEndOfFileToken() { return Token(TokenType::EndOfFile, UnownedStringSlice::fromLiteral(""), SourceLoc()); } - Token* TokenList::begin() const + const Token* TokenList::begin() const { SLANG_ASSERT(m_tokens.getCount()); return &m_tokens[0]; } - Token* TokenList::end() const + const Token* TokenList::end() const { SLANG_ASSERT(m_tokens.getCount()); SLANG_ASSERT(m_tokens[m_tokens.getCount() - 1].type == TokenType::EndOfFile); @@ -59,7 +59,7 @@ namespace Slang Token TokenReader::advanceToken() { if (!m_cursor) - return GetEndOfFileToken(); + return getEndOfFileToken(); Token token = m_nextToken; if (m_cursor < m_end) diff --git a/source/slang/slang-lexer.h b/source/slang/slang-lexer.h index 0d19fe617..d1a1ba844 100644 --- a/source/slang/slang-lexer.h +++ b/source/slang/slang-lexer.h @@ -12,8 +12,8 @@ namespace Slang struct TokenList { - Token* begin() const; - Token* end() const; + const Token* begin() const; + const Token* end() const; SLANG_FORCE_INLINE void add(const Token& token) { m_tokens.add(token); } @@ -29,13 +29,13 @@ namespace Slang , m_end (tokenList.end ()) {} - Token* begin() const { return m_begin; } - Token* end () const { return m_end ; } + const Token* begin() const { return m_begin; } + const Token* end () const { return m_end ; } int getCount() { return (int)(m_end - m_begin); } - Token* m_begin; - Token* m_end; + const Token* m_begin; + const Token* m_end; }; struct TokenReader @@ -45,17 +45,17 @@ namespace Slang explicit TokenReader(TokenSpan const& tokens) : m_cursor(tokens.begin()) , m_end (tokens.end ()) - , m_nextToken(tokens.begin() ? *tokens.begin() : GetEndOfFileToken()) + , m_nextToken(tokens.begin() ? *tokens.begin() : getEndOfFileToken()) {} explicit TokenReader(TokenList const& tokens) : m_cursor(tokens.begin()) , m_end (tokens.end ()) - , m_nextToken(tokens.begin() ? *tokens.begin() : GetEndOfFileToken()) + , m_nextToken(tokens.begin() ? *tokens.begin() : getEndOfFileToken()) {} struct ParsingCursor { Token nextToken; - Token* tokenReaderCursor = nullptr; + const Token* tokenReaderCursor = nullptr; }; ParsingCursor getCursor() { @@ -78,9 +78,9 @@ namespace Slang int getCount() { return (int)(m_end - m_cursor); } - Token* m_cursor; - Token* m_end; - static Token GetEndOfFileToken(); + const Token* m_cursor; + const Token* m_end; + static Token getEndOfFileToken(); }; typedef unsigned int LexerFlags; diff --git a/source/slang/slang-syntax.h b/source/slang/slang-syntax.h index c5160e47b..6177b894d 100644 --- a/source/slang/slang-syntax.h +++ b/source/slang/slang-syntax.h @@ -753,8 +753,8 @@ namespace Slang struct Iterator { - Element* m_cursor; - Element* m_end; + const Element* m_cursor; + const Element* m_end; bool operator!=(Iterator const& other) { @@ -766,9 +766,9 @@ namespace Slang m_cursor = adjust(m_cursor + 1, m_end); } - RefPtr& operator*() + const RefPtr& operator*() { - return *(RefPtr*)m_cursor; + return *(RefPtr*)(m_cursor); } }; @@ -784,7 +784,7 @@ namespace Slang return iter; } - static Element* adjust(Element* cursor, Element* end) + static const Element* adjust(const Element* cursor, const Element* end) { while (cursor != end) { @@ -797,7 +797,7 @@ namespace Slang // TODO(tfoley): It is ugly to have these. // We should probably fix the call sites instead. - RefPtr& getFirst() { return *begin(); } + const RefPtr& getFirst() { return *begin(); } Index getCount() { Index count = 0; @@ -819,8 +819,11 @@ namespace Slang return result; } - Element* m_begin; - Element* m_end; + bool isEmpty() const { return m_end == m_begin; } + bool isNonEmpty() const { return m_end != m_begin; } + + const Element* m_begin; + const Element* m_end; }; struct TransparentMemberInfo @@ -861,17 +864,17 @@ namespace Slang struct Iterator { FilteredMemberRefList const* list; - RefPtr* ptr; - RefPtr* end; + const RefPtr* ptr; + const RefPtr* end; Iterator() : list(nullptr), ptr(nullptr) {} Iterator( - FilteredMemberRefList const* list, - RefPtr* ptr, - RefPtr* end) - : list(list) - , ptr(ptr) - , end(end) + FilteredMemberRefList const* inList, + const RefPtr* inPtr, + const RefPtr* inEnd) + : list(inList) + , ptr(inPtr) + , end(inEnd) {} bool operator!=(Iterator other) @@ -893,7 +896,7 @@ namespace Slang Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); } Iterator end() const { return Iterator(this, decls.end(), decls.end()); } - RefPtr* Adjust(RefPtr* ptr, RefPtr* end) const + const RefPtr* Adjust(const RefPtr* ptr, const RefPtr* end) const { for (; ptr != end; ptr++) { -- cgit v1.2.3