(第九步) STL: stl_string容器实现

stl_string

警告:经过后面的测试,单单string的是没问题,但是后面运用其他容器中时的无法解析命令还是存在问题,直接使用std里的string解决了。望谅解,string有待大改

经过前面其他容器的是学习, string的实现很容易理解,没有什么太大的突出点,平常用到也很多,应该挺熟悉的,也就不多做什么解释,直接copy了代码,进行大致修改,使得能运行。

测试程序也不给了,但是这里测试的时候加载头文件,说我重复定义,把stl_string.h头文件,从test.h移动到test.cpp下才可以实现,有知道的希望可以留个言。

这里实现string是为了后面的二叉搜索树、平衡二叉树等等实现做准备,也可以直接copy着用

也是从这里,序列式的容器差不多告一段落了,之后开始树和关联式容器的学习

stl_string.h

#ifndef _STRING_H_
#define _STRING_H_

#include "../Includes/Allocator.h"
#include "../Includes/ReverseIterator.h"
#include "../Includes/UninitializedFunctions.h"
#include "../Includes/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(); }


		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);

		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_;
		}


		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 = mySTL::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);
	}

	// 小于等于
	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;
	}

	// 大于等于
	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;
	}
}

#include "../Detail/stl_string.impl.h"

#endif

stl_string.impl.h

#ifndef _STRING_IMPL_H_
#define _STRING_IMPL_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;
	}
	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;
	}
	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);
	}
	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);
		//if (n < lenghtOfS)
		//	return npos;
		//return find_aux(s, pos, lenghtOfS, pos + n);
		//bug fix
		//2014.12.24
		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, size() - pos);
		//bug fix
		//2014.12.24
		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;
		//bug fix
		//2014.12.25
		//for (i = pos - lengthOfS; i >= cond; --i){
		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();
		//if (pos - 0 < lengthOfS)
		//	return npos;
		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);
		//if (n < lengthOfS)
		//	return npos;
		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, size() - pos);
		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, size() - pos);
		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 != pos + n; ++i){
		//	if (isContained((*this)[i], s, s + strlen(s)))
		//		return i;
		//}
		//bug fix
		//2014.12.25
		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, size() - pos);
		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, size() - pos);
		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 != pos + n; ++i){
		if (!isContained((*this)[i], s, s + strlen(s)))
		return i;
		}*/
		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(const string& str, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		//return find_last_of(str.begin(), pos, pos + 1);
		return find_last_of(str.begin(), pos, str.size());
	}
	size_t string::find_last_of(const char* s, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		//return find_last_of(s, pos, pos + 1);
		return find_last_of(s, pos, strlen(s));
	}
	size_t string::find_last_of(const char* s, size_t pos, size_t n) const {
		/*for (size_t i = pos, j = 0; i >= 0 && j != n; --i, ++j){
		if (isContained((*this)[i], s, s + strlen(s)))
		return i;
		}*/
		//bug fix
		//2014.12.25
		for (size_t i = pos; i > 0; --i) {
			if (isContained((*this)[i], s, s + n))
				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, size());
		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, pos + 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, j = 0; i >= 0 && j != n; --i, ++j){
		if (!isContained((*this)[i], s, s + strlen(s)))
		return i;
		}*/
		//bug fix
		//2014.12.24
		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;
	}
	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;
	}
	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);
	}

	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);
	}

	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);
	}
}

#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值