diff options
Diffstat (limited to 'src/lib/netlist/plib/plists.h')
-rwxr-xr-x | src/lib/netlist/plib/plists.h | 114 |
1 files changed, 92 insertions, 22 deletions
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 6929a10601b..328f0b1ad23 100755 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -17,14 +17,13 @@ namespace plib { - /// \brief fixed size array allowing to override constructor and initialize members by placement new. + /// \brief Array holding uninitialized elements /// /// Use with care. This template is provided to improve locality of storage /// in high frequency applications. It should not be used for anything else. /// - /// template <class C, std::size_t N> - class uninitialised_array_t + class uninitialised_array { public: @@ -41,18 +40,10 @@ namespace plib { using const_reverse_iterator = std::reverse_iterator<const_iterator>; //uninitialised_array_t() noexcept = default; - uninitialised_array_t() noexcept - : m_initialized(0) - { - } + uninitialised_array() noexcept = default; - PCOPYASSIGNMOVE(uninitialised_array_t, delete) - ~uninitialised_array_t() noexcept - { - if (m_initialized>=N) - for (size_type i=0; i<N; ++i) - (*this)[i].~C(); - } + PCOPYASSIGNMOVE(uninitialised_array, delete) + ~uninitialised_array() noexcept = default; constexpr size_t size() const noexcept { return N; } @@ -70,34 +61,113 @@ namespace plib { return reinterpret_cast<const_reference>(m_buf[index]); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); } + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); } + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + N); } + + protected: + + private: + std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf; + }; + + /// \brief fixed allocation vector + /// + /// Currently only emplace_back and clear are supported. + /// + /// Use with care. This template is provided to improve locality of storage + /// in high frequency applications. It should not be used for anything else. + /// + template <class C, std::size_t N> + class static_vector + { + public: + + using value_type = C; + using pointer = value_type *; + using const_pointer = const value_type *; + using reference = value_type &; + using const_reference = const value_type &; + using iterator = value_type *; + using const_iterator = const value_type *; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + + static_vector() noexcept + : m_pos(0) + { + } + + PCOPYASSIGNMOVE(static_vector, delete) + ~static_vector() noexcept + { + clear(); + } + + constexpr size_t size() const noexcept { return m_pos; } + + constexpr bool empty() const noexcept { return size() == 0; } + + void clear() + { + for (size_type i=0; i<m_pos; ++i) + (*this)[i].~C(); + m_pos = 0; + } + template<typename... Args> - void emplace(size_type index, Args&&... args) + void emplace_back(Args&&... args) + { + // placement new on buffer + new (&m_buf[m_pos]) C(std::forward<Args>(args)...); + m_pos++; + } + + reference operator[](size_type index) noexcept + { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast<reference>(m_buf[index]); + } + + constexpr const_reference operator[](size_type index) const noexcept { - m_initialized++; - // allocate on buffer - new (&m_buf[index]) C(std::forward<Args>(args)...); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast<const_reference>(m_buf[index]); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); } + iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + m_pos); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); } + iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + m_pos); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + N); } + const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + m_pos); } protected: private: std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf; - unsigned m_initialized; + size_type m_pos; }; /// \brief a simple linked list. |