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.h595
1 files changed, 210 insertions, 385 deletions
diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h
index 96ab0bd0fa5..33ef2b083cf 100644
--- a/src/lib/netlist/plib/pstring.h
+++ b/src/lib/netlist/plib/pstring.h
@@ -1,17 +1,19 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * pstring.h
- */
#ifndef PSTRING_H_
#define PSTRING_H_
+///
+/// \file pstring.h
+///
+
#include "ptypes.h"
#include <exception>
#include <iterator>
#include <limits>
+#include <ostream>
#include <stdexcept>
#include <string>
#include <type_traits>
@@ -51,8 +53,8 @@ public:
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; }
- 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)); } // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
+ pointer operator->() const noexcept { return reinterpret_cast<pointer>(&(*p)); } // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
private:
template <typename G> friend struct pstring_t;
@@ -72,6 +74,9 @@ public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using string_type = typename traits_type::string_type;
+ // no non-const const_iterator for now
+ using iterator = pstring_const_iterator<pstring_t<F> >;
+ using const_iterator = pstring_const_iterator<pstring_t<F> >;
// FIXME: this is ugly
struct ref_value_type final
@@ -94,32 +99,45 @@ public:
pstring_t() = default;
~pstring_t() noexcept = default;
- // FIXME: Do something with encoding
- pstring_t(const mem_t *string)
- : m_str(string)
+ pstring_t(const mem_t *string, const size_type len)
+ : m_str(string, len)
{
}
- pstring_t(const mem_t *string, const size_type len)
- : m_str(string, len)
+ // mingw treats string constants as char* instead of char[N]
+ template<typename C,
+ class = std::enable_if_t<std::is_same<C, const mem_t>::value>>
+ pstring_t(const C *string)
+ : m_str(string)
{
}
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)
+ class = std::enable_if_t<std::is_same<C, const mem_t>::value>>
+ pstring_t(C (&string)[N]) noexcept(false) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
{
static_assert(N > 0,"pstring from array of length 0");
+ // need std::exception since pexception depends on pstring
if (string[N-1] != 0)
throw std::exception();
m_str.assign(string, N - 1);
}
+ // interpret other string as putf8strings
+ template <typename C,
+ class = std::enable_if_t<std::is_same<std::remove_const_t<C>, char>::value
+ && !std::is_same<std::remove_const_t<C>, mem_t>::value>>
+ pstring_t(C *string);
explicit pstring_t(const string_type &string)
: m_str(string)
{ }
+ pstring_t(iterator first, iterator last)
+ {
+ m_str.assign(first.p, last.p);
+ }
+
pstring_t(const pstring_t &string) = default;
pstring_t(pstring_t &&string) noexcept = default;
pstring_t &operator=(const pstring_t &string) = default;
@@ -127,12 +145,12 @@ public:
explicit pstring_t(size_type n, code_t code)
{
- while (n--)
+ while (n-- != 0)
*this += code;
}
template <typename T,
- class = typename std::enable_if<!std::is_same<T, pstring_t::traits_type>::value>::type>
+ class = std::enable_if_t<!std::is_same<T, pstring_t::traits_type>::value>>
explicit pstring_t(const pstring_t<T> &string)
{
m_str.clear();
@@ -142,9 +160,8 @@ public:
operator string_type () const { return m_str; }
-
template <typename T,
- class = typename std::enable_if<!std::is_same<T, pstring_t::traits_type>::value>::type>
+ class = std::enable_if_t<!std::is_same<T, pstring_t::traits_type>::value>>
pstring_t &operator=(const pstring_t<T> &string)
{
m_str.clear();
@@ -153,66 +170,72 @@ public:
return *this;
}
- // no non-const const_iterator for now
- using iterator = pstring_const_iterator<pstring_t<F> >;
- using const_iterator = pstring_const_iterator<pstring_t<F> >;
-
- 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()); }
+ iterator begin() noexcept { return iterator(m_str.begin()); }
+ iterator end() noexcept { return iterator(m_str.end()); }
+ const_iterator begin() const noexcept { return const_iterator(m_str.begin()); }
+ const_iterator end() const noexcept { return const_iterator(m_str.end()); }
+ const_iterator cbegin() const noexcept { return const_iterator(m_str.begin()); }
+ const_iterator cend() const noexcept { return const_iterator(m_str.end()); }
// C string conversion helpers
- const mem_t *c_str() const { return static_cast<const mem_t *>(m_str.c_str()); }
- const mem_t *data() const { return c_str(); }
+ const mem_t *c_str() const noexcept { return static_cast<const mem_t *>(m_str.c_str()); }
+ const mem_t *data() const noexcept { return c_str(); }
+
+ /// \brief return number of codes in the string
+ ///
+ /// This may report a number less than what \ref size reports. pstrings
+ /// operate on character codes. In the case of utf pstrings thus the physical size
+ /// may be bigger than the logical size.
+ size_type length() const noexcept { return traits_type::len(m_str); }
- size_type length() const { return traits_type::len(m_str); }
- size_type size() const { return traits_type::len(m_str); }
- bool empty() const { return m_str.size() == 0; }
+ /// \brief return number of memory units in the string
+ ///
+ /// This function returns the number of memory units used by a string.
+ /// Depending on the string type the size may be reported as bytes, words
+ /// or quad-words.
+ size_type size() const noexcept { return m_str.size(); }
- pstring_t substr(size_type start, size_type nlen = npos) const;
- int compare(const pstring_t &right) const;
+ bool empty() const noexcept { return m_str.empty(); }
+ void clear() noexcept { m_str.clear(); }
- size_type find(const pstring_t &search, size_type start = 0) const;
- size_type find(code_t search, size_type start = 0) const;
+ pstring_t substr(size_type start, size_type nlen) const;
+ pstring_t substr(size_type start) const;
+ int compare(const pstring_t &right) const noexcept;
- size_type find_first_not_of(const pstring_t &no) const;
- size_type find_last_not_of(const pstring_t &no) const;
+ size_type find(const pstring_t &search, size_type start = 0) const noexcept;
+ size_type find(code_t search, size_type start = 0) const noexcept;
// concatenation operators
pstring_t& operator+=(const pstring_t &string) { m_str.append(string.m_str); return *this; }
pstring_t& operator+=(const code_t c) { traits_type::encode(c, m_str); 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; }
- friend pstring_t operator+(const code_t lhs, const pstring_t &rhs) { return pstring_t(1, lhs) += rhs; }
+ friend pstring_t operator+(const pstring_t &lhs, code_t rhs) { return pstring_t(lhs) += rhs; }
+ friend pstring_t operator+(code_t lhs, const pstring_t &rhs) { return pstring_t(1, lhs) += rhs; }
// comparison operators
- bool operator==(const pstring_t &string) const { return (compare(string) == 0); }
- bool operator!=(const pstring_t &string) const { return (compare(string) != 0); }
+ bool operator==(const pstring_t &string) const noexcept { return m_str == string.m_str; }
+ bool operator!=(const pstring_t &string) const noexcept { return m_str != string.m_str; }
- bool operator<(const pstring_t &string) const { return (compare(string) < 0); }
- bool operator<=(const pstring_t &string) const { return (compare(string) <= 0); }
- bool operator>(const pstring_t &string) const { return (compare(string) > 0); }
- bool operator>=(const pstring_t &string) const { return (compare(string) >= 0); }
+ bool operator<(const pstring_t &string) const noexcept { return (compare(string) < 0); }
+ bool operator<=(const pstring_t &string) const noexcept { return (compare(string) <= 0); }
+ bool operator>(const pstring_t &string) const noexcept { return (compare(string) > 0); }
+ bool operator>=(const pstring_t &string) const noexcept { return (compare(string) >= 0); }
- friend std::ostream& operator<<(std::ostream &ostrm, const pstring_t &str)
+ friend auto operator<<(std::basic_ostream<typename string_type::value_type> &ostrm, const pstring_t &str) -> std::basic_ostream<typename string_type::value_type> &
{
ostrm << str.m_str;
return ostrm;
}
- const_reference at(const size_type pos) const { return *reinterpret_cast<const ref_value_type *>(F::nthcode(m_str.c_str(),pos)); }
+ const_reference at(const size_type pos) const { return *reinterpret_cast<const ref_value_type *>(F::nthcode(m_str.c_str(),pos)); } // NOLINT(cppcoreguidelines-pro-type-reinterpret
static constexpr const size_type npos = static_cast<size_type>(-1);
- /* the following are extensions to <string> */
-
+ // the following are extensions to <string>
// FIXME: remove those
- size_type mem_t_size() const { return m_str.size(); }
-
+ size_type mem_t_size() const noexcept { return m_str.size(); }
private:
+
string_type m_str;
};
@@ -221,112 +244,111 @@ struct pu8_traits
using mem_t = char;
using code_t = char;
using string_type = std::string;
- 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 code_t code(const mem_t *p) { return *p; }
+ static std::size_t len(const string_type &p) noexcept { return p.size(); }
+ static std::size_t codelen(const mem_t *p) noexcept { plib::unused_var(p); return 1; }
+ static std::size_t codelen(code_t c) noexcept { plib::unused_var(c); return 1; }
+ static code_t code(const mem_t *p) noexcept { 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]); }
+ static const mem_t *nthcode(const mem_t *p, std::size_t n) noexcept { return &(p[n]); }
};
-/* No checking, this may deliver invalid codes */
-struct putf8_traits
+// No checking, this may deliver invalid codes
+
+
+template <std::size_t N, typename CT>
+struct putf_traits
{
- using mem_t = char;
+};
+
+template<typename CT>
+struct putf_traits<1, CT>
+{
+ using mem_t = CT;
using code_t = char32_t;
- using string_type = std::string;
- static std::size_t len(const string_type &p)
+ using string_type = std::basic_string<CT>;
+ static std::size_t len(const string_type &p) noexcept
{
std::size_t ret = 0;
for (const auto &c : p)
{
- if (!((c & 0xC0) == 0x80))
- ret++;
+ ret += (!((c & 0xC0) == 0x80)); // NOLINT
}
return ret;
}
- static std::size_t codelen(const mem_t *p)
+
+ static constexpr std::size_t codelen(const mem_t *p) noexcept
{
- const auto p1 = reinterpret_cast<const unsigned char *>(p);
- if ((*p1 & 0x80) == 0x00)
- return 1;
- else if ((*p1 & 0xE0) == 0xC0)
- return 2;
- else if ((*p1 & 0xF0) == 0xE0)
- return 3;
- else if ((*p1 & 0xF8) == 0xF0)
- return 4;
- else
- {
- return 1; // not correct
- }
+ const auto *p1 = reinterpret_cast<const unsigned char *>(p); // NOLINT(cppcoreguidelines-pro-type-reinterpret
+ return ((*p1 & 0x80) == 0x00) ? 1 : // NOLINT
+ ((*p1 & 0xE0) == 0xC0) ? 2 : // NOLINT
+ ((*p1 & 0xF0) == 0xE0) ? 3 : // NOLINT
+ ((*p1 & 0xF8) == 0xF0) ? 4 : // NOLINT
+ 1; // Invalid UTF8 code - ignore
}
- static std::size_t codelen(const code_t c)
+
+ static constexpr std::size_t codelen(code_t c) noexcept
{
- if (c < 0x0080)
- return 1;
- else if (c < 0x800)
- return 2;
- else if (c < 0x10000)
- return 3;
- else /* U+10000 U+1FFFFF */
- return 4; /* no checks */
+ return (c < 0x00080) ? 1 : // NOLINT
+ (c < 0x00800) ? 2 : // NOLINT
+ (c < 0x10000) ? 3 : // NOLINT
+ 4; // U+10000 U+1FFFFF
}
- static code_t code(const mem_t *p)
+
+ static constexpr code_t code(const mem_t *p) noexcept
{
- const auto p1 = reinterpret_cast<const unsigned char *>(p);
- if ((*p1 & 0x80) == 0x00)
- return *p1;
- else if ((*p1 & 0xE0) == 0xC0)
- return static_cast<code_t>(((p1[0] & 0x3f) << 6) | (p1[1] & 0x3f));
- else if ((*p1 & 0xF0) == 0xE0)
- return static_cast<code_t>(((p1[0] & 0x1f) << 12) | ((p1[1] & 0x3f) << 6) | ((p1[2] & 0x3f) << 0));
- else if ((*p1 & 0xF8) == 0xF0)
- return static_cast<code_t>(((p1[0] & 0x0f) << 18) | ((p1[1] & 0x3f) << 12) | ((p1[2] & 0x3f) << 6) | ((p1[3] & 0x3f) << 0));
- else
- return *p1; // not correct
+ const auto *p1 = reinterpret_cast<const unsigned char *>(p); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
+ return ((*p1 & 0x80) == 0x00) ? *p1 : // NOLINT
+ ((*p1 & 0xE0) == 0xC0) ? static_cast<code_t>(((p1[0] & 0x3f) << 6) | (p1[1] & 0x3f)) : // NOLINT
+ ((*p1 & 0xF0) == 0xE0) ? static_cast<code_t>(((p1[0] & 0x1f) << 12) | ((p1[1] & 0x3f) << 6) | ((p1[2] & 0x3f) << 0)) : // NOLINT
+ ((*p1 & 0xF8) == 0xF0) ? static_cast<code_t>(((p1[0] & 0x0f) << 18) | ((p1[1] & 0x3f) << 12) | ((p1[2] & 0x3f) << 6) | ((p1[3] & 0x3f) << 0)) : // NOLINT
+ 0xFFFD; // NOLINT: unicode-replacement character
}
+
static void encode(const code_t c, string_type &s)
{
- if (c < 0x0080)
+ if (c < 0x0080) // NOLINT
{
s += static_cast<mem_t>(c);
}
- else if (c < 0x800)
+ else if (c < 0x800) // NOLINT
{
- s += static_cast<mem_t>(0xC0 | (c >> 6));
- s += static_cast<mem_t>(0x80 | (c & 0x3f));
+ s += static_cast<mem_t>(0xC0 | (c >> 6)); // NOLINT
+ s += static_cast<mem_t>(0x80 | (c & 0x3f)); // NOLINT
}
- else if (c < 0x10000)
+ else if (c < 0x10000) // NOLINT
{
- s += static_cast<mem_t>(0xE0 | (c >> 12));
- s += static_cast<mem_t>(0x80 | ((c>>6) & 0x3f));
- s += static_cast<mem_t>(0x80 | (c & 0x3f));
+ s += static_cast<mem_t>(0xE0 | (c >> 12)); // NOLINT
+ s += static_cast<mem_t>(0x80 | ((c>>6) & 0x3f)); // NOLINT
+ s += static_cast<mem_t>(0x80 | (c & 0x3f)); // NOLINT
}
- else /* U+10000 U+1FFFFF */
+ else // U+10000 U+1FFFFF
{
- s += static_cast<mem_t>(0xF0 | (c >> 18));
- s += static_cast<mem_t>(0x80 | ((c>>12) & 0x3f));
- s += static_cast<mem_t>(0x80 | ((c>>6) & 0x3f));
- s += static_cast<mem_t>(0x80 | (c & 0x3f));
+ s += static_cast<mem_t>(0xF0 | (c >> 18)); // NOLINT
+ s += static_cast<mem_t>(0x80 | ((c>>12) & 0x3f)); // NOLINT
+ s += static_cast<mem_t>(0x80 | ((c>>6) & 0x3f)); // NOLINT
+ s += static_cast<mem_t>(0x80 | (c & 0x3f)); // NOLINT
}
}
- static const mem_t *nthcode(const mem_t *p, const std::size_t n)
+
+ static const mem_t *nthcode(const mem_t *p, std::size_t n) noexcept
{
const mem_t *p1 = p;
std::size_t i = n;
while (i-- > 0)
+ {
p1 += codelen(p1);
+ }
return p1;
}
};
-struct putf16_traits
+template<typename CT>
+struct putf_traits<2, CT>
{
- using mem_t = char16_t;
+ using mem_t = CT;
using code_t = char32_t;
- using string_type = std::u16string;
- static std::size_t len(const string_type &p)
+ using string_type = std::basic_string<CT>;
+ static std::size_t len(const string_type &p) noexcept
{
std::size_t ret = 0;
auto i = p.begin();
@@ -334,40 +356,39 @@ struct putf16_traits
{
// FIXME: check that size is equal
auto c = static_cast<uint16_t>(*i++);
- if (!((c & 0xd800) == 0xd800))
+ if (!((c & 0xd800) == 0xd800)) // NOLINT
+ {
ret++;
+ }
}
return ret;
}
- static std::size_t codelen(const mem_t *p)
+ static std::size_t codelen(const mem_t *p) noexcept
{
auto c = static_cast<uint16_t>(*p);
- return ((c & 0xd800) == 0xd800) ? 2 : 1;
+ return ((c & 0xd800) == 0xd800) ? 2 : 1; // NOLINT
}
- static std::size_t codelen(const code_t c)
+ static std::size_t codelen(code_t c) noexcept
{
- if (c < 0x10000)
- return 1;
- else /* U+10000 U+1FFFFF */
- return 2;
+ return (c < 0x10000) ? 1 : 2; // NOLINT: U+10000 U+1FFFFF
}
- static code_t code(const mem_t *p)
+ static code_t code(const mem_t *p) noexcept
{
auto c = static_cast<uint32_t>(*p++);
- if ((c & 0xd800) == 0xd800)
+ if ((c & 0xd800) == 0xd800) // NOLINT
{
- c = (c - 0xd800) << 10;
- c += static_cast<uint32_t>(*p) - 0xdc00 + 0x10000;
+ c = (c - 0xd800) << 10; // NOLINT
+ c += static_cast<uint32_t>(*p) - 0xdc00 + 0x10000; // NOLINT
}
return static_cast<code_t>(c);
}
- static void encode(code_t c, string_type &s)
+ static void encode(code_t c, string_type &s) noexcept
{
auto cu = static_cast<uint32_t>(c);
- if (c > 0xffff)
+ if (c > 0xffff) // NOLINT
{ //make a surrogate pair
- uint32_t t = ((cu - 0x10000) >> 10) + 0xd800;
- cu = (cu & 0x3ff) + 0xdc00;
+ uint32_t t = ((cu - 0x10000) >> 10) + 0xd800; // NOLINT
+ cu = (cu & 0x3ff) + 0xdc00; // NOLINT
s += static_cast<mem_t>(t);
s += static_cast<mem_t>(cu);
}
@@ -376,327 +397,131 @@ struct putf16_traits
s += static_cast<mem_t>(cu);
}
}
- static const mem_t *nthcode(const mem_t *p, const std::size_t n)
+ static const mem_t *nthcode(const mem_t *p, std::size_t n) noexcept
{
std::size_t i = n;
while (i-- > 0)
+ {
p += codelen(p);
+ }
return p;
}
};
-struct pwchar_traits
+template<typename CT>
+struct putf_traits<4, CT>
{
- using mem_t = wchar_t;
+ using mem_t = CT;
using code_t = char32_t;
- using string_type = std::wstring;
- static std::size_t len(const string_type &p)
+ using string_type = std::basic_string<CT>;
+ static std::size_t len(const string_type &p) noexcept
{
- if (sizeof(wchar_t) == 2)
- {
- std::size_t ret = 0;
- auto i = p.begin();
- while (i != p.end())
- {
- // FIXME: check that size is equal
- auto c = static_cast<uint32_t>(*i++);
- if (!((c & 0xd800) == 0xd800))
- ret++;
- }
- return ret;
- }
- else
- return p.size();
+ return p.size();
}
- static std::size_t codelen(const mem_t *p)
+ static std::size_t codelen(const mem_t *p) noexcept
{
- if (sizeof(wchar_t) == 2)
- {
- auto c = static_cast<uint16_t>(*p);
- return ((c & 0xd800) == 0xd800) ? 2 : 1;
- }
- else
- return 1;
+ plib::unused_var(p);
+ return 1;
}
- static std::size_t codelen(const code_t c)
+ static std::size_t codelen(code_t c) noexcept
{
- if (sizeof(wchar_t) == 2)
- return ((c & 0xd800) == 0xd800) ? 2 : 1;
- else
- return 1;
+ plib::unused_var(c);
+ return 1;
}
static code_t code(const mem_t *p)
{
- if (sizeof(wchar_t) == 2)
- {
- auto c = static_cast<uint32_t>(*p++);
- if ((c & 0xd800) == 0xd800)
- {
- c = (c - 0xd800) << 10;
- c += static_cast<uint32_t>(*p) - 0xdc00 + 0x10000;
- }
- return static_cast<code_t>(c);
- }
- else
- return static_cast<code_t>(*p);
+ return static_cast<code_t>(*p);
}
static void encode(code_t c, string_type &s)
{
- if (sizeof(wchar_t) == 2)
- {
- auto cu = static_cast<uint32_t>(c);
- if (c > 0xffff)
- { //make a surrogate pair
- uint32_t t = ((cu - 0x10000) >> 10) + 0xd800;
- cu = (cu & 0x3ff) + 0xdc00;
- s += static_cast<mem_t>(t);
- s += static_cast<mem_t>(cu);
- }
- else
- s += static_cast<mem_t>(cu);
- }
- else
- s += static_cast<wchar_t>(c);
+ s += static_cast<mem_t>(c);
}
- static const mem_t *nthcode(const mem_t *p, const std::size_t n)
+ static const mem_t *nthcode(const mem_t *p, std::size_t n) noexcept
{
- if (sizeof(wchar_t) == 2)
- {
- std::size_t i = n;
- while (i-- > 0)
- p += codelen(p);
- return p;
- }
- else
- return p + n;
+ return p + n;
}
};
+using putf8_traits = putf_traits<sizeof(char), char>;
+using putf16_traits = putf_traits<sizeof(char16_t), char16_t>;
+using putf32_traits = putf_traits<sizeof(char32_t), char32_t>;
+using pwchar_traits = putf_traits<sizeof(wchar_t), wchar_t>;
+
extern template struct pstring_t<pu8_traits>;
extern template struct pstring_t<putf8_traits>;
extern template struct pstring_t<putf16_traits>;
+extern template struct pstring_t<putf32_traits>;
extern template struct pstring_t<pwchar_traits>;
#if (PSTRING_USE_STD_STRING)
using pstring = std::string;
-static inline pstring::size_type pstring_mem_t_size(const pstring &s) { return s.size(); }
#else
using pstring = pstring_t<putf8_traits>;
-template <typename T>
-static inline pstring::size_type pstring_mem_t_size(const pstring_t<T> &s) { return s.mem_t_size(); }
#endif
+using pu8string = pstring_t<pu8_traits>;
using putf8string = pstring_t<putf8_traits>;
-using pu16string = pstring_t<putf16_traits>;
+using putf16string = pstring_t<putf16_traits>;
+using putf32string = pstring_t<putf32_traits>;
using pwstring = pstring_t<pwchar_traits>;
+// interpret other string as putf8strings
+template <typename F>
+template <typename C, class>
+pstring_t<F>::pstring_t(C *string)
+{
+ m_str.clear();
+ putf8string utf8(string);
+ for (const auto &c : utf8)
+ *this += c;
+}
+
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));
- }
-
template<typename T>
- pwstring to_wstring(const T &v)
+ struct string_info<pstring_t<T>>
{
- return pwstring(std::to_wstring(v));
- }
-
-
- 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);
- }
-
- 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 startsWith(str, static_cast<pstring>(arg));
- }
-
- template<typename T>
- bool endsWith(const T &str, const char *arg)
- {
- return endsWith(str, static_cast<pstring>(arg));
- }
-
- template<typename T>
- std::size_t strlen(const T *str)
- {
- const T *p = str;
- while (*p)
- p++;
- return static_cast<std::size_t>(p - str);
- }
-
- 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;
- }
+ using mem_t = typename T::mem_t;
+#if 0
+ static std::size_t mem_size(const pstring_t<T> &s) { return s.mem_t_size(); }
+#endif
+ };
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)
+ struct string_info<std::basic_string<T>>
{
- return replace_all(str, static_cast<T>(search), static_cast<T>(replace));
- }
-
+ using mem_t = T;
+#if 0
+ static std::size_t mem_size(const std::basic_string<T> &s) { return s.size(); }
+#endif
+ };
} // namespace plib
// custom specialization of std::hash can be injected in namespace std
namespace std
{
-
- template<typename T> struct hash<pstring_t<T>>
+ template<typename T>
+ struct hash<pstring_t<T>>
{
using argument_type = pstring_t<T>;
using result_type = std::size_t;
result_type operator()(const argument_type & s) const
{
const typename argument_type::mem_t *string = s.c_str();
- result_type result = 5381;
+ result_type result = 5381; // NOLINT
for (typename argument_type::mem_t c = *string; c != 0; c = *string++)
- result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c);
+ result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c); // NOLINT
return result;
}
};
} // namespace std
-#endif /* PSTRING_H_ */
+#endif // PSTRING_H_