从零开始写STL-string类型
class string
{
public:
typedef size_t size_type;
typedef char* iterator;
typedef char value_type;
private:
char *start, *end_of_storage, *End;
std::allocator<char> data_allocator;
void DeallocateAndDestory()
{
data_allocator.deallocate(start, end_of_storage - start);
}
//重新构造元素
void reallocate(size_t new_size = 0)
{
size_t old_size = size();
if (new_size == 0)
new_size = size() ? 2 * size() : 1;
char* new_start = data_allocator.allocate(new_size);
std::copy(start, start + size(), new_start);
DeallocateAndDestory();
start = new_start;
End = new_start + old_size;
end_of_storage = new_start + new_size;
}
//移动构造元素
/*void reallocate()
{
int old_size = size();
int new_size = size() ? 2 * size() : 1;
char* new_start = data_allocator.allocate(new_size);
char* pos = new_start;
char* old_pos = start;
for (int i = 0; i < old_size; i++)
data_allocator.construct(pos++, std::move(*old_pos)), old_pos++;
data_allocator.deallocate(start, old_size);
start = new_start;
End = new_start + old_size;
end_of_storage = new_start + new_size;
}*/
public:
//debug
void print()
{
for (auto it = start; it != End; it++)
std::cout << *it;
std::cout << std::endl;
}
//Construct
string()
{
start = end_of_storage = End = nullptr;
}
string(const string& rhs)
{
start = end_of_storage = End = nullptr;
append(rhs);
}
string(string&& rhs)noexcept :start(rhs.start), end_of_storage(rhs.end_of_storage), End(rhs.End)
{
rhs.start = rhs.end_of_storage = rhs.End = nullptr;
}
string(const char* s)
{
if (s == nullptr)
string();
else
{
int cnt = 0;
for (; s[cnt] != '\0'; cnt++) {}
start = data_allocator.allocate(cnt);
std::uninitialized_copy_n(s, cnt, start);
end_of_storage = End = start + cnt;
}
}
string(size_type n, char c)
{
start = data_allocator.allocate(n);
std::uninitialized_fill_n(start, n, c);
end_of_storage = End = start + n;
}
string(const char* s, size_t n)
{
start = data_allocator.allocate(n);
std::uninitialized_copy_n(s, n, start);
End = end_of_storage = start + n;
}
~string()
{
DeallocateAndDestory();
}
//Iterator
const iterator begin() const
{
return start;
}
const iterator end() const
{
return End;
}
iterator begin()
{
return start;
}
iterator end()
{
return End;
}
//Capacity
void clear()
{
DeallocateAndDestory();
End = start = end_of_storage = nullptr;
}
bool empty()const
{
return (start == End);
}
const size_type size() const
{
return End - start;
}
const size_type length() const
{
return size();
}
const size_type capacity() const
{
return end_of_storage - start;
}
void resize(size_type n)
{
resize(n, value_type());
}
void resize(size_type n, const value_type &val)
{
if (n <= size())
{
End = start + n;
}
else
{
append(string(n - size(), val));
}
}
void reserve(size_type res_arg = 0)
{
if (res_arg + size() < capacity()) return;
reallocate(res_arg + size());
}
//Modifiers
value_type& operator[](size_type index)
{
if (index < 0 || index >= size())
{
std::cerr << "index out of range!" << std::endl;
std::exit(1);
}
else
{
return *(start + index);
}
}
value_type& front()
{
return *start;
}
value_type& back()
{
auto tmp = end();
return *(--tmp);
}
void push_back(const value_type& val)
{
if (size() == capacity())
reallocate();
*End = val;
End++;
}
void pop_back()
{
if (empty())
{
std::cerr << "Error : pop_back() on empty String!" << std::endl;
exit(1);
}
End--;
}
void swap(string& rhs)
{
std::swap(start, rhs.start);
std::swap(end_of_storage, rhs.end_of_storage);
std::swap(End, rhs.End);
}
void append(const string& rhs)
{
if (rhs.empty()) return;
if (capacity()<size() + rhs.size()) reallocate(size() + rhs.size());
std::copy(rhs.start, rhs.end_of_storage, End);
End += rhs.size();
}
void append(const char* s)
{
if (s == nullptr) return;
size_t cnt = 0;
for (; s[cnt] != '\0'; cnt++) {}
if (capacity() < size() + cnt) reallocate(size() + cnt);
std::uninitialized_copy_n(s, cnt, End);
End += cnt;
}
void append(const char* s, size_t l, size_t r)
{
if (r <= l ) return;
if (s == nullptr) return;
if (capacity()<size() + r - l - 1) reallocate(size() + r - l);
std::uninitialized_copy_n(s + l, r - l, End);
End += r - l;
}
string& operator+=(const char c)
{
(*this).push_back(c);
return *this;
}
string& operator+=(const string& rhs)
{
(*this).append(rhs);
return *this;
}
string operator+(const string& rhs)
{
string tmp(*this);
return tmp += rhs;
}
string& operator=(const string& str)
{
return assign(str);
}
string& operator=(const char* s)
{
return assign(string(s));
}
string& operator=(char c)
{
return assign(string((size_type)1, c));
}
string& assign(const string& str)
{
clear();
append(str);
return (*this);
}
string& assign(const char* s)
{
clear();
if (s == nullptr) return *this;
size_t cnt = 0;
while (s[cnt] != '\0') cnt++;
start = data_allocator.allocate(cnt);
End = std::uninitialized_copy_n(s, cnt, start);
end_of_storage += cnt;
}
string& assign(size_type n, char c)
{
clear();
if (n == 0) return *this;
start = data_allocator.allocate(n);
End = end_of_storage = std::uninitialized_fill_n(start, n, c);
}
string& insert(size_type pos, const string& rhs)
{
pos = std::min(size(), pos);
size_type new_size = size() + rhs.size();
iterator new_start = data_allocator.allocate(new_size);
std::copy(start, start + pos, new_start);
std::copy(rhs.start, rhs.End, new_start + pos);
std::copy(start + pos, End, new_start + pos + rhs.size());
start = new_start;
end_of_storage = End = new_size + new_start;
return *this;
}
string& insert(size_type pos, const char* s, size_type n)
{
return insert(pos, string(s, n));
}
string& insert(size_type pos, const char* s)
{
return insert(pos, string(s));
}
iterator insert(iterator pos, const value_type& val)
{
size_type index = pos - start;
if (size() == capacity())
reallocate();
pos = start + index;
if (pos > end()) pos = end();
std::copy(pos, End, pos + 1);
(*pos) = val;
End++;
return pos;
}
string& insert(size_type pos, size_type num, const value_type& val)
{
return insert(pos, string(num, val));
}
string& insert(iterator pos, size_type num, const value_type& val)
{
return insert(pos - start, string(num, val));
}
string& erase(size_type pos, size_type n)
{
std::copy(pos + n + start, End, start + pos);
End = End - n;
return *this;
}
iterator erase(iterator pos)
{
std::copy(pos + 1, End, pos);
End--;
return pos;
}
iterator erase(iterator first, iterator last)
{
std::copy(last, End, first);
End = End - (last - first);
return first;
}
string& replace(size_t pos, size_t n, const string& str)
{
erase(pos, n);
insert(pos, str);
return *this;
}
string& replace(iterator i1, iterator i2, const string& str)
{
insert(erase(i1, i2) - start, str);
return *this;
}
const char* c_str() const
{
if (empty()) return "";
char* ret = new char[End - start + 1];
std::uninitialized_copy(start, End, ret);
ret[End - start] = '\0';
return ret;
}
bool operator == (const string& rhs)
{
if (size() != rhs.size())
return false;
else
{
for (auto i = start, j = rhs.start; i != End; i++, j++)
{
if ((*i) != (*j))
return false;
}
return true;
}
}
bool operator == (const string& rhs) const
{
if (size() != rhs.size())
return false;
else
{
for (auto i = start, j = rhs.start; i != End; i++, j++)
{
if ((*i) != (*j))
return false;
}
return true;
}
}
int compare(const string& rhs)
{
iterator i = start, j = rhs.start;
while (i != End && j != rhs.End)
{
if ((*i) > (*j))
return 1;
else if ((*i) < (*j))
return -1;
else
i++, j++;
}
if (i == End&&j == rhs.End)
return 0;
else if (i == End)
return -1;
else
return 1;
}
size_type copy(char* s, size_type n, size_type pos = 0) const
{
if (pos + n >= size())
{
std::cerr << "out of range" << std::endl;
std::exit(1);
}
std::uninitialized_copy_n(start + pos, n, s);
return n;
}
size_t find(const string& str, size_t pos = 0) const
{
if (size() - pos < str.size())
return (size_type)(-1);
for (auto it = start + pos; it != End; it++)
{
auto i = it, j = str.start;
while (j<str.End && *i == *j)
i++, j++;
if (j == str.End)
return it - start;
}
return (size_type)(-1);
}
size_t find(const char* s, size_t pos, size_t n) const
{
return find(string(s, n), pos);
}
size_t find(const char* s, size_t pos = 0) const
{
return find(string(s), pos);
}
size_t find(char c, size_t pos = 0) const
{
if (empty())
return size_type(-1);
else
{
for (auto it = start; it != End; it++)
if (*it == c)
return it - start;
return size_type(-1);
}
}
string substr(size_t pos = 0, size_t n = 0)
{
return string(start + pos, n);
}
size_t rfind(string& rhs, size_t pos = 0)
{
if (pos == 0) pos = size();
for (auto it = std::min(start + pos, End - 1); it != start - 1; it--)
{
size_t i;
for (i = 0; i < rhs.size();)
if (rhs[i] == *(it + i))
i++;
else
break;
if (i == rhs.size())
return it - start;
}
return size_t(-1);
}
size_t rfind(const char& c, size_t pos = 0)
{
if (pos == 0) pos = size();
for (auto it = std::min(End - 1, start + pos); it != start; it--)
{
if (*it == c)
return it - start;
}
return size_t(-1);
}
size_t rfind(const char* str)
{
return rfind(string(str));
}
size_t find_first_of(const string& rhs, size_t pos = 0)
{
for (auto it = start + pos; it != End; it++)
{
auto i = rhs.start;
while (i != rhs.End)
{
if (*i == *it)
break;
i++;
}
if (i != rhs.End)
return it - start;
}
return (size_t)-1;
}
size_t find_first_of(const char& c, size_t pos = 0)
{
for (auto it = start + pos; it != End; it++)
{
if (*it == c)
return it - start;
}
return (size_t)-1;
}
size_t find_last_of(const char &c, size_t pos = 0)
{
if (pos == 0) pos = size();
for (auto it = pos + start; it != start - 1; it--)
if (*it == c)
return it - start;
return (size_t)-1;
}
size_t find_last_of(const char* str, size_t pos, size_t len)
{
size_t l = 0;
for (size_t i = 0; str[i] != '\0'; i++)
l++;
for (auto it = start + pos; it != start + pos - len; it--)
{
size_t i;
for (i = 0; str[i] != '\0'; i++)
if (str[i] == *it)
break;
if (str[i] != '\0') return it - start;
}
return size_t(-1);
}
size_t find_last_of(const string& rhs, size_t pos)
{
for (auto it = start + pos; it != start - 1; it--)
{
size_t i = 0;
while (rhs.start + i != rhs.End)
if (*it == *(start + i))
break;
else
i++;
if (rhs.size() != i) return it - start;
}
return size_t(-1);
}
size_t find_first_not_of(const string& rhs)
{
for (auto it = start; it != End; it++)
{
size_t i = 0;
while (i < rhs.size())
if (*(rhs.start + i) == *it)
break;
else
i++;
if (i == rhs.size()) return it - start;
}
return size_t(-1);
}
size_t find_last_not_of(const string& rhs, size_t pos)
{
for (auto it = start + pos; it != start - 1; it--)
{
size_t i = 0;
while (i < rhs.size())
if (*(rhs.start + i) == *it)
break;
else
i++;
if (i == rhs.size()) return it - start;
}
return size_t(-1);
}
bool operator!=(const string& rhs)
{
return !(*this == rhs);
}
bool operator>(const string& rhs)
{
return compare(rhs) > 0;
}
bool operator>=(const string& rhs)
{
return compare(rhs) >= 0;
}
bool operator<(const string& rhs)
{
return compare(rhs) < 0;
}
bool operator<=(const string& rhs)
{
return compare(rhs) <= 0;
}
};
std::ostream& operator<<(std::ostream& os, const ministl::string& rhs)
{
os << rhs.c_str();
return os;
}
size_t hash_value(const string& val)
{
const size_t _FNV_offset_basis = 2166136261U;
const size_t _FNV_prime = 16777619U;
size_t ans = _FNV_offset_basis;
for (auto it = val.begin(); it != val.end(); it++)
{
ans ^= *it;
ans *= _FNV_prime;
}
return ans;
}
}
从零开始写STL-string类型的更多相关文章
- 从零开始写STL - 智能指针
从零开始写STL - 智能指针 智能指针的分类及其特点: scoped_ptr:初始化获得资源控制权,在作用域结束释放资源 shared_ptr: 引用计数来控制共享资源,最后一个资源的引用被释放的时 ...
- 从零开始写STL—栈和队列
从零开始写STL-栈和队列 适配器模式 意图:将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 主要解决:主要解决在软件系统中,常常要将 ...
- 从零开始写STL—容器—vector
从0开始写STL-容器-vector vector又称为动态数组,那么动态体现在哪里?vector和一般的数组又有什么区别?vector中各个函数的实现原理是怎样的,我们怎样使用会更高效? 以上内容我 ...
- [STL]string类型的getline函数
3.cin.getline() 实际是cin.getline(接收字符串到m,接收个数n,结束字符).接收一个字符串,可以接收空格等,最后一个字符为‘\0’.结束符可以通过设置第三个参数自己设置,默认 ...
- 从零开始写STL—模板元编程之any
any class any; (since C++17) The class any describes a type-safe container for single values of any ...
- 从零开始写STL—functional
function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起. 这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用 基本运算符 ...
- 从零开始写STL—哈希表
static const int _stl_num_primes = 28; template<typename T, typename Hash = xhash<T>> cl ...
- 从零开始写STL—模板元编程之tuple
tuple Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generali ...
- 从零开始写STL—set/map
这一部分只要把搜索树中暴露的接口封装一下,做一些改动. set源码剖析 template<typename T> class set { public: typedef T key_typ ...
- switch case :在JDK 7中,又加入了对String类型的支持,从此不用再写If-Else来判断字符串了
switch的case语句可以处理int,short,byte,char类型的值, 因为short,byte,char都会转换成int进行处理,这一点也可以从生成的字节码看出. char a = 'e ...
随机推荐
- iOS 解决iOS 9下的http请求发送失败问题
iOS9中 因为系统要求所有的请求都必须使用https, 所以发送http请求会失败,如果想让程序能够兼容http请求 在info.plist中添加以下代码: 这里需要做的是右键info.plist文 ...
- B/S网络架构
B/S基于统一的应用层协议HTTP来交互数据,目前的B/S网络架构大多采用如图所示的架构设计,既要满足海量用户访问请求,又要保持用户请求的快速响应. 当一个用户在浏览器输入www.taobao.com ...
- 为sublime Text3 安装插件JS Format
1. 安装package control 菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去并 enter 执行,不 ...
- SAP成都研究院安德鲁:自己动手开发一个Chrome Extension
各位好,我叫何金鑫(He Andrew), 团队同事亲切地称呼在下为安德鲁.如果你在附近找到wifi热点名为 「安德鲁森面包房5g」,可能是我就在附近,我们可以去喝杯咖啡,聊聊最近有趣的东西. 鄙人现 ...
- Windows程序设计2(消息机制、菜单)
一 .小记; PostQuitMessage(0); 产生WM_QUIT消息给进程队列,且立即返回,同时使得消息循环退出,使得进程终止.(其实它通过PostMessage(hWnd,WM_QUIT,0 ...
- uva1627 Team them up!
注意这题要求互相认识不认识的人之间连一条线一个人在组1,那么不认识(互相认识)的人就在组0:同时这些人不认识的人就在组1.每个联通分量都可以独立推导,遇到矛盾则无解一个联通分量有一个核心,其他的点是分 ...
- Java数据结构和算法(一)--栈
栈: 英文名stack,特点是只允许访问最后插入的那个元素,也就是LIFO(后进先出) jdk中的stack源码: public class Stack<E> extends Vector ...
- regular expression matching DP
这个题目,我从前天晚上(8月6号晚上)调试到现在(8月8号16:21),太心酸了,不好好总结一下,就太对不起自己了! 这是题目: Implement regular expression matchi ...
- rfcn讲解博客
http://www.cnblogs.com/lillylin/p/6277094.html ROI pooling操作的输入(对于C+1个类)是k^2*(C+1)*W' *H'(W'和H'是ROI的 ...
- Mapping (RESOURCE) not found :和BeanFactory not initialized or already closed - call 'refresh' before access记录
1.Mapping (RESOURCE) not found :cn/sxx/model/Supplier.hbm.xml : origin(cn/sxx/model/Supplier.hbm.xml ...