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:
Vas Crabb 2016-09-13 11:01:06 +10:00 committed by GitHub
commit 9b88a353ba
3 changed files with 83 additions and 10 deletions

View File

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

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 "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)
{
}
};