经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
string是stl中的一个重要结构,但是也是我做的最头疼的一个部分,过程非常无为,闪光点很少,但篇幅却很长。。。建议看有趣的部分就好了
string.h
#pragma once
#ifndef _STRING_H_
#define _STRING_H_
#include "Allocator.h"
#include "ReverseIterator.h"
#include "UninitializedFunctions.h"
#include "Utility.h"
#include <cstring>
#include <type_traits>
namespace mySTL {
//the class of string
class string {
public:
typedef char value_type;
typedef char * iterator;
typedef const char * const_iterator;
typedef reverse_iterator_t<char*> reverse_iterator;
typedef reverse_iterator_t<const char*> const_reverse_iterator;
typedef char& reference;
typedef const char& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
//npos is a static member constant value with the greatest possible value for an element of type size_t.
static const size_t npos = -1;
private:
char *start_;
char *finish_;
char *endOfStorage_;
typedef mySTL::allocator<char> dataAllocator;
public:
string() :start_(0), finish_(0), endOfStorage_(0) {}
string(const string& str);
string(string&& str);
string(const string& str, size_t pos, size_t len = npos);
string(const char* s);
string(const char* s, size_t n);
string(size_t n, char c);
template <class InputIterator>
string(InputIterator first, InputIterator last);
string& operator= (const string& str);
string& operator= (string&& str);
string& operator= (const char* s);
string& operator= (char c);
~string();
iterator begin() { return start_; }
const_iterator begin() const { return start_; }
iterator end() { return finish_; }
const_iterator end() const { return finish_; }
reverse_iterator rbegin() { return reverse_iterator(finish_); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(finish_); }
reverse_iterator rend() { return reverse_iterator(start_); }
const_reverse_iterator rend() const { return const_reverse_iterator(start_); }
const_iterator cbegin() const { return start_; }
const_iterator cend() const { return finish_; }
const_reverse_iterator crbegin() const { return const_reverse_iterator(finish_); }
const_reverse_iterator crend() const { return const_reverse_iterator(start_); }
size_t size() const { return finish_ - start_; }
size_t length() const { return size(); }
size_t capacity() const { return endOfStorage_ - start_; }
void clear() {
dataAllocator::destroy(start_, finish_);
start_ = finish_;
}
bool empty() const { return begin() == end(); }
void resize(size_t n);
void resize(size_t n, char c);
void reserve(size_t n = 0);
void shrink_to_fit() {
dataAllocator::deallocate(finish_, endOfStorage_ - finish_);
endOfStorage_ = finish_;
}
char& operator[] (size_t pos) { return *(start_ + pos); }
const char& operator[] (size_t pos) const { return *(start_ + pos); }
char& back() { return *(finish_ - 1); }
const char& back() const { return *(finish_ - 1); }
char& front() { return *(start_); }
const char& front() const { return *(start_); }
void push_back(char c) { insert(end(), c); }
string& insert(size_t pos, const string& str);
string& insert(size_t pos, const string& str, size_t subpos, size_t sublen = npos);
string& insert(size_t pos, const char* s);
string& insert(size_t pos, const char* s, size_t n);
string& insert(size_t pos, size_t n, char c);
iterator insert(iterator p, size_t n, char c);
iterator insert(iterator p, char c);
template <class InputIterator>
iterator insert(iterator p, InputIterator first, InputIterator last);
string& append(const string& str);
string& append(const string& str, size_t subpos, size_t sublen = npos);
string& append(const char* s);
string& append(const char* s, size_t n);
string& append(size_t n, char c);
template <class InputIterator>
string& append(InputIterator first, InputIterator last);
string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);
void pop_back() { erase(end() - 1, end()); }
string& erase(size_t pos = 0, size_t len = npos);
iterator erase(iterator p);
iterator erase(iterator first, iterator last);
string& replace(size_t pos, size_t len, const string& str);
string& replace(iterator i1, iterator i2, const string& str);
string& replace(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen = npos);
string& replace(size_t pos, size_t len, const char* s);
string& replace(iterator i1, iterator i2, const char* s);
string& replace(size_t pos, size_t len, const char* s, size_t n);
string& replace(iterator i1, iterator i2, const char* s, size_t n);
string& replace(size_t pos, size_t len, size_t n, char c);
string& replace(iterator i1, iterator i2, size_t n, char c);
template <class InputIterator>
string& replace(iterator i1, iterator i2, InputIterator first, InputIterator last);
void swap(string& str) {
mySTL::swap(start_, str.start_);
mySTL::swap(finish_, str.finish_);
mySTL::swap(endOfStorage_, str.endOfStorage_);
}
size_t copy(char* s, size_t len, size_t pos = 0) const {
auto ptr =mySTL::uninitialized_copy(begin() + pos, begin() + pos + len, s);
return (size_t)(ptr - s);
}
size_t find(const string& str, size_t pos = 0) const;
size_t find(const char* s, size_t pos = 0) const;
size_t find(const char* s, size_t pos, size_t n) const;
size_t find(char c, size_t pos = 0) const;
size_t rfind(const string& str, size_t pos = npos) const;
size_t rfind(const char* s, size_t pos = npos) const;
size_t rfind(const char* s, size_t pos, size_t n) const;
size_t rfind(char c, size_t pos = npos) const;
size_t find_first_of(const string& str, size_t pos = 0) const;
size_t find_first_of(const char* s, size_t pos = 0) const;
size_t find_first_of(const char* s, size_t pos, size_t n) const;
size_t find_first_of(char c, size_t pos = 0) const;
size_t find_last_of(const string& str, size_t pos = npos) const;
size_t find_last_of(const char* s, size_t pos = npos) const;
size_t find_last_of(const char* s, size_t pos, size_t n) const;
size_t find_last_of(char c, size_t pos = npos) const;
size_t find_first_not_of(const string& str, size_t pos = 0) const;
size_t find_first_not_of(const char* s, size_t pos = 0) const;
size_t find_first_not_of(const char* s, size_t pos, size_t n) const;
size_t find_first_not_of(char c, size_t pos = 0) const;
size_t find_last_not_of(const string& str, size_t pos = npos) const;
size_t find_last_not_of(const char* s, size_t pos = npos) const;
size_t find_last_not_of(const char* s, size_t pos, size_t n) const;
size_t find_last_not_of(char c, size_t pos = npos) const;
string substr(size_t pos = 0, size_t len = npos) const {
len = changeVarWhenEuqalNPOS(len, size(), pos);
return string(begin() + pos, begin() + pos + len);
}
int compare(const string& str) const;
int compare(size_t pos, size_t len, const string& str) const;
int compare(size_t pos, size_t len, const string& str,
size_t subpos, size_t sublen = npos) const;
int compare(const char* s) const;
int compare(size_t pos, size_t len, const char* s) const;
int compare(size_t pos, size_t len, const char* s, size_t n) const;
private:
void moveData(string& str);
//插入时空间不足的情况
template<class InputIterator>
iterator insert_aux_copy(iterator p, InputIterator first, InputIterator last);
//插入时空间不足的情况
iterator insert_aux_filln(iterator p, size_t n, value_type c);
size_type getNewCapacity(size_type len)const;
void allocateAndFillN(size_t n, char c);
template<class InputIterator>
void allocateAndCopy(InputIterator first, InputIterator last);
void string_aux(size_t n, char c, std::true_type);
template<class InputIterator>
void string_aux(InputIterator first, InputIterator last, std::false_type);
void destroyAndDeallocate();
size_t rfind_aux(const_iterator cit, size_t pos, size_t lengthOfS, int cond)const;
size_t find_aux(const_iterator cit, size_t pos, size_t lengthOfS, size_t cond)const;
int compare_aux(size_t pos, size_t len, const_iterator cit, size_t subpos, size_t sublen)const;
bool isContained(char ch, const_iterator first, const_iterator last)const;
size_t changeVarWhenEuqalNPOS(size_t var, size_t minuend, size_t minue)const;
public:
friend std::ostream& operator <<(std::ostream& os, const string&str);
friend std::istream& operator >> (std::istream& is, string& str);
friend string operator+ (const string& lhs, const string& rhs);
friend string operator+ (const string& lhs, const char* rhs);
friend string operator+ (const char* lhs, const string& rhs);
friend string operator+ (const string& lhs, char rhs);
friend string operator+ (char lhs, const string& rhs);
friend bool operator== (const string& lhs, const string& rhs);
friend bool operator== (const char* lhs, const string& rhs);
friend bool operator== (const string& lhs, const char* rhs);
friend bool operator!= (const string& lhs, const string& rhs);
friend bool operator!= (const char* lhs, const string& rhs);
friend bool operator!= (const string& lhs, const char* rhs);
friend bool operator< (const string& lhs, const string& rhs);
friend bool operator< (const char* lhs, const string& rhs);
friend bool operator< (const string& lhs, const char* rhs);
friend bool operator<= (const string& lhs, const string& rhs);
friend bool operator<= (const char* lhs, const string& rhs);
friend bool operator<= (const string& lhs, const char* rhs);
friend bool operator> (const string& lhs, const string& rhs);
friend bool operator> (const char* lhs, const string& rhs);
friend bool operator> (const string& lhs, const char* rhs);
friend bool operator>= (const string& lhs, const string& rhs);
friend bool operator>= (const char* lhs, const string& rhs);
friend bool operator>= (const string& lhs, const char* rhs);
friend void swap(string& x, string& y);
friend std::istream& getline(std::istream& is, string& str, char delim);
friend std::istream& getline(std::istream& is, string& str);
};// end of string
template<class InputIterator>
string::string(InputIterator first, InputIterator last) {
//处理指针和数字间的区别的函数
string_aux(first, last, typename std::is_integral<InputIterator>::type());
}
template <class InputIterator>
string::iterator string::insert_aux_copy(iterator p, InputIterator first, InputIterator last) {
size_t lengthOfInsert = last - first;
auto newCapacity = getNewCapacity(lengthOfInsert);
iterator newStart = dataAllocator::allocate(newCapacity);
iterator newFinish = TinySTL::uninitialized_copy(start_, p, newStart);
newFinish = mySTL::uninitialized_copy(first, last, newFinish);
auto res = newFinish;
newFinish = mySTL::uninitialized_copy(p, finish_, newFinish);
destroyAndDeallocate();
start_ = newStart;
finish_ = newFinish;
endOfStorage_ = start_ + newCapacity;
return res;
}
template <class InputIterator>
string::iterator string::insert(iterator p, InputIterator first, InputIterator last) {
auto lengthOfLeft = capacity() - size();
size_t lengthOfInsert = distance(first, last);
if (lengthOfInsert <= lengthOfLeft) {
for (iterator it = finish_ - 1; it >= p; --it) {
*(it + lengthOfInsert) = *(it);
}
mySTL::uninitialized_copy(first, last, p);
finish_ += lengthOfInsert;
return (p + lengthOfInsert);
}
else {
return insert_aux_copy(p, first, last);
}
}
template <class InputIterator>
string& string::append(InputIterator first, InputIterator last) {
insert(end(), first, last);
return *this;
}
template <class InputIterator>
//先删除后插入,好粗暴啊
string& string::replace(iterator i1, iterator i2,
InputIterator first, InputIterator last) {
auto ptr = erase(i1, i2);
insert(ptr, first, last);
return *this;
}
template<class InputIterator>
void string::allocateAndCopy(InputIterator first, InputIterator last) {
start_ = dataAllocator::allocate(last - first);
finish_ = mySTL::uninitialized_copy(first, last, start_);
endOfStorage_ = finish_;
}
template<class InputIterator>
void string::string_aux(InputIterator first, InputIterator last, std::false_type) {
allocateAndCopy(first, last);
}
}
#endif
string.cpp
#include"../String.h"
#include<iostream>
namespace mySTL {
const size_t string::npos;
string::string(size_t n, char c) {
allocateAndFillN(n, c);
}
string::string(const char* s) {
allocateAndCopy(s, s + strlen(s));
}
string::string(const char* s, size_t n) {
allocateAndCopy(s, s + n);
}
string::string(const string& str) {
allocateAndCopy(str.start_, str.finish_);
}
string::string(string&& str) {
moveData(str);
}
string::string(const string& str, size_t pos, size_t len) {
len = changeVarWhenEuqalNPOS(len, str.size(), pos);
allocateAndCopy(str.start_ + pos, str.start_ + pos + len);
}
string::~string() {
destroyAndDeallocate();
}
string& string::operator= (const string& str) {
if (this != &str) {
destroyAndDeallocate();
allocateAndCopy(str.start_, str.finish_);
}
return *this;
}
string& string::operator= (string&& str) {
if (this != &str) {
moveData(str);
}
return *this;
}
string& string::operator= (const char* s) {
destroyAndDeallocate();
allocateAndCopy(s, s + strlen(s));
return *this;
}
string& string::operator= (char c) {
destroyAndDeallocate();
allocateAndFillN(1, c);
return *this;
}
void string::resize(size_t n) {
resize(n, value_type());
}
void string::resize(size_t n, char c) {
if (n < size()) {
dataAllocator::destroy(start_ + n, finish_);
finish_ = start_ + n;
}
else if (n > size() && n <= capacity()) {
auto lengthOfInsert = n - size();
finish_ = mySTL::uninitialized_fill_n(finish_, lengthOfInsert, c);
}
else if (n > capacity()) {
auto lengthOfInsert = n - size();
iterator newStart = dataAllocator::allocate(getNewCapacity(lengthOfInsert));
iterator newFinish = mySTL::uninitialized_copy(begin(), end(), newStart);
newFinish = mySTL::uninitialized_fill_n(newFinish, lengthOfInsert, c);
destroyAndDeallocate();
start_ = newStart;
finish_ = newFinish;
endOfStorage_ = start_ + n;
}
}
void string::reserve(size_t n) {
if (n <= capacity())
return;
iterator newStart = dataAllocator::allocate(n);
iterator newFinish = mySTL::uninitialized_copy(begin(), end(), newStart);
destroyAndDeallocate();
start_ = newStart;
finish_ = newFinish;
endOfStorage_ = start_ + n;
}
string& string::insert(size_t pos, const string& str) {
insert(start_ + pos, str.begin(), str.end());
return *this;
}
//???
string& string::insert(size_t pos, const string& str, size_t subpos, size_t sublen) {
sublen = changeVarWhenEuqalNPOS(sublen, str.size(), subpos);
insert(begin() + pos, str.begin() + subpos, str.begin() + subpos + sublen);
return *this;
}
//对字符指针特殊处理
string& string::insert(size_t pos, const char* s) {
insert(begin() + pos, s, s + strlen(s));
return *this;
}
string& string::insert(size_t pos, const char* s, size_t n) {
insert(begin() + pos, s, s + n);
return *this;
}
//
string::iterator string::insert_aux_filln(iterator p, size_t n, value_type c) {
auto newCapacity = getNewCapacity(n);
iterator newStart = dataAllocator::allocate(newCapacity);
iterator newFinish = mySTL::uninitialized_copy(start_, p, newStart);
newFinish = mySTL::uninitialized_fill_n(newFinish, n, c);
auto res = newFinish;
newFinish = mySTL::uninitialized_copy(p, finish_, newFinish);
destroyAndDeallocate();
start_ = newStart;
finish_ = newFinish;
endOfStorage_ = start_ + newCapacity;
return res;
}
//输入pos的insert
string& string::insert(size_t pos, size_t n, char c) {
insert(begin() + pos, n, c);
return *this;
}
//
string::iterator string::insert(iterator p, size_t n, char c) {
auto lengthOfLeft = capacity() - size();
if (n <= lengthOfLeft) {
for (iterator it = finish_ - 1; it >= p; --it) {
*(it + n) = *(it);
}
mySTL::uninitialized_fill_n(p, n, c);
finish_ += n;
return (p + n);
}
else {
return insert_aux_filln(p, n, c);
}
}
//
string::iterator string::insert(iterator p, char c) {
return insert(p, 1, c);
}
string& string::operator+= (const string& str) {
insert(size(), str);
return *this;
}
string& string::operator+= (const char* s) {
insert(size(), s);
return *this;
}
string& string::operator+= (char c) {
insert(end(), c);
return *this;
}
//apend调用+=
string& string::append(const string& str) {
(*this) += str;
return *this;
}
string& string::append(const string& str, size_t subpos, size_t sublen) {
sublen = changeVarWhenEuqalNPOS(sublen, str.size(), subpos);
insert(size(), str, subpos, sublen);
return *this;
}
string& string::append(const char* s) {
(*this) += s;
return *this;
}
string& string::append(const char* s, size_t n) {
insert(size(), s, n);
return *this;
}
string& string::append(size_t n, char c) {
insert(end(), n, c);
return *this;
}
//移走后删除
string::iterator string::erase(iterator first, iterator last) {
size_t lengthOfMove = finish_ - last;
for (auto i = 0; i != lengthOfMove; ++i) {
*(first + i) = *(last + i);
}
dataAllocator::destroy(first + lengthOfMove, finish_);
finish_ = first + lengthOfMove;
return first;
}
//调整范围
string& string::erase(size_t pos, size_t len) {
len = changeVarWhenEuqalNPOS(len, size(), pos);
erase(begin() + pos, begin() + pos + len);
return *this;
}
string::iterator string::erase(iterator p) {
//return erase(p, end());
//bug fix
//2014.12.24
return erase(p, p + 1);
}
// 对各种形态的调整
string& string::replace(size_t pos, size_t len, const string& str) {
return replace(begin() + pos, begin() + pos + len, str.begin(), str.end());
}
string& string::replace(iterator i1, iterator i2, const string& str) {
return replace(i1, i2, str.begin(), str.end());
}
string& string::replace(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) {
sublen = changeVarWhenEuqalNPOS(sublen, str.size(), subpos);
return replace(begin() + pos, begin() + pos + len, str.begin() + subpos, str.begin() + subpos + sublen);
}
string& string::replace(size_t pos, size_t len, const char* s) {
return replace(begin() + pos, begin() + pos + len, s, s + strlen(s));
}
string& string::replace(iterator i1, iterator i2, const char* s) {
return replace(i1, i2, s, s + strlen(s));
}
string& string::replace(iterator i1, iterator i2, size_t n, char c) {
auto ptr = erase(i1, i2);
insert(ptr, n, c);
return *this;
}
string& string::replace(size_t pos, size_t len, const char* s, size_t n) {
return replace(begin() + pos, begin() + pos + len, s, s + n);
}
string& string::replace(iterator i1, iterator i2, const char* s, size_t n) {
return replace(i1, i2, s, s + n);
}
string& string::replace(size_t pos, size_t len, size_t n, char c) {
return replace(begin() + pos, begin() + pos + len, n, c);
}
//查找:居然没用kmp。。。
size_t string::find_aux(const_iterator cit, size_t pos, size_t lengthOfS, size_t cond)const {
size_t i, j;
for (i = pos; i != cond; ++i) {
for (j = 0; j != lengthOfS; ++j) {
if (*(begin() + i + j) != cit[j])
break;
}
if (j == lengthOfS)
return i;
}
return npos;
}
//对字符指针做处理
size_t string::find(const char* s, size_t pos, size_t n) const {
size_t lenghtOfS = strlen(s);
return find_aux(s, pos, n, size());
}
//
size_t string::find(const string& str, size_t pos) const {
size_t lengthOfS = str.size();
if (size() - pos < lengthOfS)
return npos;
return find_aux(str.cbegin(), pos, lengthOfS, size());
}
size_t string::find(const char* s, size_t pos) const {
return find(s, pos, strlen(s));
}
size_t string::find(char c, size_t pos) const {
for (auto cit = cbegin() + pos; cit != cend(); ++cit) {
if (*cit == c)
return cit - cbegin();
}
return npos;
}
size_t string::rfind(char c, size_t pos) const {
pos = changeVarWhenEuqalNPOS(pos, size(), 1);
for (auto cit = cbegin() + pos; cit >= cbegin(); --cit) {
if (*cit == c)
return cit - cbegin();
}
return npos;
}
//反向查找
size_t string::rfind_aux(const_iterator cit, size_t pos, size_t lengthOfS, int cond)const {
int i, j;
for (i = pos + lengthOfS; i >= cond; --i) {
for (j = 0; j != lengthOfS; ++j) {
if (*(begin() + i + j) != cit[j])
break;
}
if (j == lengthOfS)
return i;
}
return npos;
}
//
size_t string::rfind(const string& str, size_t pos) const {
auto lengthOfS = str.size();
pos = changeVarWhenEuqalNPOS(pos, size(), 1);
return rfind_aux(str.begin(), pos, lengthOfS, 0);
}
size_t string::rfind(const char* s, size_t pos) const {
pos = changeVarWhenEuqalNPOS(pos, size(), 1);
return rfind(s, pos, strlen(s));
}
size_t string::rfind(const char* s, size_t pos, size_t n) const {
auto lengthOfS = strlen(s);
return rfind_aux(s, pos, n, 0);
}
int string::compare(const string& str) const {
return compare(0, size(), str, 0, str.size());
}
int string::compare(size_t pos, size_t len, const string& str) const {
return compare(pos, len, str, 0, str.size());
}
int string::compare_aux(size_t pos, size_t len, const_iterator cit, size_t subpos, size_t sublen)const {
size_t i, j;
for (i = 0, j = 0; i != len && j != sublen; ++i, ++j) {
if ((*this)[pos + i] < cit[subpos + j])
return -1;
else if ((*this)[pos + i] > cit[subpos + j])
return 1;
}
if (i == len && j == sublen)
return 0;
else if (i == len)
return -1;
else
return 1;
}
int string::compare(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const {
return compare_aux(pos, len, str.begin(), subpos, sublen);
}
int string::compare(const char* s) const {
return compare(0, size(), s, strlen(s));
}
int string::compare(size_t pos, size_t len, const char* s) const {
return compare(pos, len, s, strlen(s));
}
int string::compare(size_t pos, size_t len, const char* s, size_t n) const {
return compare_aux(pos, len, s, 0, n);
}
size_t string::find_first_of(const string& str, size_t pos) const {
return find_first_of(str.begin(), pos, str.size());
}
size_t string::find_first_of(const char* s, size_t pos) const {
return find_first_of(s, pos, strlen(s));
}
size_t string::find_first_of(const char* s, size_t pos, size_t n) const {
for (size_t i = pos; i != size(); ++i) {
if (isContained((*this)[i], s, s + n))
return i;
}
return npos;
}
size_t string::find_first_of(char c, size_t pos) const {
return find(c, pos);
}
size_t string::find_first_not_of(const string& str, size_t pos) const {
return find_first_not_of(str.begin(), pos, str.size());
}
size_t string::find_first_not_of(const char* s, size_t pos) const {
return find_first_not_of(s, pos, strlen(s));
}
size_t string::find_first_not_of(const char* s, size_t pos, size_t n) const {
for (size_t i = pos; i != size(); ++i) {
if (!isContained((*this)[i], s, s + n))
return i;
}
return npos;
}
size_t string::find_first_not_of(char c, size_t pos) const {
for (size_t i = pos; i != size(); ++i) {
if ((*this)[i] != c)
return i;
}
return npos;
}
size_t string::find_last_of(char c, size_t pos) const {
return rfind(c, pos);
}
size_t string::find_last_not_of(const string& str, size_t pos) const {
pos = changeVarWhenEuqalNPOS(pos, size(), 1);
return find_last_not_of(str.begin(), pos, str.size());
}
size_t string::find_last_not_of(const char* s, size_t pos) const {
pos = changeVarWhenEuqalNPOS(pos, size(), 1);
return find_last_not_of(s, pos, strlen(s));
}
size_t string::find_last_not_of(const char* s, size_t pos, size_t n) const {
for (size_t i = pos; i >= 0; --i) {
if (!isContained((*this)[i], s, s + n))
return i;
}
return npos;
}
size_t string::find_last_not_of(char c, size_t pos) const {
pos = changeVarWhenEuqalNPOS(pos, size(), 1);
for (int i = pos; i >= 0; --i) {
if ((*this)[i] != c)
return i;
}
return npos;
}
//输入输出,基本上是本文件最有营养的部分了
std::ostream& operator <<(std::ostream& os, const string&str) {
for (const auto ch : str) {
os << ch;
}
return os;
}
//
std::istream& operator >> (std::istream& is, string& str) {
char ch;
string::size_type oldSize = str.size(), index = 0;
bool hasPrevBlank = false;//一个没有用的变量
while (is.get(ch)) {//跳过前导空白
if (isblank(ch) || ch == '\n')
hasPrevBlank = true;
else
break;
}
is.putback(ch);
str.clear();
while (is.get(ch)) {
if (ch != EOF && !isblank(ch) && ch != '\n') {
str.push_back(ch);//没到尾继续
}
else
break;
}
return is;
}
//getline录入整行
std::istream& getline(std::istream& is, string& str, char delim) {
char ch;
str.clear();
while (is.get(ch)) {
if (ch == delim)
break;
else
str.push_back(ch);
}
return is;
}
std::istream& getline(std::istream& is, string& str) {
return getline(is, str, '\n');
}
//
string operator+ (const string& lhs, const string& rhs) {
string res(lhs);
return res += rhs;
}
string operator+ (const string& lhs, const char* rhs) {
string res(lhs);
return res += rhs;
}
string operator+ (const char* lhs, const string& rhs) {
string res(lhs);
return res += rhs;
}
string operator+ (const string& lhs, char rhs) {
string res(lhs);
return res += rhs;
}
string operator+ (char lhs, const string& rhs) {
string res(1, lhs);
return res += rhs;
}
//对char*额外处理
bool operator== (const string& lhs, const string& rhs) {
if (lhs.size() == rhs.size()) {
for (auto cit1 = lhs.cbegin(), cit2 = rhs.cbegin();
cit1 != lhs.cend() && cit2 != rhs.cend();
++cit1, ++cit2) {
if (*cit1 != *cit2)
return false;
}
return true;
}
return false;
}
bool operator== (const char* lhs, const string& rhs) {
return rhs == lhs;
}
bool operator== (const string& lhs, const char* rhs) {
size_t len = strlen(rhs);
if (lhs.size() == len) {
const char *p = rhs;
for (string::const_iterator cit = lhs.cbegin();
cit != lhs.cend() && p != rhs + len;
++cit, ++p) {
if (*cit != *p)
return false;
}
return true;
}
return false;
}
bool operator!= (const string& lhs, const string& rhs) {
return !(lhs == rhs);
}
bool operator!= (const char* lhs, const string& rhs) {
return !(lhs == rhs);
}
bool operator!= (const string& lhs, const char* rhs) {
return !(lhs == rhs);
}
bool operator< (const string& lhs, const string& rhs) {
return !(lhs >= rhs);
}
bool operator< (const char* lhs, const string& rhs) {
return !(lhs >= rhs);
}
bool operator< (const string& lhs, const char* rhs) {
return !(lhs >= rhs);
}
namespace {
template<class Iterator1, class Iterator2>
bool lessEqual_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (*first1 < *first2)
return true;
else if (*first1 > *first2)
return false;
}
//逐个判断再比头尾,非常漂亮
if ((first1 == last1 && first2 == last2)// ==
|| (first1 == last1))// <
return true;
else
return false;
}
}
bool operator<= (const string& lhs, const string& rhs) {
return lessEqual_aux(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
}
bool operator<= (const char* lhs, const string& rhs) {
return lessEqual_aux(lhs, lhs + strlen(lhs), rhs.cbegin(), rhs.cend());
}
bool operator<= (const string& lhs, const char* rhs) {
return lessEqual_aux(lhs.cbegin(), lhs.cend(), rhs, rhs + strlen(rhs));
}
bool operator> (const string& lhs, const string& rhs) {
return !(lhs <= rhs);
}
bool operator> (const char* lhs, const string& rhs) {
return !(lhs <= rhs);
}
bool operator> (const string& lhs, const char* rhs) {
return !(lhs <= rhs);
}
namespace {
template<class Iterator1, class Iterator2>
bool greaterEqual_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (*first1 > *first2)
return true;
else if (*first1 < *first2)
return false;
}
if ((first1 == last1 && first2 == last2)// ==
|| (first2 == last2))// >
return true;
else
return false;
}
}
bool operator>= (const string& lhs, const string& rhs) {
return greaterEqual_aux(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
}
bool operator>= (const char* lhs, const string& rhs) {
return greaterEqual_aux(lhs, lhs + strlen(lhs), rhs.cbegin(), rhs.cend());
}
bool operator>= (const string& lhs, const char* rhs) {
return greaterEqual_aux(lhs.cbegin(), lhs.cend(), rhs, rhs + strlen(rhs));
}
void swap(string& x, string& y) {
x.swap(y);
}
//移走数据
void string::moveData(string& str) {
start_ = str.start_;
finish_ = str.finish_;
endOfStorage_ = str.endOfStorage_;
str.start_ = str.finish_ = str.endOfStorage_ = 0;
}
string::size_type string::getNewCapacity(size_type len)const {
size_type oldCapacity = endOfStorage_ - start_;
auto res = mySTL::max(oldCapacity, len);
//size_type newCapacity = (oldCapacity != 0 ? (oldCapacity + res) : 1);
auto newCapacity = oldCapacity + res;
return newCapacity;
}
void string::allocateAndFillN(size_t n, char c) {
start_ = dataAllocator::allocate(n);
finish_ = mySTL::uninitialized_fill_n(start_, n, c);
endOfStorage_ = finish_;
}
void string::string_aux(size_t n, char c, std::true_type) {
allocateAndFillN(n, c);
}
void string::destroyAndDeallocate() {
dataAllocator::destroy(start_, finish_);
dataAllocator::deallocate(start_, endOfStorage_ - start_);
}
bool string::isContained(char ch, const_iterator first, const_iterator last)const {
for (auto cit = first; cit != last; ++cit) {
if (*cit == ch)
return true;
}
return false;
}
size_t string::changeVarWhenEuqalNPOS(size_t var, size_t minuend, size_t minue)const {
return (var == npos ? minuend - minue : var);
}
}