zoukankan      html  css  js  c++  java
  • 从零开始写STL-string类型

    	class string
    	{
    	public:
    		typedef size_t size_type;
    		typedef char* iterator;
    		typedef char value_type;
    	private:
    		char *start, *end_of_storage, *End;
    		std::allocator<char> data_allocator;
    		void DeallocateAndDestory()
    		{
    			data_allocator.deallocate(start, end_of_storage - start);
    		}
    		//重新构造元素 
    		void reallocate(size_t new_size = 0)
    		{
    			size_t old_size = size();
    			if (new_size == 0)
    				new_size = size() ? 2 * size() : 1;
    			char* new_start = data_allocator.allocate(new_size);
    			std::copy(start, start + size(), new_start);
    			DeallocateAndDestory();
    			start = new_start;
    			End = new_start + old_size;
    			end_of_storage = new_start + new_size;
    		}
    		//移动构造元素
    		/*void reallocate()
    		{
    		int old_size = size();
    		int new_size = size() ? 2 * size() : 1;
    		char* new_start = data_allocator.allocate(new_size);
    		char* pos = new_start;
    		char* old_pos = start;
    		for (int i = 0; i < old_size; i++)
    		data_allocator.construct(pos++, std::move(*old_pos)), old_pos++;
    		data_allocator.deallocate(start, old_size);
    		start = new_start;
    		End = new_start + old_size;
    		end_of_storage = new_start + new_size;
    		}*/
    	public:
    		//debug
    		void print()
    		{
    			for (auto it = start; it != End; it++)
    				std::cout << *it;
    			std::cout << std::endl;
    		}
    		//Construct
    		string()
    		{
    			start = end_of_storage = End = nullptr;
    		}
    		string(const string& rhs)
    		{
    			start = end_of_storage = End = nullptr;
    			append(rhs);
    		}
    		string(string&& rhs)noexcept :start(rhs.start), end_of_storage(rhs.end_of_storage), End(rhs.End)
    		{
    			rhs.start = rhs.end_of_storage = rhs.End = nullptr;
    		}
    		string(const char* s)
    		{
    			if (s == nullptr)
    				string();
    			else
    			{
    				int cnt = 0;
    				for (; s[cnt] != ''; cnt++) {}
    				start = data_allocator.allocate(cnt);
    				std::uninitialized_copy_n(s, cnt, start);
    				end_of_storage = End = start + cnt;
    			}
    		}
    		string(size_type n, char c)
    		{
    			start = data_allocator.allocate(n);
    			std::uninitialized_fill_n(start, n, c);
    			end_of_storage = End = start + n;
    		}
    		string(const char* s, size_t n)
    		{
    			start = data_allocator.allocate(n);
    			std::uninitialized_copy_n(s, n, start);
    			End = end_of_storage = start + n;
    		}
    		~string()
    		{
    			DeallocateAndDestory();
    		}
    		//Iterator
    		const iterator begin() const
    		{
    			return start;
    		}
    
    		const iterator end() const
    		{
    			return End;
    		}
    
    		iterator begin()
    		{
    			return start;
    		}
    		iterator end()
    		{
    			return End;
    		}
    
    		//Capacity
    		void clear()
    		{
    			DeallocateAndDestory();
    			End = start = end_of_storage = nullptr;
    		}
    		bool empty()const
    		{
    			return (start == End);
    		}
    		const size_type size() const
    		{
    			return End - start;
    		}
    		const size_type length() const
    		{
    			return size();
    		}
    		const size_type capacity() const
    		{
    			return end_of_storage - start;
    		}
    		void resize(size_type n)
    		{
    			resize(n, value_type());
    		}
    		void resize(size_type n, const value_type &val)
    		{
    			if (n <= size())
    			{
    				End = start + n;
    			}
    			else
    			{
    				append(string(n - size(), val));
    			}
    		}
    		void reserve(size_type res_arg = 0)
    		{
    			if (res_arg + size() < capacity()) return;
    			reallocate(res_arg + size());
    		}
    		//Modifiers
    		value_type& operator[](size_type index)
    		{
    			if (index < 0 || index >= size())
    			{
    				std::cerr << "index out of range!" << std::endl;
    				std::exit(1);
    			}
    			else
    			{
    				return *(start + index);
    			}
    		}
    		value_type& front()
    		{
    			return *start;
    		}
    		value_type& back()
    		{
    			auto tmp = end();
    			return *(--tmp);
    		}
    		void push_back(const value_type& val)
    		{
    			if (size() == capacity())
    				reallocate();
    			*End = val;
    			End++;
    		}
    		void pop_back()
    		{
    			if (empty())
    			{
    				std::cerr << "Error : pop_back() on empty String!" << std::endl;
    				exit(1);
    			}
    			End--;
    		}
    		void swap(string& rhs)
    		{
    			std::swap(start, rhs.start);
    			std::swap(end_of_storage, rhs.end_of_storage);
    			std::swap(End, rhs.End);
    		}
    		void append(const string& rhs)
    		{
    			if (rhs.empty()) return;
    			if (capacity()<size() + rhs.size()) reallocate(size() + rhs.size());
    			std::copy(rhs.start, rhs.end_of_storage, End);
    			End += rhs.size();
    		}
    		void append(const char* s)
    		{
    			if (s == nullptr) return;
    			size_t cnt = 0;
    			for (; s[cnt] != ''; cnt++) {}
    			if (capacity() < size() + cnt)	reallocate(size() + cnt);
    			std::uninitialized_copy_n(s, cnt, End);
    			End += cnt;
    		}
    		void append(const char* s, size_t l, size_t r)
    		{
    			if (r <= l ) return;
    			if (s == nullptr) return;
    			if (capacity()<size() + r - l - 1) reallocate(size() + r - l);
    			std::uninitialized_copy_n(s + l, r - l, End);
    			End += r - l;
    		}
    		string& operator+=(const char c)
    		{
    			(*this).push_back(c);
    			return *this;
    		}
    		string& operator+=(const string& rhs)
    		{
    			(*this).append(rhs);
    			return *this;
    		}
    		string operator+(const string& rhs)
    		{
    			string tmp(*this);
    			return tmp += rhs;
    		}
    		string& operator=(const string& str)
    		{
    			return assign(str);
    		}
    		string& operator=(const char* s)
    		{
    			return assign(string(s));
    		}
    		string& operator=(char c)
    		{
    			return assign(string((size_type)1, c));
    		}
    		string& assign(const string& str)
    		{
    			clear();
    			append(str);
    			return (*this);
    		}
    		string& assign(const char* s)
    		{
    			clear();
    			if (s == nullptr) return *this;
    			size_t cnt = 0;
    			while (s[cnt] != '') cnt++;
    			start = data_allocator.allocate(cnt);
    			End = std::uninitialized_copy_n(s, cnt, start);
    			end_of_storage += cnt;
    		}
    		string& assign(size_type n, char c)
    		{
    			clear();
    			if (n == 0) return *this;
    			start = data_allocator.allocate(n);
    			End = end_of_storage = std::uninitialized_fill_n(start, n, c);
    		}
    		string& insert(size_type pos, const string& rhs)
    		{
    			pos = std::min(size(), pos);
    			size_type new_size = size() + rhs.size();
    			iterator new_start = data_allocator.allocate(new_size);
    			std::copy(start, start + pos, new_start);
    			std::copy(rhs.start, rhs.End, new_start + pos);
    			std::copy(start + pos, End, new_start + pos + rhs.size());
    			start = new_start;
    			end_of_storage = End = new_size + new_start;
    			return *this;
    		}
    		string& insert(size_type pos, const char* s, size_type n)
    		{
    			return insert(pos, string(s, n));
    		}
    		string& insert(size_type pos, const char* s)
    		{
    			return insert(pos, string(s));
    		}
    		iterator insert(iterator pos, const value_type& val)
    		{
    			size_type index = pos - start;
    			if (size() == capacity())
    				reallocate();
    			pos = start + index;
    			if (pos > end()) pos = end();
    			std::copy(pos, End, pos + 1);
    			(*pos) = val;
    			End++;
    			return pos;
    		}
    		string& insert(size_type pos, size_type num, const value_type& val)
    		{
    			return insert(pos, string(num, val));
    		}
    		string& insert(iterator pos, size_type num, const value_type& val)
    		{
    			return insert(pos - start, string(num, val));
    		}
    		string& erase(size_type pos, size_type n)
    		{
    			std::copy(pos + n + start, End, start + pos);
    			End = End - n;
    			return *this;
    		}
    		iterator erase(iterator pos)
    		{
    			std::copy(pos + 1, End, pos);
    			End--;
    			return pos;
    		}
    		iterator erase(iterator first, iterator last)
    		{
    			std::copy(last, End, first);
    			End = End - (last - first);
    			return first;
    		}
    		string& replace(size_t pos, size_t n, const string& str)
    		{
    			erase(pos, n);
    			insert(pos, str);
    			return *this;
    		}
    		string& replace(iterator i1, iterator i2, const string& str)
    		{
    			insert(erase(i1, i2) - start, str);
    			return *this;
    		}
    		const char* c_str() const
    		{
    			if (empty()) return "";
    			char* ret = new char[End - start + 1];
    			std::uninitialized_copy(start, End, ret);
    			ret[End - start] = '';
    			return ret;
    		}
    		bool operator == (const string& rhs)
    		{
    			if (size() != rhs.size())
    				return false;
    			else
    			{
    				for (auto i = start, j = rhs.start; i != End; i++, j++)
    				{
    					if ((*i) != (*j))
    						return false;
    				}
    				return true;
    			}
    		}
    		bool operator == (const string& rhs) const
    		{
    			if (size() != rhs.size())
    				return false;
    			else
    			{
    				for (auto i = start, j = rhs.start; i != End; i++, j++)
    				{
    					if ((*i) != (*j))
    						return false;
    				}
    				return true;
    			}
    		}
    		int compare(const string& rhs)
    		{
    			iterator i = start, j = rhs.start;
    			while (i != End && j != rhs.End)
    			{
    				if ((*i) > (*j))
    					return 1;
    				else if ((*i) < (*j))
    					return -1;
    				else
    					i++, j++;
    			}
    			if (i == End&&j == rhs.End)
    				return 0;
    			else if (i == End)
    				return -1;
    			else
    				return 1;
    		}
    		size_type copy(char* s, size_type n, size_type pos = 0) const
    		{
    			if (pos + n >= size())
    			{
    				std::cerr << "out of range" << std::endl;
    				std::exit(1);
    			}
    			std::uninitialized_copy_n(start + pos, n, s);
    			return n;
    		}
    		size_t find(const string& str, size_t pos = 0) const
    		{
    			if (size() - pos < str.size())
    				return (size_type)(-1);
    			for (auto it = start + pos; it != End; it++)
    			{
    				auto i = it, j = str.start;
    				while (j<str.End && *i == *j)
    					i++, j++;
    				if (j == str.End)
    					return it - start;
    			}
    			return (size_type)(-1);
    		}
    		size_t find(const char* s, size_t pos, size_t n) const
    		{
    			return find(string(s, n), pos);
    		}
    		size_t find(const char* s, size_t pos = 0) const
    		{
    			return find(string(s), pos);
    		}
    		size_t find(char c, size_t pos = 0) const
    		{
    			if (empty())
    				return size_type(-1);
    			else
    			{
    				for (auto it = start; it != End; it++)
    					if (*it == c)
    						return it - start;
    				return size_type(-1);
    			}
    		}
    		string substr(size_t pos = 0, size_t n = 0)
    		{
    			return string(start + pos, n);
    		}
    		size_t rfind(string& rhs, size_t pos = 0)
    		{
    			if (pos == 0) pos = size();
    			for (auto it = std::min(start + pos, End - 1); it != start - 1; it--)
    			{
    				size_t i;
    				for (i = 0; i < rhs.size();)
    					if (rhs[i] == *(it + i))
    						i++;
    					else
    						break;
    				if (i == rhs.size())
    					return it - start;
    			}
    			return size_t(-1);
    		}
    		size_t rfind(const char& c, size_t pos = 0)
    		{
    			if (pos == 0) pos = size();
    			for (auto it = std::min(End - 1, start + pos); it != start; it--)
    			{
    				if (*it == c)
    					return it - start;
    			}
    			return size_t(-1);
    		}
    		size_t rfind(const char* str)
    		{
    			return rfind(string(str));
    		}
    		size_t find_first_of(const string& rhs, size_t pos = 0)
    		{
    			for (auto it = start + pos; it != End; it++)
    			{
    				auto i = rhs.start;
    				while (i != rhs.End)
    				{
    					if (*i == *it)
    						break;
    					i++;
    				}
    				if (i != rhs.End)
    					return it - start;
    			}
    			return (size_t)-1;
    		}
    		size_t find_first_of(const char& c, size_t pos = 0)
    		{
    			for (auto it = start + pos; it != End; it++)
    			{
    				if (*it == c)
    					return it - start;
    			}
    			return (size_t)-1;
    		}
    		size_t find_last_of(const char &c, size_t pos = 0)
    		{
    			if (pos == 0) pos = size();
    			for (auto it = pos + start; it != start - 1; it--)
    				if (*it == c)
    					return it - start;
    			return (size_t)-1;
    		}
    		size_t find_last_of(const char* str, size_t pos, size_t len)
    		{
    			size_t l = 0;
    			for (size_t i = 0; str[i] != ''; i++)
    				l++;
    			for (auto it = start + pos; it != start + pos - len; it--)
    			{
    				size_t i;
    				for (i = 0; str[i] != ''; i++)
    					if (str[i] == *it)
    						break;
    				if (str[i] != '') return it - start;
    			}
    			return size_t(-1);
    		}
    		size_t find_last_of(const string& rhs, size_t pos)
    		{
    			for (auto it = start + pos; it != start - 1; it--)
    			{
    				size_t i = 0;
    				while (rhs.start + i != rhs.End)
    					if (*it == *(start + i))
    						break;
    					else
    						i++;
    				if (rhs.size() != i)	return it - start;
    			}
    			return size_t(-1);
    		}
    		size_t find_first_not_of(const string& rhs)
    		{
    			for (auto it = start; it != End; it++)
    			{
    				size_t i = 0;
    				while (i < rhs.size())
    					if (*(rhs.start + i) == *it)
    						break;
    					else
    						i++;
    				if (i == rhs.size()) return it - start;
    			}
    			return size_t(-1);
    		}
    		size_t find_last_not_of(const string& rhs, size_t pos)
    		{
    			for (auto it = start + pos; it != start - 1; it--)
    			{
    				size_t i = 0;
    				while (i < rhs.size())
    					if (*(rhs.start + i) == *it)
    						break;
    					else
    						i++;
    				if (i == rhs.size()) return it - start;
    			}
    			return size_t(-1);
    		}
    		bool operator!=(const string& rhs)
    		{
    			return !(*this == rhs);
    		}
    		bool operator>(const string& rhs)
    		{
    			return compare(rhs) > 0;
    		}
    		bool operator>=(const string& rhs)
    		{
    			return compare(rhs) >= 0;
    		}
    		bool operator<(const string& rhs)
    		{
    			return compare(rhs) < 0;
    		}
    		bool operator<=(const string& rhs)
    		{
    			return compare(rhs) <= 0;
    		}
    	};
    	std::ostream& operator<<(std::ostream& os, const ministl::string& rhs) 
    	{
    		os << rhs.c_str();
    		return os;
    	}
    
    	size_t hash_value(const string& val)
    	{
    		const size_t _FNV_offset_basis = 2166136261U;
    		const size_t _FNV_prime = 16777619U;
    		size_t ans = _FNV_offset_basis;
    		for (auto it = val.begin(); it != val.end(); it++)
    		{
    			ans ^= *it;
    			ans *= _FNV_prime;
    		}
    		return ans;
    	}
    
    }
    
  • 相关阅读:
    获取指定包下所有自定义注解
    Java中的24种设计模式与7大原则
    学习 Spring Boot:(二十九)Spring Boot Junit 单元测试
    学习Spring Boot:(二十八)Spring Security 权限认证
    学习Spring Boot:(二十七)Spring Boot 2.0 中使用 Actuator
    学习Spring Boot:(二十六)使用 RabbitMQ 消息队列
    学习Spring Boot:(二十五)使用 Redis 实现数据缓存
    学习Spring Boot:(二十四)多数据源配置与使用
    学习Spring Boot:(二十三)Spring Boot 中使用 Docker
    学习Spring Boot:(二十二)使用 AOP
  • 原文地址:https://www.cnblogs.com/joeylee97/p/8877252.html
Copyright © 2011-2022 走看看