summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2017-03-30 20:20:00 +0200
committer couriersud <couriersud@gmx.org>2017-03-30 22:06:03 +0200
commitac13946ffbec538f5fc193843fae7dd513b9c58e (patch)
tree44ee3cdb306b6cbd214c12bd8cb46dc1e6e6fb19
parentac856bc4d1d22a4be0cd8c86ec7da66761becc96 (diff)
Change pstring to use std::string as storage container.
This removes all allocation code from pstring. const_iterator is consequently now based on pstring::const_iterator. Removed pstring_buffer. This was class wasn't a good idea. Vas was right: This change did not impact runtime performance. Startup performance (string intensive) increased. (nw)
-rw-r--r--src/devices/machine/netlist.cpp14
-rw-r--r--src/devices/machine/netlist.h1
-rw-r--r--src/lib/netlist/nl_base.cpp2
-rw-r--r--src/lib/netlist/nl_base.h1
-rw-r--r--src/lib/netlist/nl_setup.cpp26
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp2
-rw-r--r--src/lib/netlist/plib/pfunction.cpp4
-rw-r--r--src/lib/netlist/plib/poptions.cpp10
-rw-r--r--src/lib/netlist/plib/pparser.cpp34
-rw-r--r--src/lib/netlist/plib/pparser.h2
-rw-r--r--src/lib/netlist/plib/pstream.cpp2
-rw-r--r--src/lib/netlist/plib/pstream.h18
-rw-r--r--src/lib/netlist/plib/pstring.cpp396
-rw-r--r--src/lib/netlist/plib/pstring.h298
-rw-r--r--src/lib/netlist/plib/putil.cpp26
-rw-r--r--src/lib/netlist/prg/nltool.cpp18
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp3
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp8
-rw-r--r--src/lib/netlist/tools/nl_convert.h2
19 files changed, 243 insertions, 624 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 3c61bb60c2b..953ad23c72b 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -501,7 +501,7 @@ void netlist_mame_analog_output_t::static_set_params(device_t &device, const cha
void netlist_mame_analog_output_t::custom_netlist_additions(netlist::setup_t &setup)
{
const pstring pin(m_in, pstring::UTF8);
- pstring dname = "OUT_" + pin;
+ pstring dname = pstring("OUT_") + pin;
m_delegate.bind_relative_to(owner()->machine().root_device());
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
@@ -783,7 +783,7 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, devi
netlist_mame_device_t::~netlist_mame_device_t()
{
- pstring::resetmem();
+ LOG_DEV_CALLS(("~netlist_mame_device_t\n"));
}
void netlist_mame_device_t::static_set_constructor(device_t &device, void (*setup_func)(netlist::setup_t &))
@@ -795,9 +795,15 @@ void netlist_mame_device_t::static_set_constructor(device_t &device, void (*setu
void netlist_mame_device_t::device_config_complete()
{
- LOG_DEV_CALLS(("device_config_complete\n"));
+ LOG_DEV_CALLS(("device_config_complete %s %s\n", this->mconfig().gamedrv().name, this->tag()));
+}
+
+void netlist_mame_device_t::device_validity_check(validity_checker &valid) const
+{
+ LOG_DEV_CALLS(("device_validity_check %s\n", this->mconfig().gamedrv().name));
}
+
void netlist_mame_device_t::device_start()
{
LOG_DEV_CALLS(("device_start entry %s\n", tag()));
@@ -970,8 +976,6 @@ void netlist_mame_cpu_device_t::device_start()
{
netlist_mame_device_t::device_start();
- LOG_DEV_CALLS(("cpu device_start %s\n", tag()));
-
// State support
state_add(STATE_GENPC, "GENPC", m_genPC).noshow();
diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h
index e23f50ed62c..a4e13611e82 100644
--- a/src/devices/machine/netlist.h
+++ b/src/devices/machine/netlist.h
@@ -123,6 +123,7 @@ protected:
// device_t overrides
virtual void device_config_complete() override;
+ virtual void device_validity_check(validity_checker &valid) const override;
virtual void device_start() override;
virtual void device_stop() override;
virtual void device_reset() override;
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 7d91c57c7c0..4be3042d6d5 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -261,8 +261,6 @@ netlist_t::~netlist_t()
{
m_nets.clear();
m_devices.clear();
-
- pstring::resetmem();
}
nl_double netlist_t::gmin() const
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 9b6b0fbaf7b..74faabef3b6 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -1349,7 +1349,6 @@ namespace netlist
this->emplace(i, dev, pstring(names.p[i], pstring::UTF8));
}
};
-
// -----------------------------------------------------------------------------
// inline implementations
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index c48ca48ae0c..9625ed5b15b 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -41,8 +41,6 @@ setup_t::~setup_t()
m_param_values.clear();
m_sources.clear();
-
- pstring::resetmem();
}
pstring setup_t::build_fqn(const pstring &obj_name) const
@@ -97,10 +95,10 @@ bool setup_t::device_exists(const pstring &name) const
void setup_t::register_model(const pstring &model_in)
{
auto pos = model_in.find(" ");
- if (pos == model_in.end())
+ if (pos == pstring::npos)
log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in);
pstring model = model_in.left(pos).trim().ucase();
- pstring def = model_in.substr(std::next(pos, 1)).trim();
+ pstring def = model_in.substr(pos + 1).trim();
if (!m_models.insert({model, def}).second)
log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in);
}
@@ -791,13 +789,13 @@ static pstring model_string(detail::model_map_t &map)
void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
{
pstring model = model_in;
- pstring::iterator pos(nullptr);
+ std::size_t pos = 0;
pstring key;
while (true)
{
pos = model.find("(");
- if (pos != model.end()) break;
+ if (pos != pstring::npos) break;
key = model.ucase();
auto i = m_models.find(key);
@@ -818,19 +816,19 @@ 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(std::next(pos, 1)).trim();
+ pstring remainder = model.substr(pos + 1).trim();
if (!remainder.endsWith(")"))
log().fatal(MF_1_MODEL_ERROR_1, model);
// FIMXE: Not optimal
- remainder = remainder.left(std::next(remainder.begin(), (remainder.len() - 1)));
+ remainder = remainder.left(remainder.len() - 1);
std::vector<pstring> pairs(plib::psplit(remainder," ", true));
for (pstring &pe : pairs)
{
auto pose = pe.find("=");
- if (pose == pe.end())
+ if (pose == pstring::npos)
log().fatal(MF_1_MODEL_ERROR_ON_PAIR_1, model);
- map[pe.left(pose).ucase()] = pe.substr(std::next(pose, 1));
+ map[pe.left(pose).ucase()] = pe.substr(pose + 1);
}
}
@@ -854,7 +852,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 = std::next(tmp.begin(), (tmp.len() - 1));
+ auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.len() - 1));
switch (*p)
{
case 'M': factor = 1e6; break;
@@ -870,7 +868,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(std::next(tmp.begin(), (tmp.len() - 1)));
+ tmp = tmp.left(tmp.len() - 1);
return tmp.as_double() * factor;
}
@@ -975,8 +973,8 @@ bool setup_t::parse_stream(plib::putf8_reader &istrm, const pstring &name)
void setup_t::register_define(pstring defstr)
{
auto p = defstr.find("=");
- if (p != defstr.end())
- register_define(defstr.left(p), defstr.substr(std::next(p, 1)));
+ if (p != pstring::npos)
+ register_define(defstr.left(p), defstr.substr(p+1));
else
register_define(defstr, "1");
}
diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp
index edcc2544f7a..86d059d9247 100644
--- a/src/lib/netlist/plib/pfmtlog.cpp
+++ b/src/lib/netlist/plib/pfmtlog.cpp
@@ -24,7 +24,7 @@ plog_dispatch_intf::~plog_dispatch_intf()
pfmt::pfmt(const pstring &fmt)
: m_str(m_str_buf), m_allocated(0), m_arg(0)
{
- std::size_t l = fmt.blen() + 1;
+ std::size_t l = fmt.size() + 1;
if (l>sizeof(m_str_buf))
{
m_allocated = 2 * l;
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 7113a6e07fb..c369dc2ed90 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(std::next(v.begin(),1)) >= "a" && v.left(std::next(v.begin(),1)) <= "z")
+ else if (v.left(1) >= "a" && v.left(1) <= "z")
return 0;
else if (v == "*" || v == "/")
return 20;
@@ -111,7 +111,7 @@ void pfunction::compile_infix(const std::vector<pstring> &inputs, const pstring
{
// Shunting-yard infix parsing
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
- std::vector<pstring> sexpr(plib::psplit(expr.replace(" ",""), sep));
+ std::vector<pstring> sexpr(plib::psplit(expr.replace_all(" ",""), sep));
std::stack<pstring> opstk;
std::vector<pstring> postfix;
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp
index 698c813129c..c79fb28fe58 100644
--- a/src/lib/netlist/plib/poptions.cpp
+++ b/src/lib/netlist/plib/poptions.cpp
@@ -133,17 +133,19 @@ namespace plib {
}
else if (arg.startsWith("-"))
{
- auto p = std::next(arg.begin(), 1);
- opt = getopt_short(arg.substr(p, std::next(p, 1)));
+ std::size_t p = 1;
+ opt = getopt_short(arg.substr(p, 1));
++p;
- if (p != arg.end())
+ if (p < arg.len())
{
has_equal_arg = true;
opt_arg = arg.substr(p);
}
}
else
+ {
return i;
+ }
if (opt == nullptr)
return i;
if (opt->has_argument())
@@ -226,7 +228,7 @@ namespace plib {
{
line += v + "|";
}
- line = line.left(std::next(line.begin(), (line.len() - 1)));
+ line = line.left(line.len() - 1);
}
else
line += "Value";
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 679f2942729..5253417695a 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -183,7 +183,7 @@ ptokenizer::token_t ptokenizer::get_token_internal()
{
/* skip ws */
pstring::code_t c = getc();
- while (m_whitespace.find(c) != m_whitespace.end())
+ while (m_whitespace.find(c) != pstring::npos)
{
c = getc();
if (eof())
@@ -191,7 +191,7 @@ ptokenizer::token_t ptokenizer::get_token_internal()
return token_t(ENDOFFILE);
}
}
- if (m_number_chars_start.find(c) != m_number_chars_start.end())
+ if (m_number_chars_start.find(c) != pstring::npos)
{
/* read number while we receive number or identifier chars
* treat it as an identifier when there are identifier chars in it
@@ -200,9 +200,9 @@ ptokenizer::token_t ptokenizer::get_token_internal()
token_type ret = NUMBER;
pstring tokstr = "";
while (true) {
- if (m_identifier_chars.find(c) != m_identifier_chars.end() && m_number_chars.find(c) == m_number_chars.end())
+ if (m_identifier_chars.find(c) != pstring::npos && m_number_chars.find(c) == pstring::npos)
ret = IDENTIFIER;
- else if (m_number_chars.find(c) == m_number_chars.end())
+ else if (m_number_chars.find(c) == pstring::npos)
break;
tokstr += c;
c = getc();
@@ -210,11 +210,11 @@ ptokenizer::token_t ptokenizer::get_token_internal()
ungetc(c);
return token_t(ret, tokstr);
}
- else if (m_identifier_chars.find(c) != m_identifier_chars.end())
+ else if (m_identifier_chars.find(c) != pstring::npos)
{
/* read identifier till non identifier char */
pstring tokstr = "";
- while (m_identifier_chars.find(c) != m_identifier_chars.end())
+ while (m_identifier_chars.find(c) != pstring::npos)
{
tokstr += c;
c = getc();
@@ -241,7 +241,7 @@ ptokenizer::token_t ptokenizer::get_token_internal()
{
/* read identifier till first identifier char or ws */
pstring tokstr = "";
- while ((m_identifier_chars.find(c) == m_identifier_chars.end()) && (m_whitespace.find(c) == m_whitespace.end()))
+ while ((m_identifier_chars.find(c) == pstring::npos) && (m_whitespace.find(c) == pstring::npos))
{
tokstr += c;
/* expensive, check for single char tokens */
@@ -385,33 +385,33 @@ ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
pstring ppreprocessor::replace_macros(const pstring &line)
{
std::vector<pstring> elems(psplit(line, m_expr_sep));
- pstringbuffer ret("");
+ pstring ret("");
for (auto & elem : elems)
{
define_t *def = get_define(elem);
if (def != nullptr)
- ret.cat(def->m_replace);
+ ret += def->m_replace;
else
- ret.cat(elem);
+ ret += elem;
}
return ret;
}
static pstring catremainder(const std::vector<pstring> &elems, std::size_t start, pstring sep)
{
- pstringbuffer ret("");
+ pstring ret("");
for (auto & elem : elems)
{
- ret.cat(elem);
- ret.cat(sep);
+ ret += elem;
+ ret += sep;
}
return ret;
}
pstring ppreprocessor::process_line(const pstring &line)
{
- pstring lt = line.replace("\t"," ").trim();
- pstringbuffer ret;
+ pstring lt = line.replace_all("\t"," ").trim();
+ pstring ret;
m_lineno++;
// FIXME ... revise and extend macro handling
if (lt.startsWith("#"))
@@ -422,7 +422,7 @@ pstring ppreprocessor::process_line(const pstring &line)
m_level++;
std::size_t start = 0;
lt = replace_macros(lt);
- std::vector<pstring> t(psplit(lt.substr(3).replace(" ",""), m_expr_sep));
+ std::vector<pstring> t(psplit(lt.substr(3).replace_all(" ",""), m_expr_sep));
int val = static_cast<int>(expr(t, start, 0));
if (val == 0)
m_ifflag |= (1 << m_level);
@@ -477,7 +477,7 @@ pstring ppreprocessor::process_line(const pstring &line)
lt = replace_macros(lt);
if (m_ifflag == 0)
{
- ret.cat(lt);
+ ret += lt;
}
}
return ret;
diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h
index 7ff8c4762a0..5957de7ea13 100644
--- a/src/lib/netlist/plib/pparser.h
+++ b/src/lib/netlist/plib/pparser.h
@@ -127,7 +127,7 @@ private:
int m_lineno;
pstring m_cur_line;
- pstring::iterator m_px;
+ pstring::const_iterator m_px;
pstring::code_t m_unget;
/* tokenizer stuff follows ... */
diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp
index e14bc864122..420f63c9e5e 100644
--- a/src/lib/netlist/plib/pstream.cpp
+++ b/src/lib/netlist/plib/pstream.cpp
@@ -367,7 +367,7 @@ pstream::pos_type pomemstream::vtell()
bool putf8_reader::readline(pstring &line)
{
pstring::code_t c = 0;
- m_linebuf.clear();
+ m_linebuf = "";
if (!this->readcode(c))
{
line = "";
diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h
index 084a15ef988..7afc329e817 100644
--- a/src/lib/netlist/plib/pstream.h
+++ b/src/lib/netlist/plib/pstream.h
@@ -148,19 +148,19 @@ public:
postringstream() : postream(0) { }
virtual ~postringstream() override;
- const pstringbuffer &str() { return m_buf; }
+ const pstring &str() { return m_buf; }
protected:
/* write n bytes to stream */
virtual void vwrite(const void *buf, const pos_type n) override
{
- m_buf.cat(buf, n);
+ m_buf += pstring(static_cast<const pstring::mem_t *>(buf), n, pstring::UTF8);
}
virtual void vseek(const pos_type n) override { }
virtual pos_type vtell() override { return m_buf.len(); }
private:
- pstringbuffer m_buf;
+ pstring m_buf;
};
// -----------------------------------------------------------------------------
@@ -317,17 +317,17 @@ public:
char b[4];
if (m_strm.read(&b[0], 1) != 1)
return false;
- const unsigned l = pstring::traits::codelen(b);
+ const unsigned l = pstring::traits_type::codelen(b);
for (unsigned i = 1; i < l; i++)
if (m_strm.read(&b[i], 1) != 1)
return false;
- c = pstring::traits::code(b);
+ c = pstring::traits_type::code(b);
return true;
}
private:
pistream &m_strm;
- pstringbuffer m_linebuf;
+ pstring m_linebuf;
};
// -----------------------------------------------------------------------------
@@ -348,7 +348,7 @@ public:
void write(const pstring &text) const
{
- m_strm.write(text.c_str(), text.blen());
+ m_strm.write(text.c_str(), text.size());
}
void write(const pstring::code_t c) const
@@ -391,8 +391,8 @@ public:
void write(const pstring &s)
{
- write(s.blen());
- m_strm.write(s.c_str(), s.blen());
+ write(s.size());
+ m_strm.write(s.c_str(), s.size());
}
template <typename T>
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index 90dc1f82f1d..0fa6a6f83d9 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -11,16 +11,7 @@
#include <algorithm>
#include <stack>
-#include <cstdlib>
-
-template <typename F> pstr_t pstring_t<F>::m_zero(0);
-
-template<typename F>
-pstring_t<F>::~pstring_t()
-{
- if (m_ptr != nullptr)
- sfree(m_ptr);
-}
+#include <atomic>
template <typename T>
std::size_t strlen_mem(const T *s)
@@ -31,44 +22,15 @@ std::size_t strlen_mem(const T *s)
return len;
}
-
-template<typename F>
-void pstring_t<F>::pcat(const mem_t *s)
-{
- std::size_t slen = strlen_mem(s);
- pstr_t *n = salloc(m_ptr->len() + slen);
- if (m_ptr->len() > 0)
- n->copy_from(m_ptr->str(), m_ptr->len());
- if (slen > 0)
- std::copy(s, s + slen, n->str() + m_ptr->len());
- *(n->str() + n->len()) = 0;
- sfree(m_ptr);
- m_ptr = n;
-}
-
-template<typename F>
-void pstring_t<F>::pcat(const pstring_t &s)
-{
- std::size_t slen = s.blen();
- pstr_t *n = salloc(m_ptr->len() + slen);
- if (m_ptr->len() > 0)
- n->copy_from(m_ptr->str(), m_ptr->len());
- if (slen > 0)
- std::copy(s.c_str(), s.c_str() + slen, n->str() + m_ptr->len());
- *(n->str() + n->len()) = 0;
- sfree(m_ptr);
- m_ptr = n;
-}
-
template<typename F>
int pstring_t<F>::pcmp(const pstring_t &right) const
{
- std::size_t l = std::min(blen(), right.blen());
+ std::size_t l = std::min(size(), right.size());
if (l == 0)
{
- if (blen() == 0 && right.blen() == 0)
+ if (size() == 0 && right.size() == 0)
return 0;
- else if (right.blen() == 0)
+ else if (right.size() == 0)
return 1;
else
return -1;
@@ -83,40 +45,36 @@ int pstring_t<F>::pcmp(const pstring_t &right) const
int ret = (si == this->end() ? 0 : static_cast<int>(*si) - static_cast<int>(*ri));
if (ret == 0)
{
- if (this->blen() > right.blen())
+ if (this->size() > right.size())
ret = 1;
- else if (this->blen() < right.blen())
+ else if (this->size() < right.size())
ret = -1;
}
return ret;
}
-
template<typename F>
-void pstring_t<F>::pcopy(const mem_t *from, std::size_t size)
-{
- pstr_t *n = salloc(size * sizeof(mem_t));
- if (size > 0)
- n->copy_from(static_cast<const char *>(from), size);
- *(static_cast<mem_t *>(n->str()) + size) = 0;
- sfree(m_ptr);
- m_ptr = n;
-}
-
-template<typename F>
-const pstring_t<F> pstring_t<F>::substr(const const_iterator &start, const const_iterator &end) const
+pstring_t<F> pstring_t<F>::substr(size_type start, size_type nlen) const
{
pstring_t ret;
//FIXME: throw ?
- ret.pcopy(start.p, static_cast<std::size_t>(end.p - start.p));
+ const size_type l = len();
+ if (start < l)
+ {
+ if (nlen == npos || start + nlen > l)
+ nlen = l - start;
+ auto ps = std::next(begin(), static_cast<difference_type>(start));
+ auto pe = std::next(ps, static_cast<difference_type>(nlen));
+ ret.m_str.assign(ps.p, pe.p);
+ }
return ret;
}
template<typename F>
-const pstring_t<F> pstring_t<F>::ucase() const
+pstring_t<F> pstring_t<F>::ucase() const
{
pstring_t ret = "";
- for (code_t c : *this)
+ for (const auto &c : *this)
if (c >= 'a' && c <= 'z')
ret += (c - 'a' + 'A');
else
@@ -125,9 +83,10 @@ const pstring_t<F> pstring_t<F>::ucase() const
}
template<typename F>
-typename pstring_t<F>::const_iterator pstring_t<F>::find_first_not_of(const pstring_t &no) const
+typename pstring_t<F>::size_type pstring_t<F>::find_first_not_of(const pstring_t &no) const
{
- for (auto it = begin(); it != end(); ++it)
+ size_type pos = 0;
+ for (auto it = begin(); it != end(); ++it, ++pos)
{
bool f = true;
for (code_t const jt : no)
@@ -139,17 +98,18 @@ typename pstring_t<F>::const_iterator pstring_t<F>::find_first_not_of(const pstr
}
}
if (f)
- return it;
+ return pos;
}
- return end();
+ return npos;
}
template<typename F>
-typename pstring_t<F>::const_iterator pstring_t<F>::find_last_not_of(const pstring_t &no) const
+typename pstring_t<F>::size_type pstring_t<F>::find_last_not_of(const pstring_t &no) const
{
- /* FIXME: reverse const_iterator */
- const_iterator last_found = end();
- for (auto it = begin(); it != end(); ++it)
+ /* FIXME: reverse iterator */
+ size_type last_found = npos;
+ size_type pos = 0;
+ for (auto it = begin(); it != end(); ++it, ++pos)
{
bool f = true;
for (code_t const jt : no)
@@ -161,17 +121,18 @@ typename pstring_t<F>::const_iterator pstring_t<F>::find_last_not_of(const pstri
}
}
if (f)
- last_found = it;
+ last_found = pos;
}
return last_found;
}
template<typename F>
-typename pstring_t<F>::const_iterator pstring_t<F>::find(const pstring_t &search, const_iterator start) const
+typename pstring_t<F>::size_type pstring_t<F>::find(const pstring_t &search, size_type start) const
{
- for (; start != end(); ++start)
+ auto istart = std::next(begin(), static_cast<difference_type>(start));
+ for (; istart != end(); ++istart)
{
- const_iterator itc(start);
+ auto itc(istart);
auto cmp = search.begin();
while (itc != end() && cmp != search.end() && *itc == *cmp)
{
@@ -180,56 +141,41 @@ typename pstring_t<F>::const_iterator pstring_t<F>::find(const pstring_t &search
}
if (cmp == search.end())
return start;
+ ++start;
}
- return end();
+ return npos;
}
template<typename F>
-typename pstring_t<F>::const_iterator pstring_t<F>::find(const code_t search, const_iterator start) const
+typename pstring_t<F>::size_type pstring_t<F>::find(code_t search, size_type start) const
{
- mem_t buf[traits::MAXCODELEN+1] = { 0 };
- traits::encode(search, buf);
+ mem_t buf[traits_type::MAXCODELEN+1] = { 0 };
+ traits_type::encode(search, buf);
return find(pstring_t(&buf[0], UTF8), start);
}
template<typename F>
-pstring_t<F> pstring_t<F>::replace(const pstring_t &search, const pstring_t &replace) const
+pstring_t<F> pstring_t<F>::replace_all(const pstring_t &search, const pstring_t &replace) const
{
pstring_t ret("");
const size_type slen = search.len();
- auto last_s = begin();
- auto s = find(search, last_s);
- while (s != end())
+ size_type last_s = 0;
+ size_type s = find(search, last_s);
+ while (s != npos)
{
- ret += substr(last_s, s);
+ ret += substr(last_s, s - last_s);
ret += replace;
- last_s = std::next(s, slen);
+ last_s = s + slen;
s = find(search, last_s);
}
- ret += substr(last_s, end());
+ ret += substr(last_s);
return ret;
}
template<typename F>
-const pstring_t<F> pstring_t<F>::ltrim(const pstring_t &ws) const
-{
- return substr(find_first_not_of(ws), end());
-}
-
-template<typename F>
-const pstring_t<F> pstring_t<F>::rtrim(const pstring_t &ws) const
-{
- auto f = find_last_not_of(ws);
- if (f==end())
- return pstring_t("");
- else
- return substr(begin(), std::next(f, 1));
-}
-
-template<typename F>
-const pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const size_type cnt) const
+pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const size_type cnt) const
{
// FIXME: pstringbuffer ret(*this);
@@ -240,23 +186,16 @@ const pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const size_type cnt)
return ret;
}
-
-template<typename F>
-void pstring_t<F>::pcopy(const mem_t *from)
-{
- pcopy(from, strlen_mem(from));
-}
-
template<typename F>
double pstring_t<F>::as_double(bool *error) const
{
double ret;
- char *e = nullptr;
+ std::size_t e = 0;
if (error != nullptr)
*error = false;
- ret = std::strtod(c_str(), &e);
- if (*e != 0)
+ ret = std::stod(m_str, &e);
+ if (e != size())
if (error != nullptr)
*error = true;
return ret;
@@ -266,248 +205,20 @@ template<typename F>
long pstring_t<F>::as_long(bool *error) const
{
long ret;
- char *e = nullptr;
+ std::size_t e = 0;
if (error != nullptr)
*error = false;
if (startsWith("0x"))
- ret = std::strtol(substr(2).c_str(), &e, 16);
+ ret = std::stol(substr(2).m_str, &e, 16);
else
- ret = std::strtol(c_str(), &e, 10);
- if (*e != 0)
+ ret = std::stol(m_str, &e, 10);
+ if (e != size())
if (error != nullptr)
*error = true;
return ret;
}
-template<typename F>
-bool pstring_t<F>::startsWith(const pstring_t &arg) const
-{
- if (arg.blen() > blen())
- return false;
- else
- return std::equal(arg.c_str(), arg.c_str() + arg.blen(), c_str());
-}
-
-template<typename F>
-bool pstring_t<F>::endsWith(const pstring_t &arg) const
-{
- if (arg.blen() > blen())
- return false;
- else
- return std::equal(arg.c_str(), arg.c_str() + arg.blen(), c_str()+this->blen()-arg.blen());
-}
-
-// ----------------------------------------------------------------------------------------
-// pstringbuffer
-// ----------------------------------------------------------------------------------------
-
-pstringbuffer::~pstringbuffer()
-{
- if (m_ptr != nullptr)
- plib::pfree_array(m_ptr);
-}
-
-void pstringbuffer::resize(const std::size_t size)
-{
- if (m_ptr == nullptr)
- {
- m_size = DEFAULT_SIZE;
- while (m_size <= size)
- m_size *= 2;
- m_ptr = plib::palloc_array<char>(m_size);
- *m_ptr = 0;
- m_len = 0;
- }
- else if (m_size < size)
- {
- while (m_size < size)
- m_size *= 2;
- char *new_buf = plib::palloc_array<char>(m_size);
- std::copy(m_ptr, m_ptr + m_len + 1, new_buf);
- plib::pfree_array(m_ptr);
- m_ptr = new_buf;
- }
-}
-
-void pstringbuffer::pcopy(const char *from)
-{
- std::size_t nl = strlen_mem(from) + 1;
- resize(nl);
- std::copy(from, from + nl, m_ptr);
-}
-
-void pstringbuffer::pcopy(const pstring &from)
-{
- std::size_t nl = from.blen() + 1;
- resize(nl);
- std::copy(from.c_str(), from.c_str() + nl, m_ptr);
-}
-
-void pstringbuffer::pcat(const char *s)
-{
- const std::size_t slen = strlen_mem(s);
- const std::size_t nl = m_len + slen + 1;
- resize(nl);
- std::copy(s, s + slen + 1, m_ptr + m_len);
- m_len += slen;
-}
-
-void pstringbuffer::pcat(const void *m, std::size_t l)
-{
- const std::size_t nl = m_len + l + 1;
- resize(nl);
- std::copy(static_cast<const char *>(m), static_cast<const char *>(m) + l, m_ptr + m_len);
- m_len += l;
- *(m_ptr + m_len) = 0;
-}
-
-void pstringbuffer::pcat(const pstring &s)
-{
- const std::size_t slen = s.blen();
- const std::size_t nl = m_len + slen + 1;
- resize(nl);
- std::copy(s.c_str(), s.c_str() + slen, m_ptr + m_len);
- m_len += slen;
- m_ptr[m_len] = 0;
-}
-
-// ----------------------------------------------------------------------------------------
-// static stuff ...
-// ----------------------------------------------------------------------------------------
-
-/*
- * Cached allocation of string memory
- *
- * This improves startup performance by 30%.
- */
-
-#if 1
-
-static std::stack<pstr_t *> *stk = nullptr;
-
-static inline std::size_t countleadbits(std::size_t x)
-{
-#ifndef count_leading_zeros
- std::size_t msk;
- std::size_t ret;
- if (x < 0x100)
- {
- msk = 0x80;
- ret = 24;
- }
- else if (x < 0x10000)
- {
- msk = 0x8000;
- ret = 16;
- }
- else if (x < 0x1000000)
- {
- msk = 0x800000;
- ret = 8;
- }
- else
- {
- msk = 0x80000000;
- ret = 0;
- }
- while ((msk & x) == 0 && ret < 31)
- {
- msk = msk >> 1;
- ret++;
- }
- return ret;
-#else
- return count_leading_zeros(x);
-#endif
-}
-
-template<typename F>
-void pstring_t<F>::sfree(pstr_t *s)
-{
- if (s != nullptr)
- {
- bool b = s->dec_and_check();
- if ( b && s != &m_zero)
- {
- if (stk != nullptr)
- {
- size_type sn= ((32 - countleadbits(s->len())) + 1) / 2;
- stk[sn].push(s);
- }
- else
- plib::pfree_array(reinterpret_cast<char *>(s));
- }
- }
-}
-
-template<typename F>
-pstr_t *pstring_t<F>::salloc(std::size_t n)
-{
- if (stk == nullptr)
- stk = plib::palloc_array<std::stack<pstr_t *>>(17);
- pstr_t *p;
- std::size_t sn= ((32 - countleadbits(n)) + 1) / 2;
- std::size_t size = sizeof(pstr_t) + (static_cast<std::size_t>(1)<<(sn * 2)) + 1;
- if (stk[sn].empty())
- p = reinterpret_cast<pstr_t *>(plib::palloc_array<char>(size));
- else
- {
- p = stk[sn].top();
- stk[sn].pop();
- }
-
- // str_t *p = (str_t *) mm_malloc(size, 8);
- p->init(n);
- return p;
-}
-template<typename F>
-void pstring_t<F>::resetmem()
-{
- if (stk != nullptr)
- {
- for (std::size_t i=0; i<=16; i++)
- {
- for (; stk[i].size() > 0; )
- {
- plib::pfree_array(stk[i].top());
- stk[i].pop();
- }
- }
- plib::pfree_array(stk);
- stk = nullptr;
- }
-}
-
-
-#else
-template<typename F>
-void pstring_t<F>::sfree(pstr_t *s)
-{
- bool b = s->dec_and_check();
- if ( b && s != &m_zero)
- {
- plib::pfree_array(((char *)s));
- }
-}
-
-template<typename F>
-pstr_t *pstring_t<F>::salloc(std::size_t n)
-{
- int size = sizeof(pstr_t) + n + 1;
- pstr_t *p = (pstr_t *) plib::palloc_array<char>(size);
- // str_t *p = (str_t *) mm_malloc(size, 8);
- p->init(n);
- return p;
-}
-
-template<typename F>
-void pstring_t<F>::resetmem()
-{
- // Release the 0 string
-}
-#endif
-
// ----------------------------------------------------------------------------------------
// template stuff ...
// ----------------------------------------------------------------------------------------
@@ -517,4 +228,3 @@ template struct pstring_t<putf8_traits>;
const unsigned pu8_traits::MAXCODELEN;
const unsigned putf8_traits::MAXCODELEN;
-const int pstringbuffer::DEFAULT_SIZE;
diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h
index 7bb037b42cd..94e8231b9d3 100644
--- a/src/lib/netlist/plib/pstring.h
+++ b/src/lib/netlist/plib/pstring.h
@@ -9,44 +9,25 @@
#include <iterator>
#include <exception>
+#include <string>
// ----------------------------------------------------------------------------------------
-// pstring: immutable strings ...
+// pstring: semi-immutable strings ...
//
-// pstrings are just a pointer to a "pascal-style" string representation.
-// It uses reference counts and only uses new memory when a string changes.
+// The only reason this class exists is the absence of support for multi-byte
+// strings in std:: which I would consider usuable for the use-cases I encounter.
// ----------------------------------------------------------------------------------------
-struct pstr_t
-{
- explicit pstr_t(const std::size_t alen) { init(alen); }
- void init(const std::size_t alen)
- {
- m_ref_count = 1;
- m_len = alen;
- m_str[0] = 0;
- }
- char *str() { return &m_str[0]; }
- unsigned char *ustr() { return reinterpret_cast<unsigned char *>(&m_str[0]); }
- std::size_t len() const { return m_len; }
- void inc() { m_ref_count++; }
- bool dec_and_check() { --m_ref_count; return m_ref_count == 0; }
- void copy_from(const char *p, std::size_t n) { std::copy(p, p + n, str()); }
-private:
- int m_ref_count;
- std::size_t m_len;
- char m_str[1];
-};
-
template <typename F>
struct pstring_t
{
public:
- typedef F traits;
+ typedef F traits_type;
- typedef typename F::mem_t mem_t;
- typedef typename F::code_t code_t;
- typedef std::size_t size_type;
+ typedef typename traits_type::mem_t mem_t;
+ typedef typename traits_type::code_t code_t;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
enum enc_t
{
@@ -54,33 +35,52 @@ public:
};
// simple construction/destruction
- pstring_t() : m_ptr(&m_zero)
+ pstring_t()
+ : m_str("")
+ {
+ }
+ ~pstring_t()
{
- init(nullptr);
}
- ~pstring_t();
// FIXME: Do something with encoding
- pstring_t(const mem_t *string, const enc_t enc) : m_ptr(&m_zero)
+ pstring_t(const mem_t *string, const enc_t enc)
+ : m_str(string)
+ {
+ }
+
+ pstring_t(const mem_t *string, const size_type len, const enc_t enc)
+ : m_str(string, len)
{
- init(string);
}
template<typename C, std::size_t N>
- pstring_t(C (&string)[N]) : m_ptr(&m_zero) {
+ pstring_t(C (&string)[N])
+ {
static_assert(std::is_same<C, const mem_t>::value, "pstring constructor only accepts const mem_t");
- static_assert(N>0,"pstring from array of length 0");
+ static_assert(N > 0,"pstring from array of length 0");
if (string[N-1] != 0)
throw std::exception();
- init(string);
+ m_str.assign(string, N - 1);
}
- pstring_t(const pstring_t &string) : m_ptr(&m_zero) { init(string); }
- pstring_t(pstring_t &&string) : m_ptr(string.m_ptr) { string.m_ptr = nullptr; }
- explicit pstring_t(code_t code) : m_ptr(&m_zero) { pstring_t t; t+= code; init(t); }
+ pstring_t(const pstring_t &string)
+ : m_str(string.m_str)
+ { }
+
+ pstring_t(pstring_t &&string)
+ : m_str(string.m_str)
+ { }
+
+ explicit pstring_t(code_t code)
+ {
+ pstring_t t;
+ t+= code;
+ m_str.assign(t.m_str);
+ }
// assignment operators
- pstring_t &operator=(const pstring_t &string) { pcopy(string); return *this; }
+ pstring_t &operator=(const pstring_t &string) { m_str = string.m_str; return *this; }
class const_iterator final
{
@@ -93,7 +93,7 @@ public:
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); }
+ operator code_t() const noexcept { return traits_type::code(&m); }
private:
const mem_t m;
};
@@ -103,43 +103,55 @@ public:
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() noexcept : p() { }
+ explicit constexpr const_iterator(const std::string::const_iterator &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++() noexcept { p += traits_type::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); }
+ 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;
+ std::string::const_iterator p;
};
// 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()); }
+ iterator begin() { return iterator(m_str.begin()); }
+ iterator end() { return iterator(m_str.end()); }
+ const_iterator begin() const { return const_iterator(m_str.begin()); }
+ const_iterator end() const { return const_iterator(m_str.end()); }
+ const_iterator cbegin() const { return const_iterator(m_str.begin()); }
+ const_iterator cend() const { return const_iterator(m_str.end()); }
// C string conversion helpers
- const mem_t *c_str() const { return m_ptr->str(); }
+ const mem_t *c_str() const { return static_cast<const mem_t *>(m_str.c_str()); }
+
+ size_type size() const { return m_str.size(); }
+
+ pstring_t substr(size_type start, size_type nlen = npos) const;
+
+ size_type find(const pstring_t &search, size_type start = 0) const;
+ size_type find(code_t search, size_type start = 0) const;
+
+ size_type find_first_not_of(const pstring_t &no) const;
+ size_type find_last_not_of(const pstring_t &no) const;
// concatenation operators
- pstring_t& operator+=(const pstring_t &string) { pcat(string); return *this; }
+ pstring_t& operator+=(const pstring_t &string) { m_str.append(string.m_str); return *this; }
+ pstring_t& operator+=(const code_t c) { mem_t buf[traits_type::MAXCODELEN+1] = { 0 }; traits_type::encode(c, buf); m_str.append(buf); return *this; }
friend pstring_t operator+(const pstring_t &lhs, const pstring_t &rhs) { return pstring_t(lhs) += rhs; }
+ friend pstring_t operator+(const pstring_t &lhs, const code_t rhs) { return pstring_t(lhs) += rhs; }
// comparison operators
bool operator==(const pstring_t &string) const { return (pcmp(string) == 0); }
@@ -150,90 +162,62 @@ public:
bool operator>(const pstring_t &string) const { return (pcmp(string) > 0); }
bool operator>=(const pstring_t &string) const { return (pcmp(string) >= 0); }
+ /* The following is not compatible to std::string */
+
bool equals(const pstring_t &string) const { return (pcmp(string) == 0); }
- bool startsWith(const pstring_t &arg) const;
- bool endsWith(const pstring_t &arg) const;
- pstring_t replace(const pstring_t &search, const pstring_t &replace) const;
- const pstring_t cat(const pstring_t &s) const { return *this + s; }
- const pstring_t cat(const code_t c) const { return *this + c; }
+ bool startsWith(const pstring_t &arg) const { return arg.size() > size() ? false : m_str.compare(0, arg.size(), arg.m_str) == 0; }
+ bool endsWith(const pstring_t &arg) const { return arg.size() > size() ? false : m_str.compare(size()-arg.size(), arg.size(), arg.m_str) == 0; }
- size_type blen() const { return m_ptr->len(); }
+ pstring_t replace_all(const pstring_t &search, const pstring_t &replace) const;
+ pstring_t cat(const pstring_t &s) const { return *this + s; }
+ pstring_t cat(code_t c) const { return *this + c; }
// conversions
double as_double(bool *error = nullptr) const;
long as_long(bool *error = nullptr) const;
- size_type len() const
- {
- return traits::len(m_ptr);
- }
-
- 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; }
+ size_type len() const { return traits_type::len(m_str); }
- 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()); }
+ /* the following are extensions to <string> */
- 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()); }
+ pstring_t left(size_type len) const { return substr(0, len); }
+ pstring_t right(size_type nlen) const
+ {
+ return nlen >= len() ? pstring_t(*this) : substr(len() - nlen, nlen);
+ }
- const pstring_t left(const_iterator leftof) const { return substr(begin(), leftof); }
- const pstring_t right(const_iterator pos) const { return substr(pos, end()); }
+ pstring_t ltrim(const pstring_t &ws = pstring_t(" \t\n\r")) const
+ {
+ return substr(find_first_not_of(ws));
+ }
- const_iterator find_first_not_of(const pstring_t &no) const;
- const_iterator find_last_not_of(const pstring_t &no) const;
+ pstring_t rtrim(const pstring_t &ws = pstring_t(" \t\n\r")) const
+ {
+ auto f = find_last_not_of(ws);
+ if (f==npos)
+ return pstring_t("");
+ else
+ return substr(0, f + 1);
+ }
- 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;
- const pstring_t trim(const pstring_t &ws = pstring_t(" \t\n\r")) const { return this->ltrim(ws).rtrim(ws); }
+ pstring_t trim(const pstring_t &ws = pstring_t(" \t\n\r")) const { return this->ltrim(ws).rtrim(ws); }
- const pstring_t rpad(const pstring_t &ws, const size_type cnt) const;
+ pstring_t rpad(const pstring_t &ws, const size_type cnt) const;
- code_t code_at(const size_type pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); }
+ code_t code_at(const size_type pos) const {return F::code(F::nthcode(m_str.c_str(),pos)); }
- const pstring_t ucase() const;
+ pstring_t ucase() const;
- static void resetmem();
+ static const size_type npos = static_cast<size_type>(-1);
protected:
- pstr_t *m_ptr;
+ std::string m_str;
private:
- void init(const mem_t *string)
- {
- m_ptr->inc();
- if (string != nullptr && *string != 0)
- pcopy(string);
- }
- void init(const pstring_t &string)
- {
- m_ptr->inc();
- pcopy(string);
- }
int pcmp(const pstring_t &right) const;
-
- void pcopy(const mem_t *from, std::size_t size);
-
- void pcopy(const mem_t *from);
- void pcopy(const pstring_t &from)
- {
- sfree(m_ptr);
- m_ptr = from.m_ptr;
- m_ptr->inc();
- }
- void pcat(const mem_t *s);
- void pcat(const pstring_t &s);
-
- static pstr_t *salloc(std::size_t n);
- static void sfree(pstr_t *s);
-
- static pstr_t m_zero;
};
struct pu8_traits
@@ -241,7 +225,7 @@ struct pu8_traits
static const unsigned MAXCODELEN = 1; /* in memory units */
typedef char mem_t;
typedef char code_t;
- static std::size_t len(const pstr_t *p) { return p->len(); }
+ static std::size_t len(const std::string &p) { return p.size(); }
static unsigned codelen(const mem_t *p) { return 1; }
static unsigned codelen(const code_t c) { return 1; }
static code_t code(const mem_t *p) { return *p; }
@@ -255,15 +239,13 @@ struct putf8_traits
static const unsigned MAXCODELEN = 4; /* in memory units, RFC 3629 */
typedef char mem_t;
typedef unsigned code_t;
- static std::size_t len(pstr_t *p)
+ static std::size_t len(const std::string &p)
{
std::size_t ret = 0;
- unsigned char *c = p->ustr();
- while (*c)
+ for (const auto &c : p)
{
- if (!((*c & 0xC0) == 0x80))
+ if (!((c & 0xC0) == 0x80))
ret++;
- c++;
}
return ret;
}
@@ -349,80 +331,6 @@ extern template struct pstring_t<putf8_traits>;
typedef pstring_t<putf8_traits> pstring;
-// ----------------------------------------------------------------------------------------
-// pstringbuffer: a string buffer implementation
-//
-// string buffer are optimized to handle concatenations. This implementation is designed
-// to specifically interact with pstrings nicely.
-// ----------------------------------------------------------------------------------------
-
-struct pstringbuffer
-{
-public:
-
- static const int DEFAULT_SIZE = 2048;
- // simple construction/destruction
- pstringbuffer()
- {
- init();
- resize(DEFAULT_SIZE);
- }
-
- ~pstringbuffer();
-
- // construction with copy
- explicit pstringbuffer(const char *string) {init(); if (string != nullptr) pcopy(string); }
- explicit pstringbuffer(const pstring &string) {init(); pcopy(string); }
- pstringbuffer(const pstringbuffer &stringb) {init(); pcopy(stringb); }
- pstringbuffer(pstringbuffer &&b) : m_ptr(b.m_ptr), m_size(b.m_size), m_len(b.m_len) { b.m_ptr = nullptr; b.m_size = 0; b.m_len = 0; }
-
- // assignment operators
- pstringbuffer &operator=(const char *string) { pcopy(string); return *this; }
- pstringbuffer &operator=(const pstring &string) { pcopy(string); return *this; }
- pstringbuffer &operator=(const pstringbuffer &string) { pcopy(string); return *this; }
-
- // C string conversion helpers
- const char *c_str() const { return m_ptr; }
-
- // FIXME: encoding should be parameter
- operator pstring() const { return pstring(m_ptr, pstring::UTF8); }
-
- // concatenation operators
- pstringbuffer& operator+=(const char c) { char buf[2] = { c, 0 }; pcat(buf); return *this; }
- pstringbuffer& operator+=(const pstring &string) { pcat(string); return *this; }
- pstringbuffer& operator+=(const char *string) { pcat(string); return *this; }
-
- std::size_t len() const { return m_len; }
-
- void cat(const pstring &s) { pcat(s); }
- void cat(const char *s) { pcat(s); }
- void cat(const void *m, std::size_t l) { pcat(m, l); }
-
- void clear() { m_len = 0; *m_ptr = 0; }
-
-private:
-
- void init()
- {
- m_ptr = nullptr;
- m_size = 0;
- m_len = 0;
- }
-
- void resize(const std::size_t size);
-
- void pcopy(const char *from);
- void pcopy(const pstring &from);
- void pcat(const char *s);
- void pcat(const pstring &s);
- void pcat(const void *m, std::size_t l);
-
- char *m_ptr;
- std::size_t m_size;
- std::size_t m_len;
-
-};
-
// custom specialization of std::hash can be injected in namespace std
namespace std
{
diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp
index 234b4e6cbaa..ddb300958ea 100644
--- a/src/lib/netlist/plib/putil.cpp
+++ b/src/lib/netlist/plib/putil.cpp
@@ -44,20 +44,20 @@ namespace plib
{
std::vector<pstring> ret;
- pstring::iterator p = str.begin();
- pstring::iterator pn = str.find(onstr, p);
+ pstring::size_type p = 0;
+ pstring::size_type pn = str.find(onstr, p);
- while (pn != str.end())
+ while (pn != pstring::npos)
{
- pstring t = str.substr(p, pn);
+ pstring t = str.substr(p, pn - p);
if (!ignore_empty || t.len() != 0)
ret.push_back(t);
- p = std::next(pn, onstr.len());
+ p = pn + onstr.len();
pn = str.find(onstr, p);
}
- if (p != str.end())
+ if (p < str.len())
{
- pstring t = str.substr(p, str.end());
+ pstring t = str.substr(p);
if (!ignore_empty || t.len() != 0)
ret.push_back(t);
}
@@ -69,13 +69,13 @@ namespace plib
pstring col = "";
std::vector<pstring> ret;
- unsigned i = 0;
- while (i<str.blen())
+ auto i = str.begin();
+ while (i != str.end())
{
std::size_t p = static_cast<std::size_t>(-1);
for (std::size_t j=0; j < onstrl.size(); j++)
{
- if (std::equal(onstrl[j].c_str(), onstrl[j].c_str() + onstrl[j].blen(), &(str.c_str()[i])))
+ if (std::equal(onstrl[j].c_str(), onstrl[j].c_str() + onstrl[j].size(), i))
{
p = j;
break;
@@ -88,13 +88,13 @@ namespace plib
col = "";
ret.push_back(onstrl[p]);
- i += onstrl[p].blen();
+ i = std::next(i, static_cast<pstring::difference_type>(onstrl[p].len()));
}
else
{
- pstring::traits::code_t c = pstring::traits::code(str.c_str() + i);
+ pstring::code_t c = *i;
col += c;
- i+=pstring::traits::codelen(c);
+ i++;
}
}
if (col != "")
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index ba0526b5408..bde2bcd5b6c 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 (const auto &x : s)
adj += (x == '\t' ? 3 : 0);
pout("{1}\\\n", s.rpad(" ", RIGHT-1-adj));
}
@@ -434,13 +434,13 @@ void tool_app_t::cmac(const netlist::factory::element_t *e)
auto v = plib::psplit(e->param_desc(), ",");
pstring vs;
for (auto s : v)
- vs += ", p" + s.replace("+","").replace(".","_");
+ vs += ", p" + s.replace_all("+", "").replace_all(".", "_");
mac_out("#define " + e->name() + "(name" + vs + ")");
mac_out("\tNET_REGISTER_DEV(" + e->name() +", name)");
for (auto s : v)
{
- pstring r(s.replace("+","").replace(".","_"));
+ pstring r(s.replace_all("+", "").replace_all(".", "_"));
if (s.startsWith("+"))
mac_out("\tNET_CONNECT(name, " + r + ", p" + r + ")");
else
@@ -455,7 +455,7 @@ void tool_app_t::mac(const netlist::factory::element_t *e)
pstring vs;
for (auto s : v)
{
- vs += ", " + s.replace("+","").replace(".","_");
+ vs += ", " + s.replace_all("+", "").replace_all(".", "_");
}
pout("{1}(name{2})\n", e->name(), vs);
if (v.size() > 0)
@@ -463,7 +463,7 @@ void tool_app_t::mac(const netlist::factory::element_t *e)
pout("/*\n");
for (auto s : v)
{
- pstring r(s.replace("+","").replace(".","_"));
+ pstring r(s.replace_all("+", "").replace_all(".", "_"));
if (s.startsWith("+"))
pout("{1:10}: Terminal\n",r);
else
@@ -507,7 +507,7 @@ void tool_app_t::create_header()
{
last_source = e->sourcefile();
pout("{1}\n", pstring("// ").rpad("-", 72));
- pout("{1}\n", pstring("// Source: ").cat(e->sourcefile().replace("../","")));
+ pout("{1}{2}\n", pstring("// Source: "), e->sourcefile().replace_all("../", ""));
pout("{1}\n", pstring("// ").rpad("-", 72));
}
cmac(e.get());
@@ -603,7 +603,7 @@ void tool_app_t::listdevices()
if (t.second->name().startsWith(d->name()))
{
pstring tn(t.second->name().substr(d->name().len()+1));
- if (tn.find(".") == tn.end())
+ if (tn.find(".") == pstring::npos)
terms.push_back(tn);
}
}
@@ -614,7 +614,7 @@ void tool_app_t::listdevices()
{
pstring tn(t.first.substr(d->name().len()+1));
//printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), tn.c_str());
- if (tn.find(".") == tn.end())
+ if (tn.find(".") == pstring::npos)
{
terms.push_back(tn);
pstring resolved = nt.setup().resolve_alias(t.first);
@@ -770,8 +770,6 @@ int tool_app_t::execute()
{
perr("plib exception caught: {}\n", e.text());
}
-
- pstring::resetmem();
return 0;
}
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index 8adf3de2415..0323b35f3c8 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -148,7 +148,8 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
if (net_proxy_output == nullptr)
{
- auto net_proxy_output_u = plib::make_unique<proxied_analog_output_t>(*this, this->name() + "." + plib::pfmt("m{1}")(m_inps.size()));
+ pstring nname = this->name() + "." + pstring(plib::pfmt("m{1}")(m_inps.size()));
+ auto net_proxy_output_u = plib::make_unique<proxied_analog_output_t>(*this, nname);
net_proxy_output = net_proxy_output_u.get();
m_inps.push_back(std::move(net_proxy_output_u));
nl_assert(p->net().is_analog());
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index 9589794e696..bbed33043d0 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -209,8 +209,8 @@ double nl_convert_base_t::get_sp_unit(const pstring &unit)
double nl_convert_base_t::get_sp_val(const pstring &sin)
{
- auto p = sin.begin();
- while (p != sin.end() && (m_numberchars.find(*p) != m_numberchars.end()))
+ std::size_t p = 0;
+ while (p < sin.len() && (m_numberchars.find(sin.substr(p, 1)) != pstring::npos))
++p;
pstring val = sin.left(p);
pstring unit = sin.substr(p);
@@ -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(std::next(m[1].begin(), 3));
+ pins = m[1].left(3);
}
add_device("QBJT_EB", tt[0], m[0]);
add_term(tt[1], tt[0] + "." + pins.code_at(0));
@@ -381,7 +381,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
// last element is component type
// FIXME: Parameter
- pstring xname = tt[0].replace(".", "_");
+ pstring xname = tt[0].replace_all(".", "_");
pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP";
add_device(tname, xname);
for (std::size_t i=1; i < tt.size() - 1; i++)
diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h
index bf1f0710cd1..d3881320678 100644
--- a/src/lib/netlist/tools/nl_convert.h
+++ b/src/lib/netlist/tools/nl_convert.h
@@ -25,7 +25,7 @@ public:
virtual ~nl_convert_base_t();
- const pstringbuffer &result() { return m_buf.str(); }
+ const pstring &result() { return m_buf.str(); }
virtual void convert(const pstring &contents) = 0;