summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author Nathan Woods <npwoods@mess.org>2016-09-11 10:16:13 -0400
committer Nathan Woods <npwoods@mess.org>2016-09-11 10:49:23 -0400
commit91fb8f5bc3ff97df38344497af53ab45b9ce1895 (patch)
tree9f50c02bcc5a00e76382456f9e253a57327395d3 /src/lib
parentd4744d24ecbdbf51bf5f3404e057df84823ffa03 (diff)
Introduced an STL container for a view (util::view<T>), and changed opresolv to use it
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/util/opresolv.cpp6
-rw-r--r--src/lib/util/opresolv.h14
-rw-r--r--src/lib/util/view.h154
3 files changed, 164 insertions, 10 deletions
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 <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)
{
}
};
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 <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__