summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/pstring.h')
-rw-r--r--src/lib/netlist/plib/pstring.h457
1 files changed, 131 insertions, 326 deletions
diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h
index c4caeab8e8f..cabce0e7b93 100644
--- a/src/lib/netlist/plib/pstring.h
+++ b/src/lib/netlist/plib/pstring.h
@@ -7,50 +7,45 @@
#ifndef PSTRING_H_
#define PSTRING_H_
-#include "ptypes.h"
-
-#include <cstring>
-#include <exception>
#include <iterator>
-#include <limits>
-#include <stdexcept>
+#include <exception>
#include <string>
-#include <type_traits>
// ----------------------------------------------------------------------------------------
// pstring: semi-immutable strings ...
//
// The only reason this class exists is the absence of support for multi-byte
-// strings in std:: which I would consider sub-optimal for the use-cases I encounter.
+// strings in std:: which I would consider usuable for the use-cases I encounter.
// ----------------------------------------------------------------------------------------
-// enable this to use std::string instead of pstring globally.
-
-#define PSTRING_USE_STD_STRING (0)
-
template <typename T>
class pstring_const_iterator final
{
public:
- using value_type = typename T::ref_value_type;
+ typedef typename T::ref_value_type value_type;
- using pointer = value_type const *;
- using reference = value_type const &;
- using difference_type = std::ptrdiff_t;
- using iterator_category = std::forward_iterator_tag;
- using string_type = typename T::string_type;
- using traits_type = typename T::traits_type;
+ typedef value_type const *pointer;
+ typedef value_type const &reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename T::string_type string_type;
+ typedef typename T::traits_type traits_type;
- constexpr pstring_const_iterator() noexcept : p() { }
+ pstring_const_iterator() noexcept : p() { }
explicit constexpr pstring_const_iterator(const typename string_type::const_iterator &x) noexcept : p(x) { }
+#if !defined(_MSC_VER) || !defined(_ITERATOR_DEBUG_LEVEL) || (0 == _ITERATOR_DEBUG_LEVEL) // debug iterators are broken
+ pstring_const_iterator(const pstring_const_iterator &rhs) noexcept = default;
+ pstring_const_iterator(pstring_const_iterator &&rhs) noexcept = default;
+ pstring_const_iterator &operator=(const pstring_const_iterator &rhs) noexcept = default;
+ pstring_const_iterator &operator=(pstring_const_iterator &&rhs) noexcept = default;
+#endif
pstring_const_iterator& operator++() noexcept { p += static_cast<difference_type>(traits_type::codelen(&(*p))); return *this; }
- // NOLINTNEXTLINE(cert-dcl21-cpp)
- pstring_const_iterator operator++(int) & noexcept { pstring_const_iterator tmp(*this); operator++(); return tmp; }
+ pstring_const_iterator operator++(int) noexcept { pstring_const_iterator tmp(*this); operator++(); return tmp; }
- constexpr bool operator==(const pstring_const_iterator& rhs) const noexcept { return p == rhs.p; }
- constexpr bool operator!=(const pstring_const_iterator& rhs) const noexcept { return p != rhs.p; }
+ bool operator==(const pstring_const_iterator& rhs) const noexcept { return p == rhs.p; }
+ bool operator!=(const pstring_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)); }
@@ -65,21 +60,18 @@ template <typename F>
struct pstring_t
{
public:
- using traits_type = F;
+ typedef F traits_type;
- using mem_t = typename traits_type::mem_t;
- using code_t = typename traits_type::code_t;
- using value_type = typename traits_type::code_t;
- using size_type = std::size_t;
- using difference_type = std::ptrdiff_t;
- using string_type = typename traits_type::string_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;
+ typedef typename traits_type::string_type string_type;
- // FIXME: this is ugly
- struct ref_value_type final
+ class ref_value_type final
{
public:
ref_value_type() = delete;
- ~ref_value_type() = delete;
ref_value_type(const ref_value_type &) = delete;
ref_value_type(ref_value_type &&) = delete;
ref_value_type &operator=(const ref_value_type &) = delete;
@@ -88,27 +80,37 @@ public:
private:
const mem_t m;
};
- using const_reference = const ref_value_type &;
- using reference = const_reference;
+ typedef const ref_value_type& const_reference;
+ typedef const_reference reference;
+
+ enum enc_t
+ {
+ UTF8,
+ UTF16
+ };
// simple construction/destruction
- pstring_t() = default;
- ~pstring_t() noexcept = default;
+ pstring_t()
+ {
+ }
+ ~pstring_t()
+ {
+ }
// FIXME: Do something with encoding
- pstring_t(const mem_t *string)
+ pstring_t(const mem_t *string, const enc_t enc)
: m_str(string)
{
}
- pstring_t(const mem_t *string, const size_type len)
+ pstring_t(const mem_t *string, const size_type len, const enc_t enc)
: m_str(string, len)
{
}
template<typename C, std::size_t N,
class = typename std::enable_if<std::is_same<C, const mem_t>::value>::type>
- pstring_t(C (&string)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ pstring_t(C (&string)[N])
{
static_assert(N > 0,"pstring from array of length 0");
if (string[N-1] != 0)
@@ -116,15 +118,17 @@ public:
m_str.assign(string, N - 1);
}
+ pstring_t(const pstring_t &string)
+ : m_str(string.m_str)
+ { }
- explicit pstring_t(const string_type &string)
+ explicit pstring_t(const string_type &string, const enc_t enc)
: m_str(string)
{ }
- pstring_t(const pstring_t &string) = default;
- pstring_t(pstring_t &&string) noexcept = default;
- pstring_t &operator=(const pstring_t &string) = default;
- pstring_t &operator=(pstring_t &&string) noexcept = default;
+ pstring_t(pstring_t &&string)
+ : m_str(string.m_str)
+ { }
explicit pstring_t(code_t code)
{
@@ -140,8 +144,7 @@ public:
*this += static_cast<code_t>(c); // FIXME: codepage conversion for u8
}
- operator string_type () const { return m_str; }
-
+ pstring_t &operator=(const pstring_t &string) { m_str = string.m_str; return *this; }
template <typename T,
class = typename std::enable_if<!std::is_same<T, pstring_t::traits_type>::value>::type>
@@ -154,8 +157,8 @@ public:
}
// no non-const const_iterator for now
- using iterator = pstring_const_iterator<pstring_t<F> >;
- using const_iterator = pstring_const_iterator<pstring_t<F> >;
+ typedef pstring_const_iterator<pstring_t> iterator;
+ typedef pstring_const_iterator<pstring_t> const_iterator;
iterator begin() { return iterator(m_str.begin()); }
iterator end() { return iterator(m_str.end()); }
@@ -198,26 +201,67 @@ public:
const_reference at(const size_type pos) const { return *reinterpret_cast<const ref_value_type *>(F::nthcode(m_str.c_str(),pos)); }
+ /* The following is not compatible to std::string */
+
+ bool equals(const pstring_t &string) const { return (compare(string) == 0); }
+
+ bool startsWith(const pstring_t &arg) const { return arg.mem_t_size() > mem_t_size() ? false : m_str.compare(0, arg.mem_t_size(), arg.m_str) == 0; }
+ bool endsWith(const pstring_t &arg) const { return arg.mem_t_size() > mem_t_size() ? false : m_str.compare(mem_t_size()-arg.mem_t_size(), arg.mem_t_size(), arg.m_str) == 0; }
+
+ 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;
+
/* the following are extensions to <string> */
size_type mem_t_size() const { return m_str.size(); }
+ pstring_t left(size_type len) const { return substr(0, len); }
+ pstring_t right(size_type nlen) const
+ {
+ return nlen >= length() ? *this : substr(length() - nlen, nlen);
+ }
+
+ pstring_t ltrim(const pstring_t &ws = pstring_t(" \t\n\r")) const
+ {
+ return substr(find_first_not_of(ws));
+ }
+
+ pstring_t rtrim(const pstring_t &ws = pstring_t(" \t\n\r")) const
+ {
+ auto f = find_last_not_of(ws);
+ return f == npos ? pstring_t() : substr(0, f + 1);
+ }
+
+ pstring_t trim(const pstring_t &ws = pstring_t(" \t\n\r")) const { return this->ltrim(ws).rtrim(ws); }
+
+ pstring_t rpad(const pstring_t &ws, const size_type cnt) const;
+
+ pstring_t ucase() const;
+
const string_type &cpp_string() const { return m_str; }
- static constexpr const size_type npos = static_cast<size_type>(-1);
+ static const size_type npos = static_cast<size_type>(-1);
-private:
+protected:
string_type m_str;
+
+private:
};
struct pu8_traits
{
- using mem_t = char;
- using code_t = char;
- using string_type = std::string;
+ typedef char mem_t;
+ typedef char code_t;
+ typedef std::string string_type;
static std::size_t len(const string_type &p) { return p.size(); }
- static std::size_t codelen(const mem_t *p) { plib::unused_var(p); return 1; }
- static std::size_t codelen(const code_t c) { plib::unused_var(c); return 1; }
+ static std::size_t codelen(const mem_t *p) { return 1; }
+ static std::size_t codelen(const code_t c) { return 1; }
static code_t code(const mem_t *p) { return *p; }
static void encode(const code_t c, string_type &s) { s += static_cast<mem_t>(c); }
static const mem_t *nthcode(const mem_t *p, const std::size_t n) { return &(p[n]); }
@@ -226,9 +270,9 @@ struct pu8_traits
/* No checking, this may deliver invalid codes */
struct putf8_traits
{
- using mem_t = char;
- using code_t = char32_t;
- using string_type = std::string;
+ typedef char mem_t;
+ typedef char32_t code_t;
+ typedef std::string string_type;
static std::size_t len(const string_type &p)
{
std::size_t ret = 0;
@@ -241,7 +285,7 @@ struct putf8_traits
}
static std::size_t codelen(const mem_t *p)
{
- const auto p1 = reinterpret_cast<const unsigned char *>(p);
+ const unsigned char *p1 = reinterpret_cast<const unsigned char *>(p);
if ((*p1 & 0x80) == 0x00)
return 1;
else if ((*p1 & 0xE0) == 0xC0)
@@ -268,7 +312,7 @@ struct putf8_traits
}
static code_t code(const mem_t *p)
{
- const auto p1 = reinterpret_cast<const unsigned char *>(p);
+ const unsigned char *p1 = reinterpret_cast<const unsigned char *>(p);
if ((*p1 & 0x80) == 0x00)
return *p1;
else if ((*p1 & 0xE0) == 0xC0)
@@ -317,9 +361,9 @@ struct putf8_traits
struct putf16_traits
{
- using mem_t = char16_t;
- using code_t = char32_t;
- using string_type = std::u16string;
+ typedef char16_t mem_t;
+ typedef char32_t code_t;
+ typedef std::u16string string_type;
static std::size_t len(const string_type &p)
{
std::size_t ret = 0;
@@ -327,7 +371,7 @@ struct putf16_traits
while (i != p.end())
{
// FIXME: check that size is equal
- auto c = static_cast<uint16_t>(*i++);
+ uint16_t c = static_cast<uint16_t>(*i++);
if (!((c & 0xd800) == 0xd800))
ret++;
}
@@ -335,7 +379,7 @@ struct putf16_traits
}
static std::size_t codelen(const mem_t *p)
{
- auto c = static_cast<uint16_t>(*p);
+ uint16_t c = static_cast<uint16_t>(*p);
return ((c & 0xd800) == 0xd800) ? 2 : 1;
}
static std::size_t codelen(const code_t c)
@@ -347,7 +391,7 @@ struct putf16_traits
}
static code_t code(const mem_t *p)
{
- auto c = static_cast<uint32_t>(*p++);
+ uint32_t c = static_cast<uint32_t>(*p++);
if ((c & 0xd800) == 0xd800)
{
c = (c - 0xd800) << 10;
@@ -357,7 +401,7 @@ struct putf16_traits
}
static void encode(code_t c, string_type &s)
{
- auto cu = static_cast<uint32_t>(c);
+ uint32_t cu = static_cast<uint32_t>(c);
if (c > 0xffff)
{ //make a surrogate pair
uint32_t t = ((cu - 0x10000) >> 10) + 0xd800;
@@ -381,9 +425,9 @@ struct putf16_traits
struct pwchar_traits
{
- using mem_t = wchar_t;
- using code_t = char32_t;
- using string_type = std::wstring;
+ typedef wchar_t mem_t;
+ typedef char32_t code_t;
+ typedef std::wstring string_type;
static std::size_t len(const string_type &p)
{
if (sizeof(wchar_t) == 2)
@@ -393,7 +437,7 @@ struct pwchar_traits
while (i != p.end())
{
// FIXME: check that size is equal
- auto c = static_cast<uint32_t>(*i++);
+ uint32_t c = static_cast<uint32_t>(*i++);
if (!((c & 0xd800) == 0xd800))
ret++;
}
@@ -407,7 +451,7 @@ struct pwchar_traits
{
if (sizeof(wchar_t) == 2)
{
- auto c = static_cast<uint16_t>(*p);
+ uint16_t c = static_cast<uint16_t>(*p);
return ((c & 0xd800) == 0xd800) ? 2 : 1;
}
else
@@ -426,7 +470,7 @@ struct pwchar_traits
{
if (sizeof(wchar_t) == 2)
{
- auto c = static_cast<uint32_t>(*p++);
+ uint32_t c = static_cast<uint32_t>(*p++);
if ((c & 0xd800) == 0xd800)
{
c = (c - 0xd800) << 10;
@@ -442,7 +486,7 @@ struct pwchar_traits
{
if (sizeof(wchar_t) == 2)
{
- auto cu = static_cast<uint32_t>(c);
+ uint32_t cu = static_cast<uint32_t>(c);
if (c > 0xffff)
{ //make a surrogate pair
uint32_t t = ((cu - 0x10000) >> 10) + 0xd800;
@@ -475,280 +519,41 @@ extern template struct pstring_t<putf8_traits>;
extern template struct pstring_t<putf16_traits>;
extern template struct pstring_t<pwchar_traits>;
-#if (PSTRING_USE_STD_STRING)
-typedef std::string pstring;
-#else
-using pstring = pstring_t<putf8_traits>;
-#endif
-using putf8string = pstring_t<putf8_traits>;
-using pu16string = pstring_t<putf16_traits>;
-using pwstring = pstring_t<pwchar_traits>;
+typedef pstring_t<putf8_traits> pstring;
+typedef pstring_t<putf16_traits> pu16string;
+typedef pstring_t<pwchar_traits> pwstring;
namespace plib
{
- template<class T>
- struct string_info
- {
- using mem_t = typename T::mem_t;
- };
-
- template<>
- struct string_info<std::string>
- {
- using mem_t = char;
- };
-
template<typename T>
pstring to_string(const T &v)
{
- return pstring(std::to_string(v));
+ return pstring(std::to_string(v), pstring::UTF8);
}
template<typename T>
pwstring to_wstring(const T &v)
{
- return pwstring(std::to_wstring(v));
- }
-
- template <typename T, typename E = void>
- struct pstonum_helper;
-
- template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value
- && std::is_signed<T>::value>::type>
- {
- template <typename S>
- long long operator()(const S &arg, std::size_t *idx)
- {
- return std::stoll(arg, idx);
- }
- };
-
- template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_integral<T>::value
- && !std::is_signed<T>::value>::type>
- {
- template <typename S>
- unsigned long long operator()(const S &arg, std::size_t *idx)
- {
- return std::stoull(arg, idx);
- }
- };
-
- template<typename T>
- struct pstonum_helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
- {
- template <typename S>
- long double operator()(const S &arg, std::size_t *idx)
- {
- return std::stold(arg, idx);
- }
- };
-
- template<typename T, typename S>
- T pstonum(const S &arg)
- {
- decltype(arg.c_str()) cstr = arg.c_str();
- std::size_t idx(0);
- auto ret = pstonum_helper<T>()(cstr, &idx);
- using ret_type = decltype(ret);
- if (ret >= static_cast<ret_type>(std::numeric_limits<T>::lowest())
- && ret <= static_cast<ret_type>(std::numeric_limits<T>::max()))
- //&& (ret == T(0) || std::abs(ret) >= std::numeric_limits<T>::min() ))
- {
- if (cstr[idx] != 0)
- throw std::invalid_argument(std::string("Continuation after numeric value ends: ") + cstr);
- }
- else
- {
- throw std::out_of_range(std::string("Out of range: ") + cstr);
- }
- return static_cast<T>(ret);
- }
-
- template<typename R, typename T>
- R pstonum_ne(const T &str, bool &err) noexcept
- {
- try
- {
- err = false;
- return pstonum<R>(str);
- }
- catch (...)
- {
- err = true;
- return R(0);
- }
- }
-
- template<typename T>
- typename T::size_type find_first_not_of(const T &str, const T &no)
- {
- typename T::size_type pos = 0;
- for (auto it = str.begin(); it != str.end(); ++it, ++pos)
- {
- bool f = true;
- for (typename T::value_type const jt : no)
- {
- if (*it == jt)
- {
- f = false;
- break;
- }
- }
- if (f)
- return pos;
- }
- return T::npos;
- }
-
- template<typename T>
- typename T::size_type find_last_not_of(const T &str, const T &no)
- {
- /* FIXME: reverse iterator */
- typename T::size_type last_found = T::npos;
- typename T::size_type pos = 0;
- for (auto it = str.begin(); it != str.end(); ++it, ++pos)
- {
- bool f = true;
- for (typename T::value_type const jt : no)
- {
- if (*it == jt)
- {
- f = false;
- break;
- }
- }
- if (f)
- last_found = pos;
- }
- return last_found;
- }
-
- template<typename T>
- T ltrim(const T &str, const T &ws = T(" \t\n\r"))
- {
- auto f = find_first_not_of(str, ws);
- return (f == T::npos) ? T() : str.substr(f);
+ return pwstring(std::to_wstring(v), pwstring::UTF16);
}
-
- template<typename T>
- T rtrim(const T &str, const T &ws = T(" \t\n\r"))
- {
- auto f = find_last_not_of(str, ws);
- return (f == T::npos) ? T() : str.substr(0, f + 1);
- }
-
- template<typename T>
- T trim(const T &str, const T &ws = T(" \t\n\r"))
- {
- return rtrim(ltrim(str, ws), ws);
- }
-
- template<typename T>
- T left(const T &str, typename T::size_type len)
- {
- return str.substr(0, len);
- }
-
- template<typename T>
- T right(const T &str, typename T::size_type nlen)
- {
- return nlen >= str.length() ? str : str.substr(str.length() - nlen, nlen);
- }
-
- template<typename T>
- bool startsWith(const T &str, const T &arg)
- {
- return (arg == left(str, arg.length()));
- }
-
- template<typename T>
- bool endsWith(const T &str, const T &arg)
- {
- return (right(str, arg.length()) == arg);
- }
-
- template<typename T>
- bool startsWith(const T &str, const char *arg)
- {
- return (left(str, std::strlen(arg)) == arg);
- }
-
- template<typename T>
- bool endsWith(const T &str, const char *arg)
- {
- return (right(str, std::strlen(arg)) == arg);
- }
-
- template<typename T>
- T ucase(const T &str)
- {
- T ret;
- for (const auto &c : str)
- if (c >= 'a' && c <= 'z')
- ret += (c - 'a' + 'A');
- else
- ret += c;
- return ret;
- }
-
- template<typename T>
- T rpad(const T &str, const T &ws, const typename T::size_type cnt)
- {
- // FIXME: pstringbuffer ret(*this);
-
- T ret(str);
- typename T::size_type wsl = ws.length();
- for (auto i = ret.length(); i < cnt; i+=wsl)
- ret += ws;
- return ret;
- }
-
- template<typename T>
- T replace_all(const T &str, const T &search, const T &replace)
- {
- T ret;
- const typename T::size_type slen = search.length();
-
- typename T::size_type last_s = 0;
- typename T::size_type s = str.find(search, last_s);
- while (s != T::npos)
- {
- ret += str.substr(last_s, s - last_s);
- ret += replace;
- last_s = s + slen;
- s = str.find(search, last_s);
- }
- ret += str.substr(last_s);
- return ret;
- }
-
- template<typename T, typename T1, typename T2>
- T replace_all(const T &str, const T1 &search, const T2 &replace)
- {
- return replace_all(str, static_cast<T>(search), static_cast<T>(replace));
- }
-
-} // namespace plib
+}
// custom specialization of std::hash can be injected in namespace std
namespace std
{
-
template<typename T> struct hash<pstring_t<T>>
{
- using argument_type = pstring_t<T>;
- using result_type = std::size_t;
+ typedef pstring_t<T> argument_type;
+ typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
- const typename argument_type::mem_t *string = s.c_str();
+ const pstring::mem_t *string = s.c_str();
result_type result = 5381;
- for (typename argument_type::mem_t c = *string; c != 0; c = *string++)
+ for (pstring::mem_t c = *string; c != 0; c = *string++)
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c);
return result;
}
};
-} // namespace std
+}
#endif /* PSTRING_H_ */