mirror of
https://github.com/holub/mame
synced 2025-05-31 10:01:51 +03:00
Introduced an STL container for a view (util::view<T>), and changed opresolv to use it
This commit is contained in:
parent
d4744d24ec
commit
91fb8f5bc3
@ -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",
|
||||
|
@ -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++;
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#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<const entry> &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<const entry> m_entries;
|
||||
};
|
||||
|
||||
// ======================> option_guide_impl
|
||||
@ -142,7 +142,7 @@ public:
|
||||
template<typename... T>
|
||||
option_guide_impl(T &&... elems)
|
||||
: std::array<option_guide::entry, Count>({ std::forward<T>(elems)... })
|
||||
, option_guide(Count > 0 ? &(*this)[0] : nullptr, Count > 0 ? &(*this)[0] + Count : nullptr)
|
||||
, option_guide(Count > 0 ? &(*this)[0] : nullptr, Count)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
154
src/lib/util/view.h
Normal file
154
src/lib/util/view.h
Normal file
@ -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 <cstddef>
|
||||
|
||||
namespace util {
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
template<typename T >
|
||||
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<T> subscript");
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace util
|
||||
|
||||
#endif // __VIEW_H__
|
Loading…
Reference in New Issue
Block a user