📄 superstr.cpp
字号:
#include "stdafx.h"
#include "SuperStr.h"
#ifndef SS_STANDALONE
#include "Urror.hh"
#include "Associate.hh"
#endif
#include <locale>
#include <cstdarg>
#include <cfloat>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <strstream>
#include <limits>
// Super String implementation
// written by Phil Haubert and released into the public domain.
#ifndef SS_STANDALONE
#define ErrorMacro(error) UrrorMacro(error)
#else
#define ErrorMacro(error) throw error
#endif
static SS* null_string = 0;
SS& SS::nullref = *null_string;
const char SS::nullchar = 0;
const Pair<int> SS::nomatch (SS::notfound, SS::notfound);
char const * SS::formatStringLongLong = "%I64d";
char const * SS::formatStringULongLong = "%I64u";
const SS::FindFunc SS::whitespace (whiteP);
const SS::FindFunc SS::blackspace (blackP);
const SS::FindFunc SS::lowercase (lowerP);
const SS::FindFunc SS::uppercase (upperP);
const SS::FindFunc SS::alpha (alphaP);
const SS::FindFunc SS::digit (digitP);
const SS::FindFunc SS::alphanumeric (alphanumP);
const SS::FindFunc SS::punct (punctP);
const SS::FindFunc SS::printable (printableP);
const SS::FindFunc SS::hexdigit (hexDigitP);
const SS::FindFunc SS::cntrl (cntrlP);
const SS::FindFunc SS::graph (graphP);
const SS::FindBool SS::findtrue (true);
const SS::FindBool SS::findfalse (false);
const SS::FindBool SS::anychar (true, 1);
const SS::FindPosition SS::frontposition (0);
const SS::FindPosition SS::backposition (maxindex);
const SS::FindOr SS::endofline (FindSequence(anychar,FindString("\015\012")),FindSequence(anychar,FindChar('\012')),FindSequence(anychar,FindString("\012\015")),FindSequence(anychar,FindChar('\015')),backposition);
const SS::FindDelimit SS::singlequotedelimit('\'');
const SS::FindDelimit SS::doublequotedelimit('"');
const SS::FindDelimit SS::parendelimit('(',')');
SS::SS () { _zero(); assign (""); }
SS::SS (SS const & s) { _zero(); assign (s); }
SS::SS (void const * v, int n) { _zero(); assign (v,n); }
SS::SS (DoNothing) { _zero(); }
SS::Buffer::Buffer (void const * start, int n) : _isAlloc (false), _start(start), _n(n), _fillValue(0)
{
}
SS::Buffer::Buffer (int n, SS const & fillvalue) : _isAlloc (true), _start(0), _n(n), _fillValue(new SS(fillvalue))
{
}
SS::Buffer::Buffer (Buffer const & b)
{
copy (b);
}
SS::Buffer& SS::Buffer::operator = (Buffer const & b)
{
delete _fillValue;
copy (b);
return *this;
}
void SS::Buffer::copy (Buffer const & b)
{
_n = b._n;
_start = b._start;
_fillValue = new SS (*b._fillValue);
_isAlloc = b._isAlloc;
}
SS::Buffer::~Buffer ()
{
delete _fillValue;
}
void const * SS::Buffer::getStart () const
{
return _start;
}
int SS::Buffer::getSize () const
{
return _n;
}
SS SS::Buffer::getFillValue () const
{
return _fillValue ? SS(*_fillValue) : SS("");
}
bool SS::Buffer::getAlloc () const
{
return _isAlloc;
}
SS::~SS ()
{
destroy();
}
void SS::destroy()
{
if (isAlloc()) delete [] _rep;
}
SS SS::clone () const
{
return get (0, _len);
}
SS& SS::erase ()
{
_leng (0);
return *this;
}
SS& SS::buffer (int n)
{
_leng (n);
return *this;
}
SS& SS::resize (int n) {
int len = length();
if (n <= len) {
// shrinking requires no copying
zero (n, fullength);
_len = n;
} else {
// growing copies and zero fills
checkFlags();
char* ex = extract();
bool alloc_ex = isAlloc();
buffer (n);
copy (_rep, ex, len);
if (alloc_ex) delete [] ex;
zero (len, fullength);
_null();
checkFlags();
}
return *this;
}
SS& SS::buffer (void const * v, int n)
{
destroy();
_zero();
_rep = reinterpret_cast<char*>(const_cast<void*>(v));
_len = n;
setNoAlloc();
setNoRef();
checkFlags();
return *this;
}
SS& SS::resizeToNullTerminator ()
{
int pos = findNext (nullchar);
if (pos != notfound) resize(pos);
return *this;
}
char & SS::firstChar ()
{
return at (0);
}
char const & SS::firstChar () const
{
return at (0);
}
char & SS::lastChar ()
{
return at (_len-1);
}
char const & SS::lastChar () const
{
return at (_len-1);
}
SS SS::makeHeadSample () const
{
SS ret = head (HeadSample);
if (ret.length() != length()) ret += "...";
return ret;
}
SS SS::head (int len) const
{
return get (0, len);
}
SS SS::tail (int len) const
{
lenAdjust (len);
return get (_len - len, len);
}
SS SS::get (int beg, int len) const
{
adjust (beg, len);
SS ret ((Buffer)len);
copy (ret, _rep+beg, len);
return ret;
}
SS SS::get (Pair<int> const & beglen) const
{
return get (beglen._0, beglen._1);
}
SS SS::get (std::vector< Pair<int> > const & beglen) const
{
int n = 0;
std::vector< Pair<int> > v (beglen);
{for (int i=0; i<v.size(); i++) {
adjust (v[i]._0, v[i]._1);
n += v[i]._1;
}}
SS ret ((Buffer)n);
n = 0;
{for (int i=0; i<v.size(); i++) {
ret.set (*this, n, v[i]);
n += v[i]._1;
}}
return ret;
}
std::vector<SS>& SS::get (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] = get (beglen[i]);
}}
return s;
}
SS SS::getFrom (int beg) const
{
adjust (beg);
return get (beg, _len-beg);
}
SS& SS::reverse (int beg, int len)
{
adjust (beg, len);
{for (int i=0; i<len/2; i++) {
swap (beg+i, beg+len-i-1);
}}
return *this;
}
SS& SS::reverse (Pair<int> const & beglen)
{
return reverse (beglen._0, beglen._1);
}
SS& SS::reverse (std::vector< Pair<int> > const & beglen)
{
{for (int i=0; i<beglen.size(); i++) {
reverse (beglen[i]);
}}
return *this;
}
SS& SS::itemReverse (std::vector< Pair<int> > const & beglen)
{
std::vector<SS> s;
get (s, beglen);
std::reverse (s.begin(), s.end());
replaceRange (s, beglen);
return *this;
}
SS& SS::tailReverse (int len)
{
lenAdjust (len);
return reverse (_len-len, len);
}
SS& SS::sort (int beg, int len)
{
adjust (beg, len);
std::sort (_rep+beg, _rep+beg+len);
return *this;
}
SS& SS::sort (Pair<int> const & beglen)
{
return sort (beglen._0, beglen._1);
}
SS& SS::sort (std::vector< Pair<int> > const & beglen)
{
{for (int i=0; i<beglen.size(); i++) {
sort (beglen[i]);
}}
return *this;
}
SS& SS::itemSort (std::vector< Pair<int> > const & beglen)
{
std::vector<SS> s;
get (s, beglen);
std::sort (s.begin(), s.end());
replaceRange (s, beglen);
return *this;
}
SS& SS::tailSort (int len)
{
lenAdjust (len);
return sort (_len-len, len);
}
SS& SS::set (SS const & s, int pos, int beg, int len)
{
if (adjust3 (s, pos, beg, len)) {
copy (_rep+pos, s._rep+beg, len);
}
return *this;
}
SS& SS::set (SS const & s, int pos)
{
return set (s, pos, 0, s._len);
}
SS& SS::set (SS const & s, int pos, Pair<int> const & beglen)
{
return set (s, pos, beglen._0, beglen._1);
}
SS& SS::set (SS const & s, std::vector<int> const & pos)
{
{for (int i=0; i<pos.size(); i++) {
set (s, pos[i]);
}}
return *this;
}
SS& SS::set (std::vector<SS> const & s, std::vector<int> const & pos)
{
{for (int i=0; i<pos.size(); i++) {
if (!s.empty()) set (s[i%s.size()], pos[i]);
}}
return *this;
}
static inline int chooseSSVectElement (std::vector<SS> const & s, int i)
{
if (i>=s.size()) return i%s.size();
return i;
}
// channel the various multiple operations that resize into common code
// don't even try with the pointers to overloaded members
#define resizeOpHelper_a_SS(ss,v,s,f,x) \
{for (int i=v.size()-1; i>=0; i--) ss->f(s,v[i]); }
#define resizeOpHelper_a_VectSS(ss,v,s,f,x) \
if (s.size()==0) { \
SS ns; \
{for (int i=v.size()-1; i>=0; i--) ss->f(ns,v[i]); } \
} else { \
{for (int i=v.size()-1; i>=0; i--) ss->f(s[chooseSSVectElement(s,i)],v[i]); }}
#define resizeOpHelper_a_ReplSS(ss,v,s,f,x) \
{for (int i=v.size()-1; i>=0; i--) ss->f(x,s,v[i]); }
#define resizeOpHelper_b_SS(ss,v,s,f,x) \
std::vector<int> o; SS::sortBegLenVect(v,o); \
{for (int i=v.size()-1; i>=0; i--) ss->f(s,v[o[i]]); }
#define resizeOpHelper_b_VectSS(ss,v,s,f,x) \
std::vector<int> o; SS::sortBegLenVect(v,o); \
if (s.size()==0) { \
SS ns; \
{for (int i=v.size()-1; i>=0; i--) ss->f(ns,v[o[i]]); } \
} else { \
{for (int i=v.size()-1; i>=0; i--) ss->f(s[chooseSSVectElement(s,o[i])],v[o[i]]); }}
#define resizeOpHelper_b_ReplSS(ss,v,s,f,x) \
std::vector<int> o; SS::sortBegLenVect(v,o); \
{for (int i=v.size()-1; i>=0; i--) ss->f(x,s,v[o[i]]); }
#define resizeOpHelper(ss,vect,s,f,a,vtype,stype,x) \
std::vector< vtype > v = vect; \
{for (int i=0; i<v.size(); i++) a(v[i]); } \
if (SS::alreadySorted (v)) { resizeOpHelper_a_##stype(ss,v,s,f,x); } \
else { resizeOpHelper_b_##stype(ss,v,s,f,x); }
SS& SS::cut (SS& s, int beg, int len)
{
adjust (beg, len);
s = get (beg, len);
if (beg==0) {
if (len==_len) {
*this = "";
} else {
*this = getRegion (len,_len-len);
}
} else {
if (len==_len) {
*this = getRegion (0, beg);
} else {
*this = getRegion (0, beg) + getRegion (beg+len,_len-len-beg);
}
}
return s;
}
SS& SS::cut (SS& s, Pair<int> const & beglen)
{
return cut (s, beglen._0, beglen._1);
}
SS SS::cut (int beg, int len)
{
SS ret;
return cut (ret, beg, len);
}
SS SS::cut (Pair<int> const & beglen)
{
return cut (beglen._0, beglen._1);
}
std::vector<SS>& SS::cut (std::vector<SS>& s, std::vector< Pair<int> > const & beglen)
{
s = std::vector<SS>(beglen.size());
resizeOpHelper(this,beglen,s,cut,adjust,Pair<int>,VectSS,0);
return s;
}
SS SS::cutFrom (int beg)
{
adjust (beg);
return cut (beg, _len-beg);
}
SS& SS::paste (SS const & s, int pos, int beg, int len)
{
pasteAdjust (pos);
s.adjust (beg, len);
if (pos==0) {
if (beg==0 && len==s._len) {
*this = s + *this;
} else {
*this = s.getRegion (beg,len) + *this;
}
} else if (pos==_len) {
if (beg==0 && len==s._len) {
*this = *this + s;
} else {
*this = *this + s.getRegion (beg,len);
}
} else {
if (beg==0 && len==s._len) {
*this = getRegion (0,pos) + s + getRegion (pos,_len-pos);
} else {
*this = getRegion (0,pos) + s.getRegion (beg,len) + getRegion (pos,_len-pos);
}
}
return *this;
}
SS& SS::paste (SS const & s, int pos)
{
return paste (s, pos, 0, s._len);
}
SS& SS::paste (SS const & s, int pos, Pair<int> const & beglen)
{
return paste (s, pos, beglen._0, beglen._1);
}
SS& SS::paste (SS const & s, std::vector<int> const & pos)
{
resizeOpHelper(this,pos,s,paste,pasteAdjust,int,SS,0);
return *this;
}
SS& SS::paste (std::vector<SS> const & s, std::vector<int> const & pos)
{
resizeOpHelper(this,pos,s,paste,pasteAdjust,int,VectSS,0);
return *this;
}
SS& SS::fill (char c, int beg, int len)
{
adjust (beg, len);
fill (_rep+beg, c, len);
return *this;
}
SS& SS::fill (char c, Pair<int> const & beglen)
{
return fill (c, beglen._0, beglen._1);
}
SS& SS::fill (char c, std::vector< Pair<int> > const & beglen)
{
{for (int i=0; i<beglen.size(); i++) {
fill (c, beglen[i]);
}}
return *this;
}
SS& SS::repeat (SS const & s, int beg, int len)
{
int beg0 = translateIndex(beg);
adjust (beg, len);
if (s._len == 1) {
fill (_rep+beg, s[0], len);
} else {
int fillsize = s._len;
// shift pattern to accommodate out of range beg
int begchars = (beg0-beg) % fillsize;
if (begchars<0) begchars += fillsize;
int begchars_start = fillsize-begchars;
if (begchars>len) begchars = len;
len -= begchars;
int nunits = len/fillsize;
int endchars = len - nunits*fillsize;
if (begchars) {
set (s, beg, begchars_start, begchars);
}
beg += begchars;
{for (int i=0; i<nunits; i++) {
set (s, beg + i*fillsize);
}}
if (endchars) {
set (s, beg + nunits*fillsize, 0, endchars);
}
}
return *this;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -