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类型的更多相关文章

  1. 从零开始写STL - 智能指针

    从零开始写STL - 智能指针 智能指针的分类及其特点: scoped_ptr:初始化获得资源控制权,在作用域结束释放资源 shared_ptr: 引用计数来控制共享资源,最后一个资源的引用被释放的时 ...

  2. 从零开始写STL—栈和队列

    从零开始写STL-栈和队列 适配器模式 意图:将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 主要解决:主要解决在软件系统中,常常要将 ...

  3. 从零开始写STL—容器—vector

    从0开始写STL-容器-vector vector又称为动态数组,那么动态体现在哪里?vector和一般的数组又有什么区别?vector中各个函数的实现原理是怎样的,我们怎样使用会更高效? 以上内容我 ...

  4. [STL]string类型的getline函数

    3.cin.getline() 实际是cin.getline(接收字符串到m,接收个数n,结束字符).接收一个字符串,可以接收空格等,最后一个字符为‘\0’.结束符可以通过设置第三个参数自己设置,默认 ...

  5. 从零开始写STL—模板元编程之any

    any class any; (since C++17) The class any describes a type-safe container for single values of any ...

  6. 从零开始写STL—functional

    function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起. 这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用 基本运算符 ...

  7. 从零开始写STL—哈希表

    static const int _stl_num_primes = 28; template<typename T, typename Hash = xhash<T>> cl ...

  8. 从零开始写STL—模板元编程之tuple

    tuple Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generali ...

  9. 从零开始写STL—set/map

    这一部分只要把搜索树中暴露的接口封装一下,做一些改动. set源码剖析 template<typename T> class set { public: typedef T key_typ ...

  10. switch case :在JDK 7中,又加入了对String类型的支持,从此不用再写If-Else来判断字符串了

    switch的case语句可以处理int,short,byte,char类型的值, 因为short,byte,char都会转换成int进行处理,这一点也可以从生成的字节码看出. char a = 'e ...

随机推荐

  1. CMSIS的简介

    Cortex微控制器软件接口标准(Cortex Microcontroller Software Interface Standard)是ARM和一些编译器厂家以及半导体厂家共同遵循的一套标准,是由A ...

  2. 在2015年 开发一个 Web App 必须了解的那些事

    在过去的一年里,我在从头开始开发我的第一个重要的Web应用.经验教会了很多以前不知道的东西,特别是在安全性和用户体验方面. 值得一提的是,我上一次尝试构建的任何合理复杂性是在2005年.所以,在安全防 ...

  3. Python基础2 列表 元祖 字符串 字典 集合 文件操作 -DAY2

    本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 ...

  4. ::Sleep(0)的使用

    ::Sleep(0)的使用 This function causes a thread to relinquish the remainder of its time slice and become ...

  5. Hibernate初始化环境的基本封装

    public class HibernateUtils { private static SessionFactory sf; static{ sf = new Configuration().con ...

  6. Eclipse Code Recommenders 自动补全(联想)神器

    Eclipse Code Recommenders 可以在eclipse市场中下载.自动补全.模糊匹配.非常有用!

  7. Java中的反射--Reflect

    在张孝祥老师的Java讲解中,学习到了Java反射的一部分知识,觉得有必要好好学习一下哈. 一.反射的理解 经典总结:反射就是把Java类中的各种成分映射成为相应的Java类 例如:一个Java类中用 ...

  8. 关闭Visual Studio 2015 关闭单击打开文件的功能

    工具-->选项-->环境-->选项卡和窗口-->预览选项卡 去掉“在解决方案资源管理器中预览选定的文件(在按住Alt的同时单击可避免预览)(X)”的勾选

  9. sftp ftp文件同步方案

    sftp ftp文件同步方案 1. 需求 1.1实现网关服务器的ftp服务器的/batchFileRequest目录下文件向徽商所使用的sftp服务器的/batchFileRequest目录同步文件 ...

  10. 解决SimpleDateFormat线程安全问题

    package com.tanlu.user.util; import java.text.DateFormat; import java.text.ParseException; import ja ...