diff options
author | 2017-03-30 20:20:00 +0200 | |
---|---|---|
committer | 2017-03-30 22:06:03 +0200 | |
commit | ac13946ffbec538f5fc193843fae7dd513b9c58e (patch) | |
tree | 44ee3cdb306b6cbd214c12bd8cb46dc1e6e6fb19 /src | |
parent | ac856bc4d1d22a4be0cd8c86ec7da66761becc96 (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)
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/machine/netlist.cpp | 14 | ||||
-rw-r--r-- | src/devices/machine/netlist.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 26 | ||||
-rw-r--r-- | src/lib/netlist/plib/pfmtlog.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pfunction.cpp | 4 | ||||
-rw-r--r-- | src/lib/netlist/plib/poptions.cpp | 10 | ||||
-rw-r--r-- | src/lib/netlist/plib/pparser.cpp | 34 | ||||
-rw-r--r-- | src/lib/netlist/plib/pparser.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstream.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstream.h | 18 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstring.cpp | 396 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstring.h | 298 | ||||
-rw-r--r-- | src/lib/netlist/plib/putil.cpp | 26 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 18 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_matrix_solver.cpp | 3 | ||||
-rw-r--r-- | src/lib/netlist/tools/nl_convert.cpp | 8 | ||||
-rw-r--r-- | src/lib/netlist/tools/nl_convert.h | 2 |
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; |