📄 superstr.cpp
字号:
{
try {
beg = translateIndex (beg);
} catch (ErrorBadArg error) {
return false;
}
if (beg >= _len) return false;
if (beg < 0) return false;
return true;
}
// b<0 l<0 -> 0,0 * b+l<0
// b<0 l>0 b+l<0 -> 0,0 *
// b<0 l>0 b+l>0 -> 0,b+l
// b>0 l<0 b+l<0 -> 0,b
// b>0 l<0 b+l>0 -> b+l,-l
// b>0 l>0 -> b,l
// b>n l<0 b+l>n -> n-1,0 * b+l>n
// b<n l>0 b+l>n -> b,n-b
// b>n l<0 b+l<n -> b+l,n-b-l
// b>n l>0 -> n-1,0 *
void SS::adjust (int& beg, int& len) const
{
beg = translateIndex (beg);
if (beg<0 && len==fullength) beg=0;
len = translateLength (len);
int end = beg + len;
if (len<0) {
// end = beg+1; // char counting pov
end = beg; // metrics pov
beg = end+len;
}
if (beg>=_len) {
beg = _len-1;
end = beg;
}
if (beg<0) beg = 0;
if (end<0) end = 0;
if (end>_len) end = _len;
len = end - beg;
}
void SS::adjust (Pair<int>& beglen) const
{
adjust (beglen._0, beglen._1);
}
// p
// ##########
// **|******|*
// b b+l
// p
// ##########
// **|******|*
// b+l b
bool SS::adjust3 (SS const & s, int& p, int& b, int& l) const
{
p = translateIndex (p);
b = s.translateIndex (b);
l = s.translateLength (l);
if (!verify3 (s,p,b,l)) {
// switch mark and point for negative length
if (l<0) {
p += l;
b += l;
l = -l;
}
// normalize with respect to target string
int p1 = p;
lenAdjust(p1);
int d_p1_p = p1 - p;
int b1 = b + d_p1_p;
int l1 = l - d_p1_p;
// normalize with respect to source string
b = b1;
s.lenAdjust (b);
int d_b_b1 = b - b1;
p = p1 + d_b_b1;
l = l1 - d_b_b1;
// truncate len with respect to both strings
if (p+l>_len) l = _len-p;
if (b+l>s._len) l = s._len-b;
// if results invalid assume no overlap
if (!verify3 (s,p,b,l)) return false;
}
return true;
}
void SS::_leng (int n)
{
destroy();
_rep = new char [n+1];
_len = n;
_allocLength = _len;
_null();
setAlloc();
setNoRef();
}
void SS::_data (void const * s)
{
copy (_rep, s, _len);
}
void SS::_data (string const & s)
{
for (int i=0; i<_len; i++) {
_rep[i] = s[i];
}
}
void SS::_data (std::vector<char> const & v)
{
for (int i=0; i<_len; i++) _rep[i] = v[i];
}
void SS::assign (SS const & s)
{
if (&s != this) {
// a ref copies to a ref
if (s.isRef()) {
s.checkFlags();
_setData (s);
} else {
_leng (s._len);
_data (s._rep);
}
}
}
void SS::assign (Buffer const & v)
{
if (v.getAlloc()) {
buffer (v.getSize());
SS fill_value = v.getFillValue();
if (!fill_value.empty()) {
repeat (fill_value);
}
} else {
buffer (v.getStart(), v.getSize());
}
}
// make a copy of char* if memory region about to be deleted
void SS::assign (char const * s)
{
if (isAlloc() && addressInside (s)) {
assign (SS(s));
} else {
_leng (strLen(s));
_data(s);
}
}
void SS::assign (unsigned char const * s)
{
if (isAlloc() && addressInside (s)) {
assign (SS(s));
} else {
_leng (strLen(s));
_data(s);
}
}
void SS::assign (signed char const * s)
{
if (isAlloc() && addressInside (s)) {
assign (SS(s));
} else {
_leng (strLen(s));
_data(s);
}
}
void SS::assign (void const * v, int n)
{
if (isAlloc() && addressInside (v)) {
assign (SS(v,n));
} else {
_leng (n);
_data(v);
}
}
// template <class T> static inline SS format_using_strstream (T t)
// {
// std::strstream os;
// os << t;
// return SS(os.str(),os.pcount());
// }
void SS::assign (char v) { _leng (1); _rep[0] = v; }
void SS::assign (unsigned char v) { _leng (1); _rep[0] = static_cast<char>(v); }
void SS::assign (signed char v) { _leng (1); _rep[0] = static_cast<char>(v); }
void SS::assign (bool v) { assign (v ? "true" : "false"); }
void SS::assign (short v) { assign (sprint ("%d",v)); }
void SS::assign (unsigned short v) { assign (sprint ("%u",v)); }
void SS::assign (int v) { assign (sprint ("%d",v)); }
void SS::assign (unsigned int v) { assign (sprint ("%u",v)); }
void SS::assign (long v) { assign (sprint ("%ld",v)); }
void SS::assign (unsigned long v) { assign (sprint ("%lu",v)); }
void SS::assign (LongLong v) { assign (sprint (formatStringLongLong,v)); }
void SS::assign (ULongLong v) { assign (sprint (formatStringULongLong,v)); }
void SS::assign (float v) { assign (sprint ("%g",v)); }
void SS::assign (double v) { assign (sprint ("%.20g",v)); }
// long double treated as double here
void SS::assign (long double v) { assign (sprint ("%.20g",v)); }
void SS::assign (std::vector<char> const & v) { _leng (v.size()); _data(v); }
void SS::assign (string const & s) { _leng (s.length()); _data (s); }
void SS::_setData (char * rep, int len, int flags, int allocLength)
{
_rep = rep;
_len = len;
_flags = flags;
_allocLength = allocLength;
}
void SS::_setData (SS const & s)
{
_setData (s._rep, s._len, s._flags, s._allocLength);
}
void SS::_zero ()
{
_setData (0, 0, 0, 0);
}
void SS::_null ()
{
_rep [_len] = nullchar;
}
bool SS::isAlloc () const
{
return (_flags & Alloc) == 0;
}
void SS::setAlloc ()
{
_flags &= ~Alloc;
}
void SS::setNoAlloc ()
{
_flags |= Alloc;
}
bool SS::isRef () const
{
return (_flags & Ref) != 0;
}
void SS::setRef ()
{
_flags |= Ref;
}
void SS::setNoRef ()
{
_flags &= ~Ref;
}
// the flags are not exposed; calling this <should> be redundant
void SS::checkFlags () const
{
if (isAlloc() && isRef()) {
ErrorMacro(ErrorBadState((SS)"checkFlags - alloc="+isAlloc()+" ref="+isRef()+" are inconsistent"));
}
}
// the problem here is that SS const &'s are judged ambiguous
SS SS::operator + (SS s) { return concatenate (*this,s); }
SS SS::operator + (SS s) const { return concatenate (*this,s); }
bool SS::operator == (SS s) { return compare (s) == 0; }
bool SS::operator == (SS s) const { return compare (s) == 0; }
bool SS::operator != (SS s) { return compare (s) != 0; }
bool SS::operator != (SS s) const { return compare (s) != 0; }
bool SS::operator < (SS s) { return compare (s) < 0; }
bool SS::operator < (SS s) const { return compare (s) < 0; }
bool SS::operator > (SS s) { return compare (s) > 0; }
bool SS::operator > (SS s) const { return compare (s) > 0; }
bool SS::operator <= (SS s) { return compare (s) <= 0; }
bool SS::operator <= (SS s) const { return compare (s) <= 0; }
bool SS::operator >= (SS s) { return compare (s) >= 0; }
bool SS::operator >= (SS s) const { return compare (s) >= 0; }
bool SS::addressInside (void const * p) const
{
bool ret = false;
if (p) {
char const * q = reinterpret_cast<char const *>(p);
char const * beg = _rep;
char const * end = isAlloc() ? beg + _allocLength : beg + _len - 1;
if (q >= beg && q <=end) ret = true;
}
return ret;
}
int alreadySortedHelperValue (int v) { return v; }
int alreadySortedHelperValue (Pair<int> v) { return v._0; }
// assumes indices adjusted before this
template <class T>
static inline bool alreadySortedHelper (std::vector<T> const & v)
{
if (v.empty()) return true;
int beg = -1;
{for (int i=0; i<v.size(); i++) {
int x = alreadySortedHelperValue(v[i]);
if (x < beg) return false;
beg = x;
}}
return true;
}
bool SS::alreadySorted (std::vector<int> const & v)
{
return alreadySortedHelper (v);
}
bool SS::alreadySorted (std::vector< Pair<int> > const & v)
{
return alreadySortedHelper (v);
}
struct SortBegLenVectPairHelper {
bool operator () (Pair<int> const & x, Pair<int> const & y) { return x._0 < y._0; }
};
static inline int sortBegLenVectElement (int e) { return e; }
static inline int sortBegLenVectElement (Pair<int> e) { return e._0; }
template <class T>
static inline void sortBegLenVectHelper (std::vector<T> const & v, std::vector<int> & o)
{
std::vector< Pair<int> > sv (v.size());
{for (int i=0; i<sv.size(); i++) {
sv[i] = Pair<int> (sortBegLenVectElement(v[i]),i);
}}
std::sort (sv.begin(), sv.end(), SortBegLenVectPairHelper());
o = std::vector<int> (v.size());
{for (int i=0; i<o.size(); i++) {
o[i] = sv[i]._1;
}}
}
void SS::sortBegLenVect (std::vector<int> const & v, std::vector<int> & o)
{
sortBegLenVectHelper (v, o);
}
void SS::sortBegLenVect (std::vector< Pair<int> > const & v, std::vector<int> & o)
{
sortBegLenVectHelper (v, o);
}
SS SS::sprint (const char * fmt, ...)
{
va_list args;
va_start(args, fmt);
SS ret;
int const BUFFSIZE [] = {1024, 64*1024, 1024*1024, 16*1024*1024};
int nbuff = sizeof(BUFFSIZE)/sizeof(BUFFSIZE[0]);
// const int BUFFSIZE=1024;
char smallbuff[1024+1];
char* allocbuff [] = {smallbuff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int res = -1;
{for (int i=0; res==-1 && i<nbuff; i++) {
int len = BUFFSIZE[i];
char* buff = allocbuff[i] ? allocbuff[i] : new char[len+1];
res = _vsnprintf (buff, len, fmt, args);
if (res != -1) { // succeeded
buff[res] = nullchar;
ret = buff;
}
if (!allocbuff[i]) delete [] buff;
}}
va_end(args);
if (res == -1) ErrorMacro(ErrorOverflow("SS::sprint - buffer overflow"));
return ret;
}
SS::SubSS::SubSS (SS* s, int beg, int len) : _rep(s), _beg(beg), _len(len) { }
//SS::SubSS::operator SS () const
//{
// return _rep->get (_beg, _len);
//}
SS SS::SubSS::get () const
{
return _rep->get (_beg, _len);
}
SS& SS::SubSS::operator = (SS s)
{
if (!_rep->isAlloc() && _len == s.length()) {
_rep->set (s, _beg);
} else {
_rep->cut (_beg, _len);
_rep->paste (s, _beg);
}
return *_rep;
}
SS::SubSS SS::sub (int beg, int len)
{
adjust (beg, len);
return SubSS (this, beg, len);
}
SS SS::sub (int beg, int len) const
{
adjust (beg, len);
return get (beg, len);
}
SS::SubSS SS::operator () (int beg, int len)
{
return sub (beg, len);
}
SS SS::operator () (int beg, int len) const
{
return sub (beg, len);
}
SS::SubSS SS::operator () (Pair<int> const & beglen)
{
return sub (beglen._0, beglen._1);
}
SS SS::operator () (Pair<int> const & beglen) const
{
return sub (beglen._0, beglen._1);
}
SS SS::getRegion (int beg, int len) const
{
adjust (beg, len);
SS ret (Buffer (_rep+beg, len));
ret.setRef();
return ret;
}
SS SS::getRegion (Pair<int> const & beglen) const
{
return getRegion (beglen._0, beglen._1);
}
std::vector<SS>& SS::getRegion (std::vector<SS>& s, std::vector< Pair<int> > const & beglen) const
{
s = std::vector<SS> (beglen.size());
{for (int i=0; i<s.size(); i++) {
s[i] = getRegion (beglen[i]);
}}
return s;
}
std::vector< Pair<int> >& SS::tokenize (std::vector< Pair<int> >& beglen) const
{
return tokenize (SS::whitespace, beglen);
}
std::vector< Pair<int> >& SS::tokenize (SS const & delimiter, std::vector< Pair<int> >& beglen) const
{
return tokenize (FindString (delimiter), beglen);
}
std::vector< Pair<int> >& SS::tokenize (Find const & finder, std::vector< Pair<int> >& beglen) const
{
beglen.clear();
int pos=0;
int end=_len;
int begpos=pos;
SS result;
bool in_token = false;
while (pos < end) {
if (match (finder, pos, result)) {
if (in_token) {
beglen.back()._1 = pos - begpos;
in_token = false;
}
pos += result._len;
} else {
if (!in_token) {
beglen.insert (beglen.end());
beglen.back()._0 = pos;
in_token = true;
begpos = pos;
}
pos++;
if (pos == end) {
beglen.back()._1 = pos - begpos;
}
}
}
return beglen;
}
SS::SSCopyPointer::SSCopyPointer (SS const & s)
{
_rep = new SS(s);
}
SS::SSCopyPointer::SSCopyPointer (SSCopyPointer const & p)
{
_rep = new SS(*p._rep);
}
SS * SS::SSCopyPointer::operator -> ()
{
return _rep;
}
SS const * SS::SSCopyPointer::operator -> () const
{
return _rep;
}
SS & SS::SSCopyPointer::operator * ()
{
return *_rep;
}
SS const & SS::SSCopyPointer::operator * () const
{
return *_rep;
}
SS::SSCopyPointer::operator = (SSCopyPointer const & p)
{
delete _rep;
_rep = new SS(*p._rep);
}
SS::SSCopyPointer::~SSCopyPointer ()
{
delete _rep;
}
SS::Find::Find () : _rep (0)
{
}
SS::Find::Find (Find const & f)
{
_rep = f.clone();
}
SS::Find& SS::Find::operator = (Find const & f)
{
delete _rep;
_rep = f.clone();
retu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -