From ac13946ffbec538f5fc193843fae7dd513b9c58e Mon Sep 17 00:00:00 2001 From: couriersud Date: Thu, 30 Mar 2017 20:20:00 +0200 Subject: 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) --- src/lib/netlist/plib/pstring.cpp | 396 ++++++--------------------------------- 1 file changed, 53 insertions(+), 343 deletions(-) (limited to 'src/lib/netlist/plib/pstring.cpp') 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 #include -#include - -template pstr_t pstring_t::m_zero(0); - -template -pstring_t::~pstring_t() -{ - if (m_ptr != nullptr) - sfree(m_ptr); -} +#include template std::size_t strlen_mem(const T *s) @@ -31,44 +22,15 @@ std::size_t strlen_mem(const T *s) return len; } - -template -void pstring_t::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 -void pstring_t::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 int pstring_t::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::pcmp(const pstring_t &right) const int ret = (si == this->end() ? 0 : static_cast(*si) - static_cast(*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 -void pstring_t::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(from), size); - *(static_cast(n->str()) + size) = 0; - sfree(m_ptr); - m_ptr = n; -} - -template -const pstring_t pstring_t::substr(const const_iterator &start, const const_iterator &end) const +pstring_t pstring_t::substr(size_type start, size_type nlen) const { pstring_t ret; //FIXME: throw ? - ret.pcopy(start.p, static_cast(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(start)); + auto pe = std::next(ps, static_cast(nlen)); + ret.m_str.assign(ps.p, pe.p); + } return ret; } template -const pstring_t pstring_t::ucase() const +pstring_t pstring_t::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 pstring_t::ucase() const } template -typename pstring_t::const_iterator pstring_t::find_first_not_of(const pstring_t &no) const +typename pstring_t::size_type pstring_t::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::const_iterator pstring_t::find_first_not_of(const pstr } } if (f) - return it; + return pos; } - return end(); + return npos; } template -typename pstring_t::const_iterator pstring_t::find_last_not_of(const pstring_t &no) const +typename pstring_t::size_type pstring_t::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::const_iterator pstring_t::find_last_not_of(const pstri } } if (f) - last_found = it; + last_found = pos; } return last_found; } template -typename pstring_t::const_iterator pstring_t::find(const pstring_t &search, const_iterator start) const +typename pstring_t::size_type pstring_t::find(const pstring_t &search, size_type start) const { - for (; start != end(); ++start) + auto istart = std::next(begin(), static_cast(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::const_iterator pstring_t::find(const pstring_t &search } if (cmp == search.end()) return start; + ++start; } - return end(); + return npos; } template -typename pstring_t::const_iterator pstring_t::find(const code_t search, const_iterator start) const +typename pstring_t::size_type pstring_t::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 -pstring_t pstring_t::replace(const pstring_t &search, const pstring_t &replace) const +pstring_t pstring_t::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 -const pstring_t pstring_t::ltrim(const pstring_t &ws) const -{ - return substr(find_first_not_of(ws), end()); -} - -template -const pstring_t pstring_t::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 -const pstring_t pstring_t::rpad(const pstring_t &ws, const size_type cnt) const +pstring_t pstring_t::rpad(const pstring_t &ws, const size_type cnt) const { // FIXME: pstringbuffer ret(*this); @@ -240,23 +186,16 @@ const pstring_t pstring_t::rpad(const pstring_t &ws, const size_type cnt) return ret; } - -template -void pstring_t::pcopy(const mem_t *from) -{ - pcopy(from, strlen_mem(from)); -} - template double pstring_t::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 long pstring_t::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 -bool pstring_t::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 -bool pstring_t::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(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(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(m), static_cast(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 *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 -void pstring_t::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(s)); - } - } -} - -template -pstr_t *pstring_t::salloc(std::size_t n) -{ - if (stk == nullptr) - stk = plib::palloc_array>(17); - pstr_t *p; - std::size_t sn= ((32 - countleadbits(n)) + 1) / 2; - std::size_t size = sizeof(pstr_t) + (static_cast(1)<<(sn * 2)) + 1; - if (stk[sn].empty()) - p = reinterpret_cast(plib::palloc_array(size)); - else - { - p = stk[sn].top(); - stk[sn].pop(); - } - - // str_t *p = (str_t *) mm_malloc(size, 8); - p->init(n); - return p; -} -template -void pstring_t::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 -void pstring_t::sfree(pstr_t *s) -{ - bool b = s->dec_and_check(); - if ( b && s != &m_zero) - { - plib::pfree_array(((char *)s)); - } -} - -template -pstr_t *pstring_t::salloc(std::size_t n) -{ - int size = sizeof(pstr_t) + n + 1; - pstr_t *p = (pstr_t *) plib::palloc_array(size); - // str_t *p = (str_t *) mm_malloc(size, 8); - p->init(n); - return p; -} - -template -void pstring_t::resetmem() -{ - // Release the 0 string -} -#endif - // ---------------------------------------------------------------------------------------- // template stuff ... // ---------------------------------------------------------------------------------------- @@ -517,4 +228,3 @@ template struct pstring_t; const unsigned pu8_traits::MAXCODELEN; const unsigned putf8_traits::MAXCODELEN; -const int pstringbuffer::DEFAULT_SIZE; -- cgit v1.2.3-70-g09d2