结尾有代码
因为是引用计数(References counting),所以我起名为RCstring
首先是要包含的头文件
#include <string>
#include <unordered_map>
unordered_map能以O(1)的时间复杂度查找,插入,删除,用来保存所有字符串对象最合适
要用一个哈希表用来存放我门的数据,要先确认一下key和value是什么
先说一下我踩的坑,原本我用的是char*,但千不该万不该忘了char*和char*比较是比的地址
导致每次在哈希表中查询都找不到对应的value
被自己的愚蠢击败...
其实也可以重载一下,改变它的比较方式,但实在没有必要
最简单的办法就是key设置成std::string
为了方便管理这些资源,需要一个类保护这些数据
class RCstringValue
{
void copy_str(const char* rhs);
public:
char* value;
int realsize;
int count;
RCstringValue();
RCstringValue(RCstringValue* rhs);
~RCstringValue();
friend RCstring;
};
value就是保存的字符串
realsize用于保存value的真实长度
count用于保存指向这个指针的数量
copy_str是一个私有函数,用来复制rhs的数据
void RCstring::RCstringValue::copy_str(const char* rhs)
{
realsize = strlen(rhs);
value = new char[realsize] {};
for (int i = 0; i < realsize; ++i)
{
value[i] = rhs[i];
}
count = 1;
}
RCstring::RCstringValue::RCstringValue()
:value(nullptr), realsize(0), count(0)
{
}
RCstring::RCstringValue::RCstringValue(RCstringValue* rhs)
{
copy_str(rhs->value);
}
RCstring::RCstringValue::~RCstringValue()
{
delete[]value;
value = nullptr;
}
不要疑惑为什么析构函数直接清理,因为我们不使用普通变量,而是使用指针
真正的析构放在RCstring的析构函数里
RCstringValue* value;
bool locked;
int Size;
void copy();
void point_to(const RCstring& rcstr);
static std::unordered_map<std::string, RCstringValue*> hash;
私有成员
Size表示使用的大小,而realsize表示的是真实大小,是不一样的
copy用来复制自身
point_to用来指向另一个对象
hash就是储存所有RCstringValue的地址
用value中的value可以得到对应的key,相同的值使用相同的key,从而指向一个对象
//无参
RCstring::RCstring()
:value(nullptr), locked(false), Size(0)
{
}
//确认长度的构造函数
RCstring::RCstring(int length)
:locked(false)
{
value = new RCstringValue();
value->value = new char[length];
value->count = 1;
value->realsize = length;
Size = 0;
}
RCstring::RCstring(const char* rhs)
:locked(false)
{
auto iter = hash.find(rhs);
//如果在hash里找到rhs对应的value
if (iter != hash.end())
{
//指向
value = iter->second;
Size = value->realsize;
//增加计数器
++value->count;
}
else
{
//新建对象
value = new RCstringValue();
value->copy_str(rhs);
Size = value->realsize;
hash.insert(std::pair<std::string, RCstringValue*>(rhs, value));
}
}
RCstring::RCstring(const std::string& rhs)
:RCstring(rhs.data())
{
}
RCstring::RCstring(const RCstring& rhs)
:locked(false)
{
if (rhs.locked)
{
value = new RCstringValue();
value->copy_str(rhs.value->value);
Size = value->realsize;
hash.insert(std::pair<std::string, RCstringValue*>(rhs.value->value, value));
}
else
{
value = rhs.value;
Size = rhs.value->realsize;
++value->count;
}
}
locked用来表达是否有指针指向它
如果没有,locked为false,可以正常用指向它的值
如果有,locked为true,表达它有可能被修改,新建一份对象
当然凭借我的实力是做不出每时每刻跟随的效果的,但是只要手动处理一下就可以,非常简单
void RCstring::copy()
{
value = new RCstringValue(value);
}
void RCstring::point_to(const RCstring& rcstr)
{
this->~RCstring();
value = rcstr.value;
++value->count;
}
RCstring::~RCstring()
{
--value->count;
if (value->count == 0)
{
hash.erase(value->value);
delete value;
value = nullptr;
}
}
接下来是两个很重要的函数
void RCstring::lock()
{
locked = true;
if (value->count > 1)
{
copy();
}
}
void RCstring::unlock()
{
if (!locked)
{
return;
}
auto iter = hash.find(value->value);
locked = false;
if (iter != hash.end())
{
delete value;
value = iter->second;
++value->count;
}
else
{
hash.insert(std::pair<std::string, RCstringValue*>(value->value, value));
}
}
lock判断一下当前指向value的数量,如果只有一个的话就什么也不做
否则就复制一次自身,从引用计数系统里移除
unlock判断一下value对应的value是否存在,如果存在则不需要这个value,释放后指向引用计数系统的value,而不存在则插入这个value,重新加入引用计数系统
这样就可以做到在频繁修改时先退出引用计数系统,而在修改完毕后再次加入的效果
目前来看需要手动lock的情况基本不存在,只需要手动unlock就可以了
char& RCstring::operator[](int index)
{
if (locked)
{
return value->value[index];
}
lock();
return value->value[index];
}
char RCstring::operator[](int index)const
{
return value->value[index];
}
char RCstring::operator()(int index)const
{
return value->value[index];
}
char RCstring::at(int index)const
{
if (index < 0 || index>Size)
{
std::abort();
}
return value->value[index];
}
这四个都是返回index的字符
第一个是修改的时候才需要使用的,如果没有手动lock就会自动lock
第二个是用于常量对象的,返回值不是引用,无法修改值
第三个是我用来方便非常量对象读取用的,不会修改值
第四个是std::string里也有的,它会判断一下下标是否非法
然后就可以实现各种成员函数了
RCstring RCstring::substr(int start, int length)const
{
RCstring rc(length);
rc.Size = length;
rc.lock();
for (int i = start; i < start + length; ++i)
{
rc[i - start] = value->value[i];
}
rc.unlock();
return rc;
}
一般来说rc是不需要手动lock的,但是用来提醒自己非常合适
其它的就很简单了
void RCstring::assign(int num, char ch)
{
RCstring rcstr(num);
rcstr.lock();
for (int i = 0; i < num; ++i)
{
rcstr[i] = ch;
}
rcstr.unlock();
Size = num;
point_to(rcstr);
}
void RCstring::append(const std::string& str)
{
if (Size + str.size() > value->realsize)
{
RCstring rcstr = Size + str.size();
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Size + str.size(); ++i)
{
rcstr[i] = str[i - Size];
}
rcstr.unlock();
Size = Size + str.size();
point_to(rcstr);
return;
}
lock();
for (int i = Size; i < Size + str.size(); ++i)
{
value->value[i] = str[i - Size];
}
unlock();
Size = Size + str.size();
}
void RCstring::erase(int start, int length)
{
RCstring rcstr(value->realsize - length);
rcstr.lock();
bool isturned = false;
for (int i = 0; i < value->realsize; ++i)
{
if (i == start)
{
i += length;
isturned = true;
}
if (i < value->realsize)
{
if (!isturned)
{
rcstr[i] = value->value[i];
}
else
{
rcstr[i - length] = value->value[i];
}
}
}
rcstr.unlock();
Size -= length;
point_to(rcstr);
}
void RCstring::resize(int Newsize, char ch)
{
if (Newsize < Size)
{
Size = Newsize;
return;
}
RCstring rcstr(Newsize);
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Newsize; ++i)
{
rcstr[i] = ch;
}
rcstr.unlock();
Size = Newsize;
point_to(rcstr);
}
void RCstring::reverse(int Newsize)
{
if (Newsize < Size)
{
return;
}
RCstring rcstr(Newsize);
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
rcstr.unlock();
point_to(rcstr);
}
void RCstring::insert(int Where, const char* ptr)
{
int length = strlen(ptr);
if (Size + length > value->realsize)
{
RCstring rcstr = Size + length;
rcstr.lock();
int n = 0;
for (int i = 0; i < Size + length; ++i)
{
if (i == Where)
{
int z = 0;
for (int u = i; u < i + length; ++u)
{
rcstr[u] = ptr[z];
++z;
}
n = length;
}
rcstr[i + n] = value->value[i];
}
rcstr.unlock();
Size += length;
point_to(rcstr);
return;
}
for (int right = Size + length - 1; right > Where; --right)
{
std::swap(value->value[right], value->value[right - 1]);
}
for (int i = Where; i < Where + length; ++i)
{
value->value[i] = ptr[i - Where];
}
Size += length;
}
const RCstring RCstring::operator+(const char* ptr)
{
int length = strlen(ptr);
RCstring str = length + Size;
str.lock();
for (int i = 0; i < Size; ++i)
{
str[i] = value->value[i];
}
for (int i = Size; i < Size + length; ++i)
{
str[i] = ptr[i - Size];
}
str.unlock();
str.Size = length + Size;
return str;
}
有一点要注意,这也是我踩过的坑,虽然写了参数为const char* 的函数,但是不能直接append(str.data()),因为如果这么做是把整个指针都复制过去,但我们使用的可能不是整个指针而是其中的一部分,这也是我为什么要把Size分发到各个RCstring里而不是加入引用计数系统
比如一个字符串 aabbccddee
有个RCstring的RCstringValue指向它
如果它想让它的Size变为2,只需要一个赋值就可以了,但是如果Size放在RCstringValue里就要新建一个对象,而它们的区别就是使用的大小不同而已
最后附上源码
#include <string>
#include<unordered_map>
class RCstring
{
class RCstringValue
{
void copy_str(const char* rhs);
public:
char* value;
int realsize;
int count;
RCstringValue();
RCstringValue(RCstringValue* rhs);
~RCstringValue();
friend RCstring;
};
class iterator
{
char* value;
public:
iterator(char* p);
iterator operator++();
iterator operator++(int);
iterator operator--();
iterator operator--(int);
iterator operator+(int val);
iterator operator-(int val);
char operator*();
bool operator==(iterator another);
bool operator!=(iterator another);
};
RCstringValue* value;
bool locked;
int Size;
void copy();
void point_to(const RCstring& rcstr);
static std::unordered_map<std::string, RCstringValue*> hash;
public:
RCstring();
RCstring(int length);
RCstring(const char* rhs);
RCstring(const std::string& rhs);
RCstring(const RCstring& rhs);
RCstring substr(int start, int length)const;
std::vector<RCstring> split(char p)const;
void assign(int num, char ch);
void assign(const char* ptr);
void assign(const RCstring& s);
void assign(const std::string& s);
void assign(iterator start, iterator end);
void append(const std::string& str);
void append(const RCstring& str);
void append(const char* ptr);
void append(iterator start, iterator end);
void erase(int off);
void erase(int start, int length);
void erase(iterator off);
void erase(iterator start, iterator end);
void resize(int NewSize, char Ch = 0);
void reverse(int Newsize);
void insert(int Where, char p);
void insert(int Where, const char* ptr);
void insert(int Where, const std::string& str);
void insert(int Where, const RCstring& str);
const RCstring operator+(const RCstring& rhs);
const RCstring operator+(const char* rhs);
const RCstring operator+(const std::string& rhs);
iterator begin()const;
iterator end()const;
iterator rbegin()const;
iterator rend()const;
const char* data()const;
int toint()const;
float tofloat()const;
std::string tostring()const;
void lock();
void unlock();
RCstring& operator=(const RCstring& rhs);
bool operator==(const RCstring& rhs);
bool operator!=(const RCstring& rhs);
char& operator[](int index);
char operator[](int index)const;
char operator()(int index)const;
char at(int index)const;
int size()const;
int max_size()const;
~RCstring();
};
std::unordered_map<std::string, RCstring::RCstringValue*> RCstring::hash;
void RCstring::RCstringValue::copy_str(const char* rhs)
{
realsize = strlen(rhs);
value = new char[realsize] {};
for (int i = 0; i < realsize; ++i)
{
value[i] = rhs[i];
}
count = 1;
}
RCstring::RCstringValue::RCstringValue()
:value(nullptr), realsize(0), count(0)
{
}
RCstring::RCstringValue::RCstringValue(RCstringValue* rhs)
{
copy_str(rhs->value);
}
RCstring::RCstringValue::~RCstringValue()
{
delete[]value;
value = nullptr;
}
RCstring::iterator::iterator(char* p)
{
value = p;
}
RCstring::iterator RCstring::iterator::operator++()
{
return ++value;
}
RCstring::iterator RCstring::iterator::operator++(int)
{
iterator iter = *this;
++value;
return iter;
}
RCstring::iterator RCstring::iterator::operator--()
{
return --value;
}
RCstring::iterator RCstring::iterator::operator--(int)
{
iterator iter = *this;
--value;
return iter;
}
RCstring::iterator RCstring::iterator::operator+(int val)
{
return value + val;
}
RCstring::iterator RCstring::iterator::operator-(int val)
{
return value - val;
}
char RCstring::iterator::operator*()
{
return *value;
}
bool RCstring::iterator::operator==(RCstring::iterator another)
{
return value == another.value;
}
bool RCstring::iterator::operator!=(RCstring::iterator another)
{
return value != another.value;
}
void RCstring::copy()
{
value = new RCstringValue(value);
}
void RCstring::point_to(const RCstring& rcstr)
{
this->~RCstring();
value = rcstr.value;
++value->count;
}
RCstring::RCstring()
:value(nullptr), locked(false), Size(0)
{
}
RCstring::RCstring(int length)
:locked(false)
{
value = new RCstringValue();
value->value = new char[length];
value->count = 1;
value->realsize = length;
Size = 0;
}
RCstring::RCstring(const char* rhs)
:locked(false)
{
auto iter = hash.find(rhs);
if (iter != hash.end())
{
value = iter->second;
Size = value->realsize;
++value->count;
}
else
{
value = new RCstringValue();
value->copy_str(rhs);
Size = value->realsize;
hash.insert(std::pair<std::string, RCstringValue*>(rhs, value));
}
}
RCstring::RCstring(const std::string& rhs)
:RCstring(rhs.data())
{
}
RCstring::RCstring(const RCstring& rhs)
:locked(false)
{
if (rhs.locked)
{
value = new RCstringValue();
value->copy_str(rhs.value->value);
Size = value->realsize;
hash.insert(std::pair<std::string, RCstringValue*>(rhs.value->value, value));
}
else
{
value = rhs.value;
Size = rhs.value->realsize;
++value->count;
}
}
RCstring RCstring::substr(int start, int length)const
{
RCstring rc(length);
rc.Size = length;
rc.lock();
for (int i = start; i < start + length; ++i)
{
rc[i - start] = value->value[i];
}
rc.unlock();
return rc;
}
std::vector<RCstring> RCstring::split(char p)const
{
std::vector<RCstring> v;
int slow = 0;
int n = size();
for (int fast = 0; fast < n; ++fast)
{
if (value->value[fast] == p)
{
if (fast != 0)
{
if (value->value[fast - 1] != p)
{
RCstring str = substr(slow, fast - slow);
++str.value->count;
v.push_back(str);
slow = fast + 1;
}
else
{
++slow;
}
}
else
{
++slow;
}
}
else if (fast == n - 1)
{
RCstring str = substr(slow, fast - slow);
++str.value->count;
v.push_back(str);
}
}
return v;
}
void RCstring::assign(int num, char ch)
{
RCstring rcstr(num);
rcstr.lock();
for (int i = 0; i < num; ++i)
{
rcstr[i] = ch;
}
rcstr.unlock();
Size = num;
point_to(rcstr);
}
void RCstring::assign(const char* ptr)
{
RCstring rcstr(strlen(ptr));
rcstr.lock();
rcstr.value->copy_str(ptr);
rcstr.unlock();
Size = rcstr.max_size();
point_to(rcstr);
}
void RCstring::assign(const RCstring& s)
{
point_to(s.data());
Size = s.size();
}
void RCstring::assign(const std::string& s)
{
point_to(s.data());
Size = s.size();
}
void RCstring::assign(iterator start, iterator end)
{
int length = 0;
for (auto iter = start; iter != end; ++iter)
{
++length;
}
RCstring rcstr = length;
rcstr.lock();
int i = 0;
for (auto iter = start; iter != end; ++iter)
{
rcstr[i] = *iter;
++i;
}
Size = length;
point_to(rcstr);
}
void RCstring::append(const std::string& str)
{
if (Size + str.size() > value->realsize)
{
RCstring rcstr = Size + str.size();
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Size + str.size(); ++i)
{
rcstr[i] = str[i - Size];
}
rcstr.unlock();
Size = Size + str.size();
point_to(rcstr);
return;
}
lock();
for (int i = Size; i < Size + str.size(); ++i)
{
value->value[i] = str[i - Size];
}
unlock();
Size = Size + str.size();
}
void RCstring::append(const RCstring& str)
{
if (Size + str.Size > value->realsize)
{
RCstring rcstr = Size + str.Size;
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Size + str.Size; ++i)
{
rcstr[i] = str[i - Size];
}
rcstr.unlock();
Size = Size + str.Size;
point_to(rcstr);
return;
}
lock();
for (int i = Size; i < Size + str.Size; ++i)
{
value->value[i] = str[i - Size];
}
unlock();
Size = Size + str.Size;
}
void RCstring::append(const char* ptr)
{
int length = strlen(ptr);
if (Size + length > value->realsize)
{
RCstring rcstr = Size + length;
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Size + length; ++i)
{
rcstr[i] = ptr[i - Size];
}
rcstr.unlock();
Size = Size + length;
point_to(rcstr);
return;
}
lock();
for (int i = Size; i < Size + length; ++i)
{
value->value[i] = ptr[i - Size];
}
unlock();
Size = Size + length;
}
void RCstring::append(iterator start, iterator end)
{
int length = 0;
for (auto a = start; a != end; ++a)
{
++length;
}
if (Size + length > value->realsize)
{
RCstring rcstr = Size + length;
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
int i = Size;
for (auto a = start; a != end; ++a)
{
rcstr[i] = *a;
++i;
}
rcstr.unlock();
Size = Size + length;
point_to(rcstr);
return;
}
lock();
int i = Size;
for (auto a = start; a != end; ++a)
{
value->value[i] = *a;
++i;
}
unlock();
Size = Size + length;
}
void RCstring::erase(int off)
{
Size = off;
}
void RCstring::erase(int start, int length)
{
RCstring rcstr(value->realsize - length);
rcstr.lock();
bool isturned = false;
for (int i = 0; i < value->realsize; ++i)
{
if (i == start)
{
i += length;
isturned = true;
}
if (i < value->realsize)
{
if (!isturned)
{
rcstr[i] = value->value[i];
}
else
{
rcstr[i - length] = value->value[i];
}
}
}
rcstr.unlock();
Size -= length;
point_to(rcstr);
}
void RCstring::erase(RCstring::iterator off)
{
int index = 0;
for (auto a = begin(); a != off; ++a)
{
++index;
}
Size = index;
}
void RCstring::erase(iterator _start, iterator _end)
{
int length = 0;
for (auto a = _start; a != _end; ++a)
{
++length;
}
RCstring rcstr = Size - length;
rcstr.lock();
int i = 0;
for (auto a = begin(); a != end(); ++a)
{
if (a == _start)
{
a = _end;
}
if (a != end())
{
rcstr[i] = *a;
++i;
}
}
rcstr.unlock();
Size -= length;
point_to(rcstr);
}
void RCstring::resize(int Newsize, char ch)
{
if (Newsize < Size)
{
Size = Newsize;
return;
}
RCstring rcstr(Newsize);
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Newsize; ++i)
{
rcstr[i] = ch;
}
rcstr.unlock();
Size = Newsize;
point_to(rcstr);
}
void RCstring::reverse(int Newsize)
{
if (Newsize < Size)
{
return;
}
RCstring rcstr(Newsize);
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
rcstr.unlock();
point_to(rcstr);
}
void RCstring::insert(int Where, char p)
{
if (Size + 1 > value->realsize)
{
RCstring rcstr = Size + 1;
rcstr.lock();
int n = 0;
for (int i = 0; i < Size + 1; ++i)
{
if (i == Where)
{
rcstr[i] = p;
n = 1;
}
rcstr[i + n] = value->value[i];
}
rcstr.unlock();
++Size;
point_to(rcstr);
return;
}
for (int right = Size; right > Where; --right)
{
std::swap(value->value[right], value->value[right - 1]);
}
value->value[Where] = p;
++Size;
}
void RCstring::insert(int Where, const char* ptr)
{
int length = strlen(ptr);
if (Size + length > value->realsize)
{
RCstring rcstr = Size + length;
rcstr.lock();
int n = 0;
for (int i = 0; i < Size + length; ++i)
{
if (i == Where)
{
int z = 0;
for (int u = i; u < i + length; ++u)
{
rcstr[u] = ptr[z];
++z;
}
n = length;
}
rcstr[i + n] = value->value[i];
}
rcstr.unlock();
Size += length;
point_to(rcstr);
return;
}
for (int right = Size + length - 1; right > Where; --right)
{
std::swap(value->value[right], value->value[right - 1]);
}
for (int i = Where; i < Where + length; ++i)
{
value->value[i] = ptr[i - Where];
}
Size += length;
}
void RCstring::insert(int Where, const std::string& str)
{
int length = str.size();
if (Size + length > value->realsize)
{
RCstring rcstr = Size + length;
rcstr.lock();
int n = 0;
for (int i = 0; i < Size + length; ++i)
{
if (i == Where)
{
int z = 0;
for (int u = i; u < i + length; ++u)
{
rcstr[u] = str[z];
++z;
}
n = length;
}
rcstr[i + n] = value->value[i];
}
rcstr.unlock();
Size += length;
point_to(rcstr);
return;
}
for (int right = Size + length - 1; right > Where; --right)
{
std::swap(value->value[right], value->value[right - 1]);
}
for (int i = Where; i < Where + length; ++i)
{
value->value[i] = str[i - Where];
}
Size += length;
}
void RCstring::insert(int Where, const RCstring& str)
{
int length = str.size();
if (Size + length > value->realsize)
{
RCstring rcstr = Size + length;
rcstr.lock();
int n = 0;
for (int i = 0; i < Size + length; ++i)
{
if (i == Where)
{
int z = 0;
for (int u = i; u < i + length; ++u)
{
rcstr[u] = str[z];
++z;
}
n = length;
}
rcstr[i + n] = value->value[i];
}
rcstr.unlock();
Size += length;
point_to(rcstr);
return;
}
for (int right = Size + length - 1; right > Where; --right)
{
std::swap(value->value[right], value->value[right - 1]);
}
for (int i = Where; i < Where + length; ++i)
{
value->value[i] = str[i - Where];
}
Size += length;
}
const RCstring RCstring::operator+(const char* ptr)
{
int length = strlen(ptr);
RCstring str = length + Size;
str.lock();
for (int i = 0; i < Size; ++i)
{
str[i] = value->value[i];
}
for (int i = Size; i < Size + length; ++i)
{
str[i] = ptr[i - Size];
}
str.unlock();
str.Size = length + Size;
return str;
}
const RCstring RCstring::operator+(const std::string& str)
{
RCstring rcstr = Size + str.size();
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Size + str.size(); ++i)
{
rcstr[i] = str[i - Size];
}
rcstr.unlock();
rcstr.Size = Size + str.size();
return rcstr;
}
const RCstring RCstring::operator+(const RCstring& str)
{
RCstring rcstr = Size + str.size();
rcstr.lock();
for (int i = 0; i < Size; ++i)
{
rcstr[i] = value->value[i];
}
for (int i = Size; i < Size + str.size(); ++i)
{
rcstr[i] = str[i - Size];
}
rcstr.unlock();
rcstr.Size = Size + str.size();
return rcstr;
}
RCstring::iterator RCstring::begin()const
{
return value->value;
}
RCstring::iterator RCstring::end()const
{
return value->value + Size;
}
RCstring::iterator RCstring::rbegin()const
{
return value->value + Size - 1;
}
RCstring::iterator RCstring::rend()const
{
return value->value - 1;
}
const char* RCstring::data()const
{
return value->value;
}
int RCstring::toint()const
{
return std::stoi(value->value);
}
float RCstring::tofloat()const
{
return std::stof(value->value);
}
std::string RCstring::tostring()const
{
return std::string(value->value);
}
void RCstring::lock()
{
locked = true;
if (value->count > 1)
{
copy();
}
}
void RCstring::unlock()
{
if (!locked)
{
return;
}
auto iter = hash.find(value->value);
locked = false;
if (iter != hash.end())
{
delete value;
value = iter->second;
++value->count;
}
else
{
hash.insert(std::pair<std::string, RCstringValue*>(value->value, value));
}
}
RCstring& RCstring::operator=(const RCstring& rhs)
{
if (rhs.locked)
{
value->copy_str(rhs.value->value);
Size = value->realsize;
return *this;
}
--value->count;
if (value->count == 0)
{
hash.erase(value->value);
delete value;
value = nullptr;
}
value = rhs.value;
++value->value;
return *this;
}
bool RCstring::operator==(const RCstring& rhs)
{
if (Size != rhs.Size)
{
return false;
}
for (int i = 0; i < Size; ++i)
{
if (value->value[i] != rhs[i])
{
return false;
}
}
return true;
}
bool RCstring::operator!=(const RCstring& rhs)
{
if (Size != rhs.Size)
{
return true;
}
for (int i = 0; i < Size; ++i)
{
if (value->value[i] != rhs[i])
{
return true;
}
}
return false;
}
char& RCstring::operator[](int index)
{
if (locked)
{
return value->value[index];
}
lock();
return value->value[index];
}
char RCstring::operator[](int index)const
{
return value->value[index];
}
char RCstring::operator()(int index)const
{
return value->value[index];
}
char RCstring::at(int index)const
{
if (index < 0 || index>Size)
{
std::abort();
}
return value->value[index];
}
int RCstring::size()const
{
return Size;
}
int RCstring::max_size()const
{
return value->realsize;
}
RCstring::~RCstring()
{
--value->count;
if (value->count == 0)
{
hash.erase(value->value);
delete value;
value = nullptr;
}
}
有错误请大佬指正!