diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt index 24cde73e41..f088dd5f8d 100644 --- a/src/misc/CMakeLists.txt +++ b/src/misc/CMakeLists.txt @@ -1,12 +1,10 @@ add_files( - array.hpp binaryheap.hpp countedobj.cpp countedptr.hpp dbg_helpers.cpp dbg_helpers.h endian_buffer.hpp - fixedsizearray.hpp getoptdata.cpp getoptdata.h hashtable.hpp diff --git a/src/misc/array.hpp b/src/misc/array.hpp deleted file mode 100644 index cc48d295cd..0000000000 --- a/src/misc/array.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file array.hpp Array without an explicit maximum size. */ - -#ifndef ARRAY_HPP -#define ARRAY_HPP - -#include "fixedsizearray.hpp" -#include "../string_func.h" - -/** - * Flexible array with size limit. Implemented as fixed size - * array of fixed size arrays - */ -template -class SmallArray { -protected: - typedef FixedSizeArray SubArray; ///< inner array - typedef FixedSizeArray SuperArray; ///< outer array - - static const uint Tcapacity = B * N; ///< total max number of items - - SuperArray data; ///< array of arrays of items - - /** return first sub-array with free space for new item */ - inline SubArray &FirstFreeSubArray() - { - uint super_size = data.Length(); - if (super_size > 0) { - SubArray &s = data[super_size - 1]; - if (!s.IsFull()) return s; - } - return *data.AppendC(); - } - -public: - /** implicit constructor */ - inline SmallArray() - { - } - - /** Clear (destroy) all items */ - inline void Clear() - { - data.Clear(); - } - - /** Return actual number of items */ - inline uint Length() const - { - uint super_size = data.Length(); - if (super_size == 0) return 0; - uint sub_size = data[super_size - 1].Length(); - return (super_size - 1) * B + sub_size; - } - /** return true if array is empty */ - inline bool IsEmpty() - { - return data.IsEmpty(); - } - - /** return true if array is full */ - inline bool IsFull() - { - return data.IsFull() && data[N - 1].IsFull(); - } - - /** allocate but not construct new item */ - inline T *Append() - { - return FirstFreeSubArray().Append(); - } - - /** allocate and construct new item */ - inline T *AppendC() - { - return FirstFreeSubArray().AppendC(); - } - - /** indexed access (non-const) */ - inline T& operator[](uint index) - { - const SubArray &s = data[index / B]; - T &item = s[index % B]; - return item; - } - /** indexed access (const) */ - inline const T& operator[](uint index) const - { - const SubArray &s = data[index / B]; - const T &item = s[index % B]; - return item; - } - - /** - * Helper for creating a human readable output of this data. - * @param dmp The location to dump to. - */ - template void Dump(D &dmp) const - { - dmp.WriteValue("capacity", Tcapacity); - uint num_items = Length(); - dmp.WriteValue("num_items", num_items); - for (uint i = 0; i < num_items; i++) { - const T &item = (*this)[i]; - dmp.WriteStructT(fmt::format("item[{}]", i), &item); - } - } -}; - -#endif /* ARRAY_HPP */ diff --git a/src/misc/dbg_helpers.h b/src/misc/dbg_helpers.h index fdfcaba04a..27db305b14 100644 --- a/src/misc/dbg_helpers.h +++ b/src/misc/dbg_helpers.h @@ -165,6 +165,34 @@ struct DumpTarget { EndStruct(); } } + + /** Dump nested object (or only its name if this instance is already known). */ + template void WriteStructT(const std::string &name, const std::deque *s) + { + static size_t type_id = ++LastTypeId(); + + if (s == nullptr) { + /* No need to dump nullptr struct. */ + WriteValue(name, ""); + return; + } + std::string known_as; + if (FindKnownName(type_id, s, known_as)) { + /* We already know this one, no need to dump it. */ + std::string known_as_str = std::string("known_as.") + name; + WriteValue(name, known_as_str); + } else { + /* Still unknown, dump it */ + BeginStruct(type_id, name, s); + size_t num_items = s->size(); + this->WriteValue("num_items", std::to_string(num_items)); + for (size_t i = 0; i < num_items; i++) { + const auto &item = (*s)[i]; + this->WriteStructT(fmt::format("item[{}]", i), &item); + } + EndStruct(); + } + } }; #endif /* DBG_HELPERS_H */ diff --git a/src/misc/fixedsizearray.hpp b/src/misc/fixedsizearray.hpp deleted file mode 100644 index f06492ff13..0000000000 --- a/src/misc/fixedsizearray.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file fixedsizearray.hpp A fixed size array that doesn't create items until needed. */ - -#ifndef FIXEDSIZEARRAY_HPP -#define FIXEDSIZEARRAY_HPP - -#include "../core/alloc_func.hpp" - -/** - * fixed size array - * Upon construction it preallocates fixed size block of memory - * for all items, but doesn't construct them. Item's construction - * is delayed. - */ -template -struct FixedSizeArray { -protected: - /** header for fixed size array */ - struct ArrayHeader - { - uint items; ///< number of items in the array - uint reference_count; ///< block reference counter (used by copy constructor and by destructor) - }; - - /* make constants visible from outside */ - static const uint Tsize = sizeof(T); ///< size of item - static const uint HeaderSize = sizeof(ArrayHeader); ///< size of header - - /** - * the only member of fixed size array is pointer to the block - * of C array of items. Header can be found on the offset -sizeof(ArrayHeader). - */ - T *data; - - /** return reference to the array header (non-const) */ - inline ArrayHeader &Hdr() - { - return *(ArrayHeader*)(((uint8_t*)data) - HeaderSize); - } - - /** return reference to the array header (const) */ - inline const ArrayHeader &Hdr() const - { - return *(ArrayHeader*)(((uint8_t*)data) - HeaderSize); - } - - /** return reference to the block reference counter */ - inline uint &RefCnt() - { - return Hdr().reference_count; - } - - /** return reference to number of used items */ - inline uint &SizeRef() - { - return Hdr().items; - } - -public: - /** Default constructor. Preallocate space for items and header, then initialize header. */ - FixedSizeArray() - { - /* Ensure the size won't overflow. */ - static_assert(C < (SIZE_MAX - HeaderSize) / Tsize); - - /* allocate block for header + items (don't construct items) */ - data = (T*)((MallocT(HeaderSize + C * Tsize)) + HeaderSize); - SizeRef() = 0; // initial number of items - RefCnt() = 1; // initial reference counter - } - - /** Copy constructor. Preallocate space for items and header, then initialize header. */ - FixedSizeArray(const FixedSizeArray &src) - { - /* share block (header + items) with the source array */ - data = src.data; - RefCnt()++; // now we share block with the source - } - - /** destroy remaining items and free the memory block */ - ~FixedSizeArray() - { - /* release one reference to the shared block */ - if ((--RefCnt()) > 0) return; // and return if there is still some owner - - Clear(); - /* free the memory block occupied by items */ - free(((uint8_t*)data) - HeaderSize); - data = nullptr; - } - - /** Clear (destroy) all items */ - inline void Clear() - { - /* Walk through all allocated items backward and destroy them - * Note: this->Length() can be zero. In that case data[this->Length() - 1] is evaluated unsigned - * on some compilers with some architectures. (e.g. gcc with x86) */ - for (T *pItem = this->data + this->Length() - 1; pItem >= this->data; pItem--) { - pItem->~T(); - } - /* number of items become zero */ - SizeRef() = 0; - } - - /** return number of used items */ - inline uint Length() const - { - return Hdr().items; - } - - /** return true if array is full */ - inline bool IsFull() const - { - return Length() >= C; - } - - /** return true if array is empty */ - inline bool IsEmpty() const - { - return Length() <= 0; - } - - /** add (allocate), but don't construct item */ - inline T *Append() - { - assert(!IsFull()); - return &data[SizeRef()++]; - } - - /** add and construct item using default constructor */ - inline T *AppendC() - { - T *item = Append(); - new(item)T; - return item; - } - /** return item by index (non-const version) */ - inline T& operator[](uint index) - { - assert(index < Length()); - return data[index]; - } - - /** return item by index (const version) */ - inline const T& operator[](uint index) const - { - assert(index < Length()); - return data[index]; - } -}; - -#endif /* FIXEDSIZEARRAY_HPP */ diff --git a/src/pathfinder/yapf/nodelist.hpp b/src/pathfinder/yapf/nodelist.hpp index b74345e544..9aa30ee07f 100644 --- a/src/pathfinder/yapf/nodelist.hpp +++ b/src/pathfinder/yapf/nodelist.hpp @@ -10,7 +10,6 @@ #ifndef NODELIST_HPP #define NODELIST_HPP -#include "../../misc/array.hpp" #include "../../misc/hashtable.hpp" #include "../../misc/binaryheap.hpp" @@ -24,7 +23,7 @@ class CNodeList_HashTableT { public: typedef Titem_ Titem; ///< Make #Titem_ visible from outside of class. typedef typename Titem_::Key Key; ///< Make Titem_::Key a property of this class. - typedef SmallArray CItemArray; ///< Type that we will use as item container. + using CItemArray = std::deque; ///< Type that we will use as item container. typedef CHashTableT COpenList; ///< How pointers to open nodes will be stored. typedef CHashTableT CClosedList; ///< How pointers to closed nodes will be stored. typedef CBinaryHeapT CPriorityQueue; ///< How the priority queue will be managed. @@ -63,7 +62,7 @@ public: /** allocate new data item from m_arr */ inline Titem_ *CreateNewNode() { - if (m_new_node == nullptr) m_new_node = m_arr.AppendC(); + if (m_new_node == nullptr) m_new_node = &m_arr.emplace_back(); return m_new_node; } diff --git a/src/pathfinder/yapf/yapf.hpp b/src/pathfinder/yapf/yapf.hpp index 36df4db951..db8508fdcd 100644 --- a/src/pathfinder/yapf/yapf.hpp +++ b/src/pathfinder/yapf/yapf.hpp @@ -14,8 +14,6 @@ #include "../pathfinder_func.h" #include "yapf.h" -#include "../../misc/fixedsizearray.hpp" -#include "../../misc/array.hpp" #include "../../misc/hashtable.hpp" #include "../../misc/binaryheap.hpp" #include "../../misc/dbg_helpers.h" diff --git a/src/pathfinder/yapf/yapf_costcache.hpp b/src/pathfinder/yapf/yapf_costcache.hpp index 06e8566a79..0c0aa729fd 100644 --- a/src/pathfinder/yapf/yapf_costcache.hpp +++ b/src/pathfinder/yapf/yapf_costcache.hpp @@ -57,7 +57,7 @@ public: typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::CachedData CachedData; typedef typename CachedData::Key CacheKey; - typedef SmallArray LocalCache; + using LocalCache = std::deque; protected: LocalCache m_local_cache; @@ -76,7 +76,7 @@ public: inline bool PfNodeCacheFetch(Node &n) { CacheKey key(n.GetKey()); - Yapf().ConnectNodeToCachedData(n, *new (m_local_cache.Append()) CachedData(key)); + Yapf().ConnectNodeToCachedData(n, m_local_cache.emplace_back(key)); return false; } @@ -123,7 +123,7 @@ struct CSegmentCostCacheT : public CSegmentCostCacheBase { static const int C_HASH_BITS = 14; typedef CHashTableT HashTable; - typedef SmallArray Heap; + using Heap = std::deque; typedef typename Tsegment::Key Key; ///< key to hash table HashTable m_map; @@ -135,7 +135,7 @@ struct CSegmentCostCacheT : public CSegmentCostCacheBase { inline void Flush() { m_map.Clear(); - m_heap.Clear(); + m_heap.clear(); } inline Tsegment &Get(Key &key, bool *found) @@ -143,7 +143,7 @@ struct CSegmentCostCacheT : public CSegmentCostCacheBase { Tsegment *item = m_map.Find(key); if (item == nullptr) { *found = false; - item = new (m_heap.Append()) Tsegment(key); + item = &m_heap.emplace_back(key); m_map.Push(*item); } else { *found = true;