mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Merge pull request #1393 from npwoods/view_container
Introduced an STL container for a view (util::view<T>), and changed opresolv to use it
This commit is contained in:
commit
9b88a353ba
@ -17,6 +17,7 @@
|
||||
#include "corealloc.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -351,4 +352,76 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// ======================> contiguous_sequence_wrapper
|
||||
|
||||
namespace util {
|
||||
|
||||
// wraps an existing sequence of values
|
||||
template<typename T>
|
||||
class contiguous_sequence_wrapper
|
||||
{
|
||||
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;
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
contiguous_sequence_wrapper(T *ptr, std::size_t size)
|
||||
: m_begin(ptr)
|
||||
, m_end(ptr + size)
|
||||
{
|
||||
}
|
||||
|
||||
contiguous_sequence_wrapper(const contiguous_sequence_wrapper &that) = default;
|
||||
|
||||
// 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; }
|
||||
|
||||
// reverse iteration
|
||||
reverse_iterator rbegin() { return std::reverse_iterator<iterator>(end()); }
|
||||
const_reverse_iterator rbegin() const { return std::reverse_iterator<const_iterator>(end()); }
|
||||
const_reverse_iterator crbegin() const { return std::reverse_iterator<const_iterator>(cend()); }
|
||||
reverse_iterator rend() { return std::reverse_iterator<iterator>(begin()); }
|
||||
const_reverse_iterator rend() const { return std::reverse_iterator<iterator>(begin()); }
|
||||
const_reverse_iterator crend() const { return std::reverse_iterator<iterator>(begin()); }
|
||||
|
||||
// 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 operator[](0); }
|
||||
const_reference front() const { return operator[](0); }
|
||||
reference back() { return operator[](size() - 1); }
|
||||
const_reference back() const { return operator[](size() - 1); }
|
||||
reference operator[] (size_type n) { return m_begin[n]; }
|
||||
const_reference operator[] (size_type n) const { return m_begin[n]; }
|
||||
reference at(size_type n) { check_in_bounds(n); return operator[](n); }
|
||||
const_reference at(size_type n) const { check_in_bounds(n); return operator[](n); }
|
||||
|
||||
private:
|
||||
iterator m_begin;
|
||||
iterator m_end;
|
||||
|
||||
void check_in_bounds(size_type n)
|
||||
{
|
||||
if (n < 0 || n >= size())
|
||||
throw std::out_of_range("invalid contiguous_sequence_wrapper<T> subscript");
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace util
|
||||
|
||||
#endif
|
||||
|
@ -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 "coretmpl.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::contiguous_sequence_wrapper<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::contiguous_sequence_wrapper<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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user