diff options
Diffstat (limited to 'src/emu/netlist/plib/plists.h')
-rw-r--r-- | src/emu/netlist/plib/plists.h | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/src/emu/netlist/plib/plists.h b/src/emu/netlist/plib/plists.h new file mode 100644 index 00000000000..fb121b798b6 --- /dev/null +++ b/src/emu/netlist/plib/plists.h @@ -0,0 +1,585 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * plists.h + * + */ + +#pragma once + +#ifndef PLISTS_H_ +#define PLISTS_H_ + +#include <cstring> + +#include "palloc.h" +#include "pstring.h" + +// ---------------------------------------------------------------------------------------- +// parray_t: dynamic array +// ---------------------------------------------------------------------------------------- + +template <class _ListClass> +class parray_t +{ +public: + + ATTR_COLD parray_t(std::size_t numElements) + : m_list(0), m_capacity(0) + { + set_capacity(numElements); + } + + ATTR_COLD parray_t(const parray_t &rhs) + : m_list(0), m_capacity(0) + { + set_capacity(rhs.size()); + for (std::size_t i=0; i<m_capacity; i++) + m_list[i] = rhs[i]; + } + + ATTR_COLD parray_t &operator=(const parray_t &rhs) + { + set_capacity(rhs.size()); + for (std::size_t i=0; i<m_capacity; i++) + m_list[i] = rhs[i]; + return *this; + } + + ~parray_t() + { + if (m_list != NULL) + pfree_array(m_list); + m_list = NULL; + } + + /* using the [] operator will not allow gcc to vectorize code because + * basically a pointer is returned. + * array works around this. + */ + + ATTR_HOT /* inline */ _ListClass *data() { return m_list; } + + ATTR_HOT /* inline */ _ListClass& operator[](std::size_t index) { return m_list[index]; } + ATTR_HOT /* inline */ const _ListClass& operator[](std::size_t index) const { return m_list[index]; } + + ATTR_HOT /* inline */ std::size_t size() const { return m_capacity; } + +protected: + ATTR_COLD void set_capacity(const std::size_t new_capacity) + { + if (m_list != NULL) + pfree_array(m_list); + if (new_capacity > 0) + m_list = palloc_array(_ListClass, new_capacity); + else + m_list = NULL; + m_capacity = new_capacity; + } + +private: + + _ListClass * m_list; + int m_capacity; +}; + +// ---------------------------------------------------------------------------------------- +// plist_t: a simple list +// ---------------------------------------------------------------------------------------- +#if 0 +#include <vector> +//#define plist_t std::vector +template <typename _ListClass> +class plist_t : public std::vector<_ListClass> +{ +public: + plist_t() : std::vector<_ListClass>() {} + plist_t(const int numElements) : std::vector<_ListClass>(numElements) {} + + /* inline */ void add(const _ListClass &elem) { this->push_back(elem); } + void clear_and_free() + { + for (_ListClass *i = this->data(); i < this->data() + this->size(); i++) + { + pfree(*i); + } + this->clear(); + } + /* inline */ bool contains(const _ListClass &elem) const + { + for (const _ListClass *i = this->data(); i < this->data() + this->size(); i++) + { + if (*i == elem) + return true; + } + return false; + } + + /* inline */ void remove(const _ListClass &elem) + { + for (int i = 0; i < this->size(); i++) + { + if (this->at(i) == elem) + { + this->erase(this->begin() + i); + return; + } + } + } + /* inline */ void remove_at(const int pos) + { + this->erase(this->begin() + pos); + } + + /* inline */ int indexof(const _ListClass &elem) const + { + for (int i = 0; i < this->size(); i++) + { + if (this->at(i) == elem) + return i; + } + return -1; + } + + ATTR_HOT /* inline */ void swap(const int pos1, const int pos2) + { + //nl_assert((pos1>=0) && (pos1<m_count)); + //nl_assert((pos2>=0) && (pos2<m_count)); + _ListClass tmp = (*this)[pos1]; + (*this)[pos1] = (*this)[pos2]; + (*this)[pos2] =tmp; + } + +}; + +#else +template <typename _ListClass> +class plist_t +{ +public: + + ATTR_COLD plist_t(const std::size_t numElements = 0) + { + m_capacity = numElements; + if (m_capacity == 0) + m_list = NULL; + else + m_list = this->alloc(m_capacity); + m_count = 0; + } + + ATTR_COLD plist_t(const plist_t &rhs) + { + m_capacity = rhs.capacity(); + if (m_capacity == 0) + m_list = NULL; + else + m_list = this->alloc(m_capacity); + m_count = 0; + for (std::size_t i=0; i<rhs.size(); i++) + { + this->add(rhs[i]); + } + } + + ATTR_COLD plist_t &operator=(const plist_t &rhs) + { + this->clear(); + for (std::size_t i=0; i<rhs.size(); i++) + { + this->add(rhs[i]); + } + return *this; + } + + + ~plist_t() + { + if (m_list != NULL) + this->dealloc(m_list); + m_list = NULL; + } + + ATTR_HOT /* inline */ _ListClass *data() { return m_list; } + + ATTR_HOT /* inline */ _ListClass& operator[](std::size_t index) { return *(m_list + index); } + ATTR_HOT /* inline */ const _ListClass& operator[](std::size_t index) const { return *(m_list + index); } + + ATTR_HOT /* inline */ void add(const _ListClass &elem) + { + if (m_count >= m_capacity){ + std::size_t new_size = m_capacity * 2; + if (new_size < 32) + new_size = 32; + set_capacity(new_size); + } + + m_list[m_count++] = elem; + } + + ATTR_HOT /* inline */ void remove(const _ListClass &elem) + { + for (std::size_t i = 0; i < m_count; i++) + { + if (m_list[i] == elem) + { + m_count --; + while (i < m_count) + { + m_list[i] = m_list[i+1]; + i++; + } + return; + } + } + } + + ATTR_HOT /* inline */ void remove_at(const std::size_t pos) + { + //nl_assert((pos>=0) && (pos<m_count)); + m_count--; + for (std::size_t i = pos; i < m_count; i++) + { + m_list[i] = m_list[i+1]; + } + } + + ATTR_HOT /* inline */ void swap(const std::size_t pos1, const std::size_t pos2) + { + //nl_assert((pos1>=0) && (pos1<m_count)); + //nl_assert((pos2>=0) && (pos2<m_count)); + _ListClass tmp = m_list[pos1]; + m_list[pos1] = m_list[pos2]; + m_list[pos2] =tmp; + } + + ATTR_HOT /* inline */ bool contains(const _ListClass &elem) const + { + for (_ListClass *i = m_list; i < m_list + m_count; i++) + { + if (*i == elem) + return true; + } + return false; + } + + ATTR_HOT /* inline */ int indexof(const _ListClass &elem) const + { + for (std::size_t i = 0; i < m_count; i++) + { + if (m_list[i] == elem) + return i; + } + return -1; + } + + ATTR_HOT /* inline */ std::size_t size() const { return m_count; } + ATTR_HOT /* inline */ bool is_empty() const { return (m_count == 0); } + ATTR_HOT /* inline */ void clear() { m_count = 0; } + ATTR_HOT /* inline */ std::size_t capacity() const { return m_capacity; } + + ATTR_COLD void clear_and_free() + { + for (_ListClass *i = m_list; i < m_list + m_count; i++) + { + pfree(*i); + } + clear(); + } + +private: + ATTR_COLD void set_capacity(const std::size_t new_capacity) + { + std::size_t cnt = size(); + if (new_capacity > 0) + { + _ListClass *m_new = this->alloc(new_capacity); + _ListClass *pd = m_new; + + if (cnt > new_capacity) + cnt = new_capacity; + for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++) + *pd = *ps; + if (m_list != NULL) + this->dealloc(m_list); + m_list = m_new; + m_count = cnt; + } + else + { + if (m_list != NULL) + this->dealloc(m_list); + m_list = NULL; + m_count = 0; + } + m_capacity = new_capacity; + } + + _ListClass *alloc(const std::size_t n) + { + return palloc_array(_ListClass, n); + } + + void dealloc(_ListClass *p) + { + pfree_array(p); + } + + std::size_t m_count; + _ListClass * m_list; + std::size_t m_capacity; +}; +#endif + +// ---------------------------------------------------------------------------------------- +// pnamedlist_t: a simple list of elements which have a name() interface +// ---------------------------------------------------------------------------------------- + +template <class _ListClass> +class pnamedlist_t : public plist_t<_ListClass> +{ +public: + _ListClass find(const pstring &name) const + { + for (std::size_t i=0; i < this->size(); i++) + if (get_name((*this)[i]) == name) + return (*this)[i]; + return _ListClass(NULL); + } + + void remove_by_name(const pstring &name) + { + plist_t<_ListClass>::remove(find(name)); + } + + bool add(_ListClass dev, bool allow_duplicate) + { + if (allow_duplicate) + plist_t<_ListClass>::add(dev); + else + { + if (!(this->find(get_name(dev)) == _ListClass(NULL))) + return false; + plist_t<_ListClass>::add(dev); + } + return true; + } + +private: + template <typename T> static const pstring get_name(const T *elem) { return elem->name(); } + template <typename T> static const pstring get_name(T *elem) { return elem->name(); } + template <typename T> static const pstring get_name(const T &elem) { return elem.name(); } + +}; + + +// ---------------------------------------------------------------------------------------- +// pstack_t: a simple stack +// ---------------------------------------------------------------------------------------- + +template <class _StackClass> +class pstack_t +{ +public: + + ATTR_COLD pstack_t(const int numElements = 128) + : m_list(numElements) + { + } + + ATTR_COLD pstack_t(const pstack_t &rhs) + : m_list(rhs.m_list) + { + } + + ATTR_COLD pstack_t &operator=(const pstack_t &rhs) + { + m_list = rhs.m_list; + return *this; + } + + + ~pstack_t() + { + } + + ATTR_HOT /* inline */ void push(const _StackClass &elem) + { + m_list.add(elem); + } + + ATTR_HOT /* inline */ _StackClass peek() const + { + return m_list[m_list.size() - 1]; + } + + ATTR_HOT /* inline */ _StackClass pop() + { + _StackClass ret = peek(); + m_list.remove_at(m_list.size() - 1); + return ret; + } + + ATTR_HOT /* inline */ int count() const { return m_list.size(); } + ATTR_HOT /* inline */ bool empty() const { return (m_list.size() == 0); } + ATTR_HOT /* inline */ void reset() { m_list.reset(); } + ATTR_HOT /* inline */ int capacity() const { return m_list.capacity(); } + +private: + plist_t<_StackClass> m_list; +}; + +template <class _ListClass> +struct plinkedlist_element_t +{ + plinkedlist_element_t() : m_next(NULL) {} + _ListClass * m_next; + +}; + +// ---------------------------------------------------------------------------------------- +// plinkedlist_t: a simple linked list +// ---------------------------------------------------------------------------------------- + +template <class _ListClass> +class plinkedlist_t +{ +public: + + plinkedlist_t() : m_head(NULL) {} + + ATTR_HOT /* inline */ void insert(const _ListClass &before, _ListClass &elem) + { + if (m_head == &before) + { + elem.m_next = m_head; + m_head = elem; + } + else + { + _ListClass *p = m_head; + while (p != NULL) + { + if (p->m_next == &before) + { + elem->m_next = &before; + p->m_next = &elem; + return; + } + p = p->m_next; + } + //FXIME: throw a standard exception + //nl_assert_always(false, "element not found"); + } + } + + ATTR_HOT /* inline */ void insert(_ListClass &elem) + { + elem.m_next = m_head; + m_head = &elem; + } + + ATTR_HOT /* inline */ void add(_ListClass &elem) + { + _ListClass **p = &m_head; + while (*p != NULL) + { + p = &((*p)->m_next); + } + *p = &elem; + elem.m_next = NULL; + } + + ATTR_HOT /* inline */ void remove(const _ListClass &elem) + { + _ListClass **p = &m_head; + while (*p != &elem) + { + //nl_assert(*p != NULL); + p = &((*p)->m_next); + } + (*p) = elem.m_next; + } + + + ATTR_HOT static /* inline */ _ListClass *next(const _ListClass &elem) { return elem.m_next; } + ATTR_HOT static /* inline */ _ListClass *next(const _ListClass *elem) { return elem->m_next; } + ATTR_HOT /* inline */ _ListClass *first() const { return m_head; } + ATTR_HOT /* inline */ void clear() { m_head = NULL; } + ATTR_HOT /* inline */ bool is_empty() const { return (m_head == NULL); } + +private: + _ListClass *m_head; +}; + +// ---------------------------------------------------------------------------------------- +// string list +// ---------------------------------------------------------------------------------------- + +class pstring_list_t : public plist_t<pstring> +{ +public: + pstring_list_t() : plist_t<pstring>() { } + + pstring_list_t(const pstring &str, const pstring &onstr, bool ignore_empty = false) + : plist_t<pstring>() + { + + int p = 0; + int pn; + + pn = str.find(onstr, p); + while (pn>=0) + { + pstring t = str.substr(p, pn - p); + if (!ignore_empty || t.len() != 0) + this->add(t); + p = pn + onstr.len(); + pn = str.find(onstr, p); + } + if (p<str.len()) + { + pstring t = str.substr(p); + if (!ignore_empty || t.len() != 0) + this->add(t); + } + } + + static pstring_list_t splitexpr(const pstring &str, const pstring_list_t &onstrl) + { + pstring_list_t temp; + pstring col = ""; + + int i = 0; + while (i<str.len()) + { + int p = -1; + for (std::size_t j=0; j < onstrl.size(); j++) + { + if (std::strncmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].len())==0) + { + p = j; + break; + } + } + if (p>=0) + { + if (col != "") + temp.add(col); + col = ""; + temp.add(onstrl[p]); + i += onstrl[p].len(); + } + else + { + col += str.cstr()[i]; + i++; + } + } + if (col != "") + temp.add(col); + return temp; + } +}; + +#endif /* PLISTS_H_ */ |