summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/plists.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/plists.h')
-rw-r--r--src/lib/netlist/plib/plists.h122
1 files changed, 112 insertions, 10 deletions
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h
index 5fefa658b83..c2fee9c2f8e 100644
--- a/src/lib/netlist/plib/plists.h
+++ b/src/lib/netlist/plib/plists.h
@@ -12,6 +12,8 @@
#include "pstring.h"
+#include <array>
+#include <type_traits>
#include <vector>
namespace plib {
@@ -29,14 +31,13 @@ class uninitialised_array_t
{
public:
- typedef C* iterator;
- typedef const C* const_iterator;
+ using iterator = C *;
+ using const_iterator = const C *;
- uninitialised_array_t()
- {
- }
+ uninitialised_array_t() noexcept = default;
- ~uninitialised_array_t()
+ COPYASSIGNMOVE(uninitialised_array_t, delete)
+ ~uninitialised_array_t() noexcept
{
for (std::size_t i=0; i<N; i++)
(*this)[i].~C();
@@ -51,7 +52,7 @@ public:
const C& operator[](const std::size_t &index) const noexcept
{
- return *reinterpret_cast<C *>(&m_buf[index]);
+ return *reinterpret_cast<const C *>(&m_buf[index]);
}
template<typename... Args>
@@ -75,7 +76,8 @@ protected:
private:
/* ensure proper alignment */
- typename std::aligned_storage<sizeof(C), alignof(C)>::type m_buf[N];
+ PALIGNAS_VECTOROPT()
+ std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
};
// ----------------------------------------------------------------------------------------
@@ -83,6 +85,7 @@ private:
// the list allows insertions / deletions if used properly
// ----------------------------------------------------------------------------------------
+#if 0
template <class LC>
class linkedlist_t
{
@@ -152,9 +155,10 @@ public:
void remove(const LC *elem) noexcept
{
auto p = &m_head;
- for ( ; *p != elem; p = &((*p)->m_next))
+ while(*p != elem)
{
//nl_assert(*p != nullptr);
+ p = &((*p)->m_next);
}
(*p) = elem->m_next;
}
@@ -166,7 +170,105 @@ public:
private:
LC *m_head;
};
+#else
+template <class LC>
+class linkedlist_t
+{
+public:
+
+ struct element_t
+ {
+ public:
+
+ friend class linkedlist_t<LC>;
+
+ constexpr element_t() : m_next(nullptr), m_prev(nullptr) {}
+ ~element_t() noexcept = default;
+
+ COPYASSIGNMOVE(element_t, delete)
+
+ constexpr LC *next() const noexcept { return m_next; }
+ constexpr LC *prev() const noexcept { return m_prev; }
+ private:
+ LC * m_next;
+ LC * m_prev;
+ };
+
+ struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
+ {
+ private:
+ LC* p;
+ public:
+ explicit constexpr iter_t(LC* x) noexcept : p(x) { }
+ constexpr iter_t(iter_t &rhs) noexcept : p(rhs.p) { }
+ iter_t(iter_t &&rhs) noexcept { std::swap(*this, rhs); }
+ iter_t& operator=(const iter_t &rhs) noexcept { iter_t t(rhs); std::swap(*this, t); return *this; }
+ iter_t& operator=(iter_t &&rhs) noexcept { std::swap(*this, rhs); return *this; }
+ iter_t& operator++() noexcept {p = p->next();return *this;}
+ // NOLINTNEXTLINE(cert-dcl21-cpp)
+ iter_t operator++(int) & noexcept {const iter_t tmp(*this); operator++(); return tmp;}
+
+ ~iter_t() = default;
+
+ constexpr bool operator==(const iter_t& rhs) const noexcept {return p == rhs.p;}
+ constexpr bool operator!=(const iter_t& rhs) const noexcept {return p != rhs.p;}
+ /* constexpr */ LC& operator*() noexcept {return *p;}
+ /* constexpr */ LC* operator->() noexcept {return p;}
+
+ constexpr LC& operator*() const noexcept {return *p;}
+ constexpr LC* operator->() const noexcept {return p;}
+ };
+
+ constexpr linkedlist_t() : m_head(nullptr) {}
-}
+ constexpr iter_t begin() const noexcept { return iter_t(m_head); }
+ constexpr iter_t end() const noexcept { return iter_t(nullptr); }
+
+ void push_front(LC *elem) noexcept
+ {
+ if (m_head)
+ m_head->m_prev = elem;
+ elem->m_next = m_head;
+ elem->m_prev = nullptr;
+ m_head = elem;
+ }
+
+ void push_back(LC *elem) noexcept
+ {
+ LC ** p(&m_head);
+ LC * prev(nullptr);
+ while (*p != nullptr)
+ {
+ prev = *p;
+ p = &((*p)->m_next);
+ }
+ *p = elem;
+ elem->m_prev = prev;
+ elem->m_next = nullptr;
+ }
+
+ void remove(const LC *elem) noexcept
+ {
+ if (elem->m_prev)
+ elem->m_prev->m_next = elem->m_next;
+ else
+ m_head = elem->m_next;
+ if (elem->m_next)
+ elem->m_next->m_prev = elem->m_prev;
+ else
+ {
+ /* update tail */
+ }
+ }
+
+ LC *front() const noexcept { return m_head; }
+ void clear() noexcept { m_head = nullptr; }
+ constexpr bool empty() const noexcept { return (m_head == nullptr); }
+
+private:
+ LC *m_head;
+};
+#endif
+} // namespace plib
#endif /* PLISTS_H_ */