diff --git a/scripts/src/lib.lua b/scripts/src/lib.lua index 51b92d098d2..3050e38b0a4 100644 --- a/scripts/src/lib.lua +++ b/scripts/src/lib.lua @@ -93,6 +93,7 @@ project "utils" MAME_DIR .. "src/lib/util/vbiparse.h", MAME_DIR .. "src/lib/util/vecstream.cpp", MAME_DIR .. "src/lib/util/vecstream.h", + MAME_DIR .. "src/lib/util/view.h", MAME_DIR .. "src/lib/util/wavwrite.cpp", MAME_DIR .. "src/lib/util/wavwrite.h", MAME_DIR .. "src/lib/util/xmlfile.cpp", diff --git a/src/lib/util/opresolv.cpp b/src/lib/util/opresolv.cpp index 74595d43abd..44ba0e51583 100644 --- a/src/lib/util/opresolv.cpp +++ b/src/lib/util/opresolv.cpp @@ -31,11 +31,11 @@ namespace util { option_resolution::option_resolution(const option_guide &guide) { // reserve space for entries - m_entries.reserve(guide.end() - guide.begin()); + m_entries.reserve(guide.entries().size()); // initialize each of the entries; can't use foreach because we need to scan the // ENUM_VALUE entries - for (auto iter = guide.begin(); iter != guide.end(); iter++) + for (auto iter = guide.entries().begin(); iter != guide.entries().end(); iter++) { // create the entry m_entries.emplace_back(*iter); @@ -49,7 +49,7 @@ option_resolution::option_resolution(const option_guide &guide) auto enum_value_end = enum_value_begin; // and identify all entries of type ENUM_VALUE - while (enum_value_end != guide.end() && enum_value_end->type() == option_guide::entry::option_type::ENUM_VALUE) + while (enum_value_end != guide.entries().end() && enum_value_end->type() == option_guide::entry::option_type::ENUM_VALUE) { iter++; enum_value_end++; diff --git a/src/lib/util/opresolv.h b/src/lib/util/opresolv.h index f6a98bf444a..d89c8197a75 100644 --- a/src/lib/util/opresolv.h +++ b/src/lib/util/opresolv.h @@ -45,6 +45,8 @@ #include #include +#include "view.h" + //************************************************************************** // TYPE DEFINITIONS @@ -118,19 +120,17 @@ public: }; // methods - const entry *begin() const { return m_begin; } - const entry *end() const { return m_end; } + const util::view &entries() const { return m_entries; } protected: - option_guide(const entry *begin, const entry *end) - : m_begin(begin), m_end(end) + option_guide(const entry *begin, size_t count) + : m_entries(begin, count) { } private: - const entry *m_begin; - const entry *m_end; + util::view m_entries; }; // ======================> option_guide_impl @@ -142,7 +142,7 @@ public: template option_guide_impl(T &&... elems) : std::array({ std::forward(elems)... }) - , option_guide(Count > 0 ? &(*this)[0] : nullptr, Count > 0 ? &(*this)[0] + Count : nullptr) + , option_guide(Count > 0 ? &(*this)[0] : nullptr, Count) { } }; diff --git a/src/lib/util/view.h b/src/lib/util/view.h new file mode 100644 index 00000000000..7bbccc977aa --- /dev/null +++ b/src/lib/util/view.h @@ -0,0 +1,154 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods +/****************************************************************************** + + view.h + + STL container for a view + +***************************************************************************/ + +#pragma once + +#ifndef __VIEW_H__ +#define __VIEW_H__ + +#include + +namespace util { + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +template +class view +{ +public: + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; + typedef T value_type; + typedef T &reference; + typedef const T &const_reference; + typedef T *pointer; + + class iterator + { + public: + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T &reference; + typedef T *pointer; + + typedef std::random_access_iterator_tag iterator_category; + + iterator(T *ptr) : m_ptr(ptr) { } + iterator(const iterator &that) : m_ptr(that) { } + + iterator& operator=(const iterator &that) { m_ptr = that.m_ptr; return *this; } + bool operator==(const iterator &that) const { return m_ptr == that.m_ptr; } + bool operator!=(const iterator &that) const { return m_ptr != that.m_ptr; } + bool operator<(const iterator &that) const { return m_ptr < that.m_ptr; } + bool operator>(const iterator &that) const { return m_ptr > that.m_ptr; } + bool operator<=(const iterator &that) const { return m_ptr <= that.m_ptr; } + bool operator>=(const iterator &that) const { return m_ptr >= that.m_ptr; } + iterator operator+(size_type i) const { return iterator(m_ptr + i); } + iterator operator-(size_type i) const { return iterator(m_ptr - i); } + difference_type operator-(const iterator &that) const { return m_ptr - that.m_ptr; } + + iterator& operator++() { m_ptr++; return *this; } + iterator operator++(int) { iterator result = *this; m_ptr++; return result; } + + reference operator*() const { return *m_ptr; } + pointer operator->() const { return m_ptr; } + operator T*() const { return m_ptr; } + + private: + T *m_ptr; + }; + + class const_iterator + { + public: + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef const T &const_reference; + typedef const T *const_pointer; + + typedef std::random_access_iterator_tag iterator_category; + + const_iterator(const T *ptr) : m_ptr(ptr) { } + const_iterator(const iterator &that) : m_ptr(that) { } + const_iterator(const const_iterator &that) : m_ptr(that) { } + + const_iterator& operator=(const const_iterator &that) { m_ptr = that.m_ptr; return *this; } + bool operator==(const const_iterator &that) const { return m_ptr == that.m_ptr; } + bool operator!=(const const_iterator &that) const { return m_ptr != that.m_ptr; } + bool operator<(const const_iterator &that) const { return m_ptr < that.m_ptr; } + bool operator>(const const_iterator &that) const { return m_ptr > that.m_ptr; } + bool operator<=(const const_iterator &that) const { return m_ptr <= that.m_ptr; } + bool operator>=(const const_iterator &that) const { return m_ptr >= that.m_ptr; } + const_iterator operator+(size_type i) const { return const_iterator(m_ptr + i); } + const_iterator operator-(size_type i) const { return const_iterator(m_ptr - i); } + difference_type operator-(const const_iterator &that) const { return m_ptr - that.m_ptr; } + + const_iterator& operator++() { m_ptr++; return *this; } + const_iterator operator++(int) { const_iterator result = *this; m_ptr++; return result; } + + const_reference operator*() const { return *m_ptr; } + const_pointer operator->() const { return m_ptr; } + operator T*() const { return m_ptr; } + + private: + const T *m_ptr; + }; + + view(T *ptr, std::size_t size) + : m_begin(ptr) + , m_end(ptr + size) + { + } + + view(const view &that) + : m_begin(that.m_begin) + , m_end(that.m_end) + { + } + + // iteration + iterator begin() { return m_begin; } + const_iterator begin() const { return m_begin; } + const_iterator cbegin() const { return m_begin; } + iterator end() { return m_end; } + const_iterator end() const { return m_end; } + const_iterator cend() const { return m_end; } + + // capacity + size_type size() const { return m_end - m_begin; } + size_type max_size() const { return size(); } + bool empty() const { return size() > 0; } + + // element access + reference front() { return *this[0]; } + const_reference front() const { return *this[0]; } + reference back() { return *this[size() - 1]; } + const_reference back() const { return *this[size() - 1]; } + reference operator[] (size_type n) { return m_begin.m_ptr[n]; } + const_reference operator[] (size_type n) const { return m_begin.m_ptr[n]; } + reference at(size_type n) { check_in_bounds(n); return *this[n]; } + const_reference at(size_type n) const { check_in_bounds(n); return *this[n]; } + +private: + iterator m_begin; + iterator m_end; + + void check_in_bounds(size_type n) + { + if (n < 0 || n >= size()) + throw new std::out_of_range("invalid view subscript"); + } +}; + +}; // namespace util + +#endif // __VIEW_H__