tinystl实现(第二十步:string实现)

2023-11-19

经过长时间的学习终于可以开始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);
	}

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

tinystl实现(第二十步:string实现) 的相关文章

随机推荐

  • GitHub设置头像

    在 GitHub 上随处可见的头像 账户独有的标识 是通过 Gravatar服务显示的 只要使用创建 GitHub 账户时注册的邮箱在 Gravatar 上设置头像 GitHub 的头像就会变成您设置好的样子 http cn gravata
  • 华为OD机试 - 解密犯罪时间(Java)

    题目描述 警察在侦破一个案件时 得到了线人给出的可能犯罪时间 形如 HH MM 表示的时刻 根据警察和线人的约定 为了隐蔽 该时间是修改过的 解密规则为 利用当前出现过的数字 构造下一个距离当前时间最近的时刻 则该时间为可能的犯罪时间 每个
  • 深度学习中的IoU概念理解

    1 什么是IoU Intersection over Union IoU是一种测量在特定数据集中检测相应物体准确度的一个标准 IoU是一个简单的测量标准 只要是在输出中得出一个预测范围 bounding boxex 的任务都可以用IoU来进
  • Delphi中关于资源释放(Free,Relealse,FreeAndNil)

    根据日常编程经验 得出一些Delphi中关于资源释放的体会 假如有对象Obj为TObject类型 1 Obj Free直接释放资源后 调用OnDestroy事件 但是没有将Obj指针值置为Nil 2 Obj Release 等待资源不再使用
  • Kali proxychains

    1 什么是proxychains 在linux系统中有很多软件是不支持代理的 但是proxychains 却可以让不支持代理的软件 也能走代理通道 支持HTTP HTTPS SOCKS4 SOCKS5 等多种代理协议 而且还能配置代理链 可
  • struct和typedef struct的用法和区别

    1 在C和C 里的不同 在c中定义一个结构体类型用typedef typedef struct Student int m Stu 用这种形式定义的时候 在声明结构体变量的时候可用 Stu stu1 这种形式也等同于struct Strde
  • Open3D (C++) 点云添加随机噪声

    Open3D C 点云添加随机噪声 在三维点云数据中 噪声是不可避免的 它可能是由于传感器测量误差 环境因素或其他未知影响造成的 为了模拟这些噪声 我们可以使用 Open3D 中提供的工具将噪声添加到点云数据中 本文将介绍如何使用 Open
  • postgres导入备份出现'无效的命令\N'

    在使用pg dump对数据库进行备份的时候 到出成默认的格式 导致插入数据时 提示无效的命令 N 解决方法 使用custom格式导出 然后用pg restore导入 导出 pg dump F custom U username d dbna
  • 下拉框,文本域和文件域

    p 国家 p
  • VS中报错IntelliSense: argument of type "void *" is incompatible with parameter of type "const char *"

    在用VS编写C 程序的时候 遇到这样的问题IntelliSense argument of type void is incompatible with parameter of type const char 但是给的例程确实传入参数就是
  • ListView的操作

    转自http blog sina com cn s blog 43eb83b90100mhrs html 这一篇对我也不错http blog csdn net xiaohan2826 article details 8603015 小白叔叔
  • PCIe 5.0 规范最新更新及PCIe 5.0测试挑战​

    PCIe 5 0 基础规范 v1 0 在 2019 年年中发布以后 Synopsys 发布了世界上第一款支持 PCIe 5 0 基础规范 v1 0 的 IP 并展示了在其实验室验证发射机 接收机 Tx Rx 性能的环境 Intel 也在 2
  • 基于MATLAB手写体数字识别程序设计

    基于MATLAB手写体数字识别程序设计 手写体识别由于其实用性 一直处于研究进步的阶段 本文主要针对的是对0 9十个手写数字体脱机识别 在Matlab中对样本部分为进行16特征的提取 分别采用最小距离法 最近邻法 KNN法以及BP神经网络算
  • UNIX网络编程-recv、send、read、write之间的联系与区别

    原文链接 http www cnblogs com mhscn p 3911284 html include
  • 在centos7中安装docker

    一 前置条件 64 bit 系统 kernel 3 10 CentOS 7 1 检查 使用 uname r 检查 kernel 版本 uname r 3 10 0 327 el7 x86 64 二 安装 yum安装方式 1 使用 sudo
  • Hdfs下载报错,(null) entry in command string: null chmod 0644问题的解决

    解决 缺少系统文件hadoop dll文件 1 下载hadoop dll文件 2 把文件放在 windows system32目录下
  • python 根据年份,月份信息显示此月份天数

    1 普通方法 2 year int input 请输入年份 3 month int input 请输入月份 1 12 4 if month 2 5 if year 4 0 and year 100 0
  • Qt QtCreator 所有版本官方下载地址

    直接跳过输入账号 选择所需版本 废话不多说 直接上链接 1 所有版本QT下载地址 http download qt io archive qt 2 所有Qt Creator下载地址 http download qt io archive q
  • Unity知识点详解面试题大全

    1 请简述值类型与引用类型的区别 答 区别 1 值类型存储在内存栈中 引用类型数据存储在内存堆中 而内存单元中存放的是堆中存放的地址 2 值类型存取快 引用类型存取慢 3 值类型表示实际数据 引用类型表示指向存储在内存堆中的数据的指针和引用
  • tinystl实现(第二十步:string实现)

    经过长时间的学习终于可以开始tinystl的仿 chao 写工作了 本文参考了这位大神的github 坦白讲我只是补充了注释 因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验 所以只能这样做 不过相信能够有助于大家的学习