Introduced an STL container for a view (util::view<T>), and changed opresolv to use it

This commit is contained in:
Nathan Woods 2016-09-11 10:16:13 -04:00
parent d4744d24ec
commit 91fb8f5bc3
4 changed files with 165 additions and 10 deletions

View File

@ -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",

View File

@ -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++;

View File

@ -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
View 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__