summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2017-03-30 15:23:23 +1100
committer Vas Crabb <vas@vastheman.com>2017-03-30 15:51:14 +1100
commit5e8fefbb1214e9936253a81da4946cc42cc20b9d (patch)
tree30d297c7eb05c68326488bf1618505a8d00bd135 /src/lib/netlist
parent35b673ea45da6b4759f170813f99c124c7db9d70 (diff)
Turn psring iterator into a real forward iterator that works with standard algorithms.
There are a few changes to achieve this: * Rename to const_iterator since it's immutable * Typedef iterator to const_iterator for now as there's no mutable iterator * Add default constrcutor and operator-> required by concept, const-qualify operators * Remove operator+ and operator+= since it's not a random-access iterator (use std::next and std::advance instead) * Return reference/pointer to a proxy rather than a code_t value from opertator*/operator-> The final change is required to meet the requirement that operator* for two equivalent forward iterators return an equivalent reference. The pstring doesn't actually contain a sequence of code_t, so there's no way to return a reference to code_t directly. Instead, a reference to a proxy object aliased on the string storage is returned. The proxy is implicitly convertible to code_t. The most noticeable side effect is that auto c = *s.begin() or for (auto c : s) won't work. You need to do for (auto &c : s) or for (code_t c : s) instead.
Diffstat (limited to 'src/lib/netlist')
-rw-r--r--src/lib/netlist/nl_setup.cpp14
-rw-r--r--src/lib/netlist/plib/pfunction.cpp2
-rw-r--r--src/lib/netlist/plib/poptions.cpp6
-rw-r--r--src/lib/netlist/plib/pstring.cpp26
-rw-r--r--src/lib/netlist/plib/pstring.h84
-rw-r--r--src/lib/netlist/plib/putil.cpp2
-rw-r--r--src/lib/netlist/prg/nltool.cpp2
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp2
8 files changed, 85 insertions, 53 deletions
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index a3a49513a9f..c48ca48ae0c 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -100,7 +100,7 @@ void setup_t::register_model(const pstring &model_in)
if (pos == model_in.end())
log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in);
pstring model = model_in.left(pos).trim().ucase();
- pstring def = model_in.substr(pos + 1).trim();
+ pstring def = model_in.substr(std::next(pos, 1)).trim();
if (!m_models.insert({model, def}).second)
log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in);
}
@@ -818,11 +818,11 @@ void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
log().fatal(MF_1_MODEL_NOT_FOUND, model_in);
}
- pstring remainder=model.substr(pos+1).trim();
+ pstring remainder=model.substr(std::next(pos, 1)).trim();
if (!remainder.endsWith(")"))
log().fatal(MF_1_MODEL_ERROR_1, model);
// FIMXE: Not optimal
- remainder = remainder.left(remainder.begin() + (remainder.len() - 1));
+ remainder = remainder.left(std::next(remainder.begin(), (remainder.len() - 1)));
std::vector<pstring> pairs(plib::psplit(remainder," ", true));
for (pstring &pe : pairs)
@@ -830,7 +830,7 @@ void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
auto pose = pe.find("=");
if (pose == pe.end())
log().fatal(MF_1_MODEL_ERROR_ON_PAIR_1, model);
- map[pe.left(pose).ucase()] = pe.substr(pose+1);
+ map[pe.left(pose).ucase()] = pe.substr(std::next(pose, 1));
}
}
@@ -854,7 +854,7 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity)
pstring tmp = model_value_str(map, entity);
nl_double factor = NL_FCONST(1.0);
- auto p = tmp.begin() + (tmp.len() - 1);
+ auto p = std::next(tmp.begin(), (tmp.len() - 1));
switch (*p)
{
case 'M': factor = 1e6; break;
@@ -870,7 +870,7 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity)
log().fatal(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity);
}
if (factor != NL_FCONST(1.0))
- tmp = tmp.left(tmp.begin() + (tmp.len() - 1));
+ tmp = tmp.left(std::next(tmp.begin(), (tmp.len() - 1)));
return tmp.as_double() * factor;
}
@@ -976,7 +976,7 @@ void setup_t::register_define(pstring defstr)
{
auto p = defstr.find("=");
if (p != defstr.end())
- register_define(defstr.left(p), defstr.substr(p+1));
+ register_define(defstr.left(p), defstr.substr(std::next(p, 1)));
else
register_define(defstr, "1");
}
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 0f48860d15b..7113a6e07fb 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -86,7 +86,7 @@ static int get_prio(pstring v)
{
if (v == "(" || v == ")")
return 1;
- else if (v.left(v.begin()+1) >= "a" && v.left(v.begin()+1) <= "z")
+ else if (v.left(std::next(v.begin(),1)) >= "a" && v.left(std::next(v.begin(),1)) <= "z")
return 0;
else if (v == "*" || v == "/")
return 20;
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp
index 9defcf84975..698c813129c 100644
--- a/src/lib/netlist/plib/poptions.cpp
+++ b/src/lib/netlist/plib/poptions.cpp
@@ -133,8 +133,8 @@ namespace plib {
}
else if (arg.startsWith("-"))
{
- auto p = arg.begin() + 1;
- opt = getopt_short(arg.substr(p,p + 1));
+ auto p = std::next(arg.begin(), 1);
+ opt = getopt_short(arg.substr(p, std::next(p, 1)));
++p;
if (p != arg.end())
{
@@ -226,7 +226,7 @@ namespace plib {
{
line += v + "|";
}
- line = line.left(line.begin() + (line.len() - 1));
+ line = line.left(std::next(line.begin(), (line.len() - 1)));
}
else
line += "Value";
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index 5396f333358..90dc1f82f1d 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -104,7 +104,7 @@ void pstring_t<F>::pcopy(const mem_t *from, std::size_t size)
}
template<typename F>
-const pstring_t<F> pstring_t<F>::substr(const iterator &start, const iterator &end) const
+const pstring_t<F> pstring_t<F>::substr(const const_iterator &start, const const_iterator &end) const
{
pstring_t ret;
//FIXME: throw ?
@@ -116,7 +116,7 @@ template<typename F>
const pstring_t<F> pstring_t<F>::ucase() const
{
pstring_t ret = "";
- for (auto c : *this)
+ for (code_t c : *this)
if (c >= 'a' && c <= 'z')
ret += (c - 'a' + 'A');
else
@@ -125,12 +125,12 @@ const pstring_t<F> pstring_t<F>::ucase() const
}
template<typename F>
-typename pstring_t<F>::iterator pstring_t<F>::find_first_not_of(const pstring_t &no) const
+typename pstring_t<F>::const_iterator pstring_t<F>::find_first_not_of(const pstring_t &no) const
{
for (auto it = begin(); it != end(); ++it)
{
bool f = true;
- for (auto const jt : no)
+ for (code_t const jt : no)
{
if (*it == jt)
{
@@ -145,14 +145,14 @@ typename pstring_t<F>::iterator pstring_t<F>::find_first_not_of(const pstring_t
}
template<typename F>
-typename pstring_t<F>::iterator pstring_t<F>::find_last_not_of(const pstring_t &no) const
+typename pstring_t<F>::const_iterator pstring_t<F>::find_last_not_of(const pstring_t &no) const
{
- /* FIXME: reverse iterator */
- iterator last_found = end();
+ /* FIXME: reverse const_iterator */
+ const_iterator last_found = end();
for (auto it = begin(); it != end(); ++it)
{
bool f = true;
- for (auto const jt : no)
+ for (code_t const jt : no)
{
if (*it == jt)
{
@@ -167,11 +167,11 @@ typename pstring_t<F>::iterator pstring_t<F>::find_last_not_of(const pstring_t &
}
template<typename F>
-typename pstring_t<F>::iterator pstring_t<F>::find(const pstring_t &search, iterator start) const
+typename pstring_t<F>::const_iterator pstring_t<F>::find(const pstring_t &search, const_iterator start) const
{
for (; start != end(); ++start)
{
- iterator itc(start);
+ const_iterator itc(start);
auto cmp = search.begin();
while (itc != end() && cmp != search.end() && *itc == *cmp)
{
@@ -185,7 +185,7 @@ typename pstring_t<F>::iterator pstring_t<F>::find(const pstring_t &search, iter
}
template<typename F>
-typename pstring_t<F>::iterator pstring_t<F>::find(const code_t search, iterator start) const
+typename pstring_t<F>::const_iterator pstring_t<F>::find(const code_t search, const_iterator start) const
{
mem_t buf[traits::MAXCODELEN+1] = { 0 };
traits::encode(search, buf);
@@ -205,7 +205,7 @@ pstring_t<F> pstring_t<F>::replace(const pstring_t &search, const pstring_t &rep
{
ret += substr(last_s, s);
ret += replace;
- last_s = s + slen;
+ last_s = std::next(s, slen);
s = find(search, last_s);
}
ret += substr(last_s, end());
@@ -225,7 +225,7 @@ const pstring_t<F> pstring_t<F>::rtrim(const pstring_t &ws) const
if (f==end())
return pstring_t("");
else
- return substr(begin(), f + 1);
+ return substr(begin(), std::next(f, 1));
}
template<typename F>
diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h
index 394b8c193de..7bb037b42cd 100644
--- a/src/lib/netlist/plib/pstring.h
+++ b/src/lib/netlist/plib/pstring.h
@@ -82,25 +82,57 @@ public:
// assignment operators
pstring_t &operator=(const pstring_t &string) { pcopy(string); return *this; }
- struct iterator final : public std::iterator<std::forward_iterator_tag, mem_t>
+ class const_iterator final
{
- const mem_t * p;
public:
- explicit constexpr iterator(const mem_t *x) noexcept : p(x) {}
- iterator(const iterator &rhs) noexcept = default;
- iterator(iterator &&rhs) noexcept { p = rhs.p; }
- iterator &operator=(const iterator &it) { p = it.p; return *this; }
- iterator& operator++() noexcept { p += traits::codelen(p); return *this; }
- iterator operator++(int) noexcept { iterator tmp(*this); operator++(); return tmp; }
- bool operator==(const iterator& rhs) noexcept { return p==rhs.p; }
- bool operator!=(const iterator& rhs) noexcept { return p!=rhs.p; }
- const code_t operator*() noexcept { return traits::code(p); }
- iterator& operator+=(size_type count) { while (count>0) { --count; ++(*this); } return *this; }
- friend iterator operator+(iterator lhs, const size_type &rhs) { return (lhs += rhs); }
+ class value_type final
+ {
+ public:
+ value_type() = delete;
+ value_type(const value_type &) = delete;
+ value_type(value_type &&) = delete;
+ value_type &operator=(const value_type &) = delete;
+ value_type &operator=(value_type &&) = delete;
+ operator code_t() const noexcept { return traits::code(&m); }
+ private:
+ const mem_t m;
+ };
+
+ typedef value_type const *pointer;
+ typedef value_type const &reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ const_iterator() noexcept : p(nullptr) { }
+ explicit constexpr const_iterator(const mem_t *x) noexcept : p(x) { }
+ const_iterator(const const_iterator &rhs) noexcept = default;
+ const_iterator(const_iterator &&rhs) noexcept = default;
+ const_iterator &operator=(const const_iterator &rhs) noexcept = default;
+ const_iterator &operator=(const_iterator &&rhs) noexcept = default;
+
+ const_iterator& operator++() noexcept { p += traits::codelen(p); return *this; }
+ const_iterator operator++(int) noexcept { const_iterator tmp(*this); operator++(); return tmp; }
+
+ bool operator==(const const_iterator& rhs) const noexcept { return p == rhs.p; }
+ bool operator!=(const const_iterator& rhs) const noexcept { return p != rhs.p; }
+
+ reference operator*() const noexcept { return *reinterpret_cast<pointer>(p); }
+ pointer operator->() const noexcept { return reinterpret_cast<pointer>(p); }
+
+ private:
+ template <typename G> friend struct pstring_t;
+ const mem_t * p;
};
- iterator begin() const { return iterator(m_ptr->str()); }
- iterator end() const { return iterator(m_ptr->str() + blen()); }
+ // no non-const const_iterator for now
+ typedef const_iterator iterator;
+
+ iterator begin() { return iterator(m_ptr->str()); }
+ iterator end() { return iterator(m_ptr->str() + blen()); }
+ const_iterator begin() const { return const_iterator(m_ptr->str()); }
+ const_iterator end() const { return const_iterator(m_ptr->str() + blen()); }
+ const_iterator cbegin() const { return const_iterator(m_ptr->str()); }
+ const_iterator cend() const { return const_iterator(m_ptr->str() + blen()); }
// C string conversion helpers
const mem_t *c_str() const { return m_ptr->str(); }
@@ -141,20 +173,20 @@ public:
pstring_t& operator+=(const code_t c) { mem_t buf[traits::MAXCODELEN+1] = { 0 }; traits::encode(c, buf); pcat(buf); return *this; }
friend pstring_t operator+(const pstring_t &lhs, const code_t rhs) { return pstring_t(lhs) += rhs; }
- iterator find(const pstring_t &search, iterator start) const;
- iterator find(const pstring_t &search) const { return find(search, begin()); }
- iterator find(const code_t search, iterator start) const;
- iterator find(const code_t search) const { return find(search, begin()); }
+ const_iterator find(const pstring_t &search, const_iterator start) const;
+ const_iterator find(const pstring_t &search) const { return find(search, begin()); }
+ const_iterator find(const code_t search, const_iterator start) const;
+ const_iterator find(const code_t search) const { return find(search, begin()); }
- const pstring_t substr(const iterator &start, const iterator &end) const ;
- const pstring_t substr(const iterator &start) const { return substr(start, end()); }
- const pstring_t substr(size_type start) const { return (start >= len()) ? pstring_t("") : substr(begin() + start, end()); }
+ const pstring_t substr(const const_iterator &start, const const_iterator &end) const;
+ const pstring_t substr(const const_iterator &start) const { return substr(start, end()); }
+ const pstring_t substr(size_type start) const { return (start >= len()) ? pstring_t("") : substr(std::next(begin(), start), end()); }
- const pstring_t left(iterator leftof) const { return substr(begin(), leftof); }
- const pstring_t right(iterator pos) const { return substr(pos, end()); }
+ const pstring_t left(const_iterator leftof) const { return substr(begin(), leftof); }
+ const pstring_t right(const_iterator pos) const { return substr(pos, end()); }
- iterator find_first_not_of(const pstring_t &no) const;
- iterator find_last_not_of(const pstring_t &no) const;
+ const_iterator find_first_not_of(const pstring_t &no) const;
+ const_iterator find_last_not_of(const pstring_t &no) const;
const pstring_t ltrim(const pstring_t &ws = pstring_t(" \t\n\r")) const;
const pstring_t rtrim(const pstring_t &ws = pstring_t(" \t\n\r")) const;
diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp
index 0f09f512242..234b4e6cbaa 100644
--- a/src/lib/netlist/plib/putil.cpp
+++ b/src/lib/netlist/plib/putil.cpp
@@ -52,7 +52,7 @@ namespace plib
pstring t = str.substr(p, pn);
if (!ignore_empty || t.len() != 0)
ret.push_back(t);
- p = pn + onstr.len();
+ p = std::next(pn, onstr.len());
pn = str.find(onstr, p);
}
if (p != str.end())
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index e797399b9a1..ba0526b5408 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -421,7 +421,7 @@ void tool_app_t::mac_out(const pstring &s, const bool cont)
if (cont)
{
unsigned adj = 0;
- for (auto x : s)
+ for (auto &x : s)
adj += (x == '\t' ? 3 : 0);
pout("{1}\\\n", s.rpad(" ", RIGHT-1-adj));
}
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index 305dcf4853d..9589794e696 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -318,7 +318,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
{
if (m[1].len() != 4)
fprintf(stderr, "error with model desc %s\n", model.c_str());
- pins = m[1].left(m[1].begin() + 3);
+ pins = m[1].left(std::next(m[1].begin(), 3));
}
add_device("QBJT_EB", tt[0], m[0]);
add_term(tt[1], tt[0] + "." + pins.code_at(0));