📄 superstr.cpp
字号:
// include logic for unequal lengths
int SS::compare (void const * bf0, int l0, void const * bf1, int l1)
{
int n = l0 < l1 ? l0 : l1;
int ret = SS::compare (bf0, bf1, n);
if (ret==0 && l0 != l1) {
ret = l0 < l1 ? -1 : 1;
}
return ret;
}
static inline bool ss_less_than (char a, char b)
{
return a < b;
}
static inline bool ss_nc_less_than (char a, char b)
{
return SS::getLower(a) < SS::getLower(b);
}
template <class T>
static inline int compareHelper (char const * a, int l0, T const & b, int l1, bool(less_than)(char,char) = ss_less_than)
{
int n = l0 < l1 ? l0 : l1;
int ret = 0;
{for (int i=0; i<n; i++) {
if (less_than (a[i],b[i])) {
ret = -1;
break;
} else if (less_than (b[i],a[i])) {
ret = 1;
break;
}
}}
if (ret==0 && l0 != l1) {
ret = l0 < l1 ? -1 : 1;
}
return ret;
}
int SS::compareString (char const * a, int l0, string const & b)
{
return compareHelper (a, l0, b, b.length());
}
int SS::compareVector (char const * a, int l0, std::vector<char> const & b)
{
return compareHelper (a, l0, b, b.size());
}
int SS::compareNoCase (SS const & s) const
{
return compareHelper (_rep, _len, s._rep, s._len, ss_nc_less_than);
}
bool SS::compare (Find const & f) const
{
int len;
int res = find (f, 0, &len);
return len == _len && res == 0;
}
void SS::fill (void * dst, char c, int n)
{
memset (dst, c, n);
}
int SS::findNext (void const * dat, char c, int n)
{
char const * ret = (char const *)memchr (dat, c, n);
return ret ? ret-(char const *)dat : notfound;
}
int SS::strLen (char const * s)
{
return s ? strlen (s) : 0;
}
int SS::strLen (signed char const * s)
{
return strLen (reinterpret_cast<char const *>(s));
}
int SS::strLen (unsigned char const * s)
{
return strLen (reinterpret_cast<char const *>(s));
}
// primitive for operator's +
SS SS::concatenate (SS const & u, SS const & w)
{
SS t (Buffer (u._len + w._len));
t.set (u);
return t.set (w, u._len);
}
SS SS::concatenate (std::vector<SS>& s)
{
int len=0;
{for (int i=0; i<s.size(); i++) {
len += s[i].length();
}}
SS ret ((Buffer)len);
len = 0;
{for (int i=0; i<s.size(); i++) {
ret.set (s[i], len);
len += s[i].length();
}}
return ret;
}
// doesn't report overflow
template <class T>
static inline T strToNumericBase (SS const & s, int base)
{
if (base<2 || base>36) ErrorMacro(SS::ErrorNumberFormat((SS)"strToNumeric - base of " + base + " is invalid"));
bool is_signed = false;
int left = 0;
if (s[left] == '+') {
left = 1;
} else if (s[left] == '-') {
left = 1;
is_signed = true;
}
T ret = 0;
{for (int i=left; i<s.size(); i++) {
char digit = s[i];
T x=0;
if (digit >= '0' && digit <= '9') {
x = digit-'0';
} else if (digit >= 'A' && digit <= 'Z') {
x = 10 + digit-'A';
} else if (digit >= 'a' && digit <= 'z') {
x = 10 + digit-'a';
} else {
ErrorMacro(SS::ErrorNumberFormat((SS)"strToNumeric - digit #"+ i + ", '"+digit+"' in base " + base + " is invalid"));
}
if (x<base) {
ret = x + base*ret;
} else {
ErrorMacro(SS::ErrorNumberFormat((SS)"strToNumeric - digit #"+ i + ", '"+digit+"' in base " + base + " is invalid"));
}
}}
if (is_signed) return -ret;
return ret;
}
template <class T>
static inline T strToNumeric (SS const & s)
{
if (s.size()>2 && s.head(2).toLower() == "0x") {
return strToNumericBase<T> (s.getFrom(2), 16);
}
return strToNumericBase<T> (s, 10);
}
bool SS::toBool () const
{
if (*this == "true" || *this == "1") return true;
if (*this == "false" || *this == "0") return false;
ErrorMacro(ErrorNumberFormat ((SS)"SS::toBool - can't convert " + *this));
return false;
}
short SS::toShort () const
{
return strToNumeric<short> (*this);
}
unsigned short SS::toUShort () const
{
return strToNumeric<unsigned short> (*this);
}
int SS::toInt () const
{
return strToNumeric<int> (*this);
}
unsigned int SS::toUInt () const
{
return strToNumeric<unsigned int> (*this);
}
long SS::toLong () const
{
return strToNumeric<long> (*this);
}
unsigned long SS::toULong () const
{
return strToNumeric<unsigned long> (*this);
}
SS::LongLong SS::toLongLong () const
{
return strToNumeric<LongLong> (*this);
}
SS::ULongLong SS::toULongLong () const
{
return strToNumeric<ULongLong> (*this);
}
short SS::toShort (int base) const
{
return strToNumericBase<short> (*this, base);
}
unsigned short SS::toUShort (int base) const
{
return strToNumericBase<unsigned short> (*this, base);
}
int SS::toInt (int base) const
{
return strToNumericBase<int> (*this, base);
}
unsigned int SS::toUInt (int base) const
{
return strToNumericBase<unsigned int> (*this, base);
}
long SS::toLong (int base) const
{
return strToNumericBase<long> (*this, base);
}
unsigned long SS::toULong (int base) const
{
return strToNumericBase<unsigned long> (*this, base);
}
SS::LongLong SS::toLongLong (int base) const
{
return strToNumericBase<LongLong> (*this, base);
}
SS::ULongLong SS::toULongLong (int base) const
{
return strToNumericBase<ULongLong> (*this, base);
}
template <class T> static inline T extract_using_strstream (SS const & s, T& t)
{
std::istrstream is (s.data());
is >> t;
if (is.fail() || is.bad()) {
ErrorMacro(SS::ErrorNumberFormat ((SS)"SS - extract_using_strstream - \"" + s + "\" not convertable"));
}
return t;
}
float SS::toFloat () const
{
float v;
return extract_using_strstream (*this, v);
// return toDouble();
}
double SS::toDouble () const
{
double v;
return extract_using_strstream (*this, v);
// char* end = 0;
// char const * beg = *this;
// double ret = strtod (beg, &end);
// if (end == beg || *end != nullchar) {
// ErrorMacro(ErrorNumberFormat ((SS)"SS::toDouble - \"" + *this + "\" not convertable"));
// }
// return ret;
}
long double SS::toLongDouble () const
{
long double v;
return extract_using_strstream (*this, v);
}
SS::string SS::toString () const
{
return string (_rep, _len);
}
std::vector<char> SS::toVector () const
{
std::vector<char> ret(_len);
{for (int i=0; i<_len; i++) {
ret[i] = _rep[i];
}}
return ret;
}
void SS::toInteger (short & number) const
{
number = strToNumeric<short> (*this);
}
void SS::toInteger (unsigned short & number) const
{
number = strToNumeric<unsigned short> (*this);
}
void SS::toInteger (int & number) const
{
number = strToNumeric<int> (*this);
}
void SS::toInteger (unsigned int & number) const
{
number = strToNumeric<unsigned int> (*this);
}
void SS::toInteger (long & number) const
{
number = strToNumeric<long> (*this);
}
void SS::toInteger (unsigned long & number) const
{
number = strToNumeric<unsigned long> (*this);
}
void SS::toInteger (LongLong & number) const
{
number = strToNumeric<LongLong> (*this);
}
void SS::toInteger (ULongLong & number) const
{
number = strToNumeric<ULongLong> (*this);
}
void SS::toInteger (short & number, int base) const
{
number = strToNumericBase<short> (*this, base);
}
void SS::toInteger (unsigned short & number, int base) const
{
number = strToNumericBase<unsigned short> (*this, base);
}
void SS::toInteger (int & number, int base) const
{
number = strToNumericBase<int> (*this, base);
}
void SS::toInteger (unsigned int & number, int base) const
{
number = strToNumericBase<unsigned int> (*this, base);
}
void SS::toInteger (long & number, int base) const
{
number = strToNumericBase<long> (*this, base);
}
void SS::toInteger (unsigned long & number, int base) const
{
number = strToNumericBase<unsigned long> (*this, base);
}
void SS::toInteger (LongLong & number, int base) const
{
number = strToNumericBase<LongLong> (*this, base);
}
void SS::toInteger (ULongLong & number, int base) const
{
number = strToNumericBase<ULongLong> (*this, base);
}
template <class T>
static inline SS toBaseImpl (T number, int base)
{
if (base<2 || base>36) ErrorMacro(SS::ErrorNumberFormat((SS)"toBase - base of " + base + " is invalid"));
bool is_signed = false;
if (number < 0) {
is_signed = true;
number = -number;
}
std::vector<T> digits;
T rem = number;
while (rem >= base) {
T p = rem/base;
T q = rem - p*base;
rem = p;
digits.insert (digits.begin(), q);
}
digits.insert (digits.begin(), rem);
SS ret (SS::Buffer(digits.size()));
char* digit_array = "0123456789abcdefghijklmnopqrstuvwxyz";
{for (int i=0; i<ret.size(); i++) {
ret[i] = digit_array [digits[i]];
}}
if (is_signed) return ret = '-' + ret;
return ret;
}
SS SS::toBase (short number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (unsigned short number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (int number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (unsigned int number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (long number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (unsigned long number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (LongLong number, int base)
{
return toBaseImpl (number, base);
}
SS SS::toBase (ULongLong number, int base)
{
return toBaseImpl (number, base);
}
bool SS::verify (int ind) const
{
try {
ind = translateIndex(ind);
} catch (ErrorBadArg error) {
return false;
}
return ind>=0 && ind<_len;
}
bool SS::verify (int beg, int len) const
{
bool ret = verify(beg);
if (len != fullength) {
if (len>0) {
ret = ret && verify(beg+len-1);
} else {
ret = false;
}
}
return ret;
}
bool SS::verify3 (SS const & s, int pos, int beg, int len) const
{
return pos>=0 && pos<_len && beg>=0 && beg<s._len && len>0 && pos+len<=_len && beg+len<=s._len;
}
int SS::translateIndex (int ind) const
{
if (ind == fullength || ind == notfound || ind == allitems) {
ErrorMacro(ErrorBadArg((SS)"SS::translateIndex - an index parameter cannot take the value "+ind));
}
return ind == maxindex ? _len-1 : ind;
}
int SS::translateLength (int len) const
{
if (len == maxindex || len == notfound || len == allitems) {
ErrorMacro(ErrorBadArg((SS)"SS::translateLength - a length parameter cannot take the value "+len));
}
return len == fullength ? _len : len;
}
int SS::translateCheck (int ind) const
{
ind = translateIndex (ind);
check (ind);
return ind;
}
void SS::check (int ind) const
{
if (ind < 0 || ind >= _len) {
SS err = (SS)"Index of " + ind + " in \"" + makeHeadSample() + "\" is ";
if (ind < 0) {
err += "less than zero";
} else {
err += "greater than the maximum of ";
err += _len-1;
}
ErrorMacro (ErrorOutOfRange(err));
}
}
bool SS::findCheck (int beg, int end, int inc) const
{
if (beg == notfound || end == notfound || inc == 0) return false;
if (beg == maxindex) beg = _len-1;
if (end == maxindex) end = _len-1;
if (inc>0) {
if (end == fullength) end = _len-1;
if (beg >= _len || end < 0 || end < beg) return false;
} else {
if (end == fullength) end = 0;
if (end >= _len || beg < 0 || end > beg) return false;
}
return true;
}
void SS::adjust (int& ind) const
{
ind = translateIndex (ind);
if (ind < 0 ) ind = 0;
if (ind > _len - 1 ) ind = _len - 1;
}
void SS::lenAdjust (int& len) const
{
len = translateLength (len);
if (len > _len) len = _len;
if (len < 0) len = 0;
}
void SS::pasteAdjust (int& ind) const
{
if (ind==maxindex) ind = _len -1;
ind = translateLength (ind);
if (ind > _len) ind = _len;
if (ind < 0) ind = 0;
}
void SS::modAdjust (int& beg, int& end, int inc) const
{
if (end == fullength) end = inc>0?_len-1:0;
beg = translateIndex (beg);
end = translateIndex (end);
int abeg = beg > 0 ? beg : -beg;
int aend = end > 0 ? end : -end;
int ainc = inc > 0 ? inc : -inc;
if (beg < 0) beg += ((abeg - 1 )/ainc+1)*ainc;
if (beg > _len -1 ) beg -= ((abeg - _len)/ainc+1)*ainc;
if (end < 0) end += ((aend - 1 )/ainc+1)*ainc;
if (end > _len -1 ) end -= ((aend - _len)/ainc+1)*ainc;
}
bool SS::matchAdjust (int& beg) const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -