📄 flex_string_shell.h
字号:
////////////////////////////////////////////////////////////////////////////////// flex_string// Copyright (c) 2001 by Andrei Alexandrescu// Permission to use, copy, modify, distribute and sell this software for any// purpose is hereby granted without fee, provided that the above copyright// notice appear in all copies and that both that copyright notice and this// permission notice appear in supporting documentation.// The author makes no representations about the// suitability of this software for any purpose. It is provided "as is"// without express or implied warranty.////////////////////////////////////////////////////////////////////////////////#ifndef FLEX_STRING_SHELL_INC_#define FLEX_STRING_SHELL_INC_// $Id: flex_string_shell.h 754 2006-10-17 19:59:11Z syntheticpp $///////////////////////////////////////////////////////////////////////////////// class template flex_string// This file does not include any storage policy headers///////////////////////////////////////////////////////////////////////////////#include <memory>#include <algorithm>#include <functional>#include <cassert>#include <limits>#include <stdexcept>#include "flex_string_details.h"#include <string>// Forward declaration for default storage policytemplate <typename E, class A> class AllocatorStringStorage;template <class T> class mallocator{public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef std::size_t size_type; //typedef unsigned int size_type; //typedef std::ptrdiff_t difference_type; typedef int difference_type; template <class U> struct rebind { typedef mallocator<U> other; }; mallocator() {} mallocator(const mallocator&) {} //template <class U> //mallocator(const mallocator<U>&) {} ~mallocator() {} pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return x; } pointer allocate(size_type n, const_pointer = 0) { using namespace std; void* p = malloc(n * sizeof(T)); if (!p) throw bad_alloc(); return static_cast<pointer>(p); } void deallocate(pointer p, size_type) { using namespace std; free(p); } size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); } void construct(pointer p, const value_type& x) { new(p) value_type(x); } void destroy(pointer p) { p->~value_type(); }private: void operator=(const mallocator&);};template<> class mallocator<void>{ typedef void value_type; typedef void* pointer; typedef const void* const_pointer; template <class U> struct rebind { typedef mallocator<U> other; };};template <class T>inline bool operator==(const mallocator<T>&, const mallocator<T>&) { return true;}template <class T>inline bool operator!=(const mallocator<T>&, const mallocator<T>&) { return false;}template <class Allocator>typename Allocator::pointer Reallocate( Allocator& alloc, typename Allocator::pointer p, typename Allocator::size_type oldObjCount, typename Allocator::size_type newObjCount, void*){ // @@@ not implemented}template <class Allocator>typename Allocator::pointer Reallocate( Allocator& alloc, typename Allocator::pointer p, typename Allocator::size_type oldObjCount, typename Allocator::size_type newObjCount, mallocator<void>*){ // @@@ not implemented}////////////////////////////////////////////////////////////////////////////////// class template flex_string// a std::basic_string compatible implementation // Uses a Storage policy ////////////////////////////////////////////////////////////////////////////////template <typename E, class T = std::char_traits<E>, class A = std::allocator<E>, class Storage = AllocatorStringStorage<E, A> >class flex_string : private Storage{ template <typename Exception> static void Enforce(bool condition, Exception*, const char* msg) { if (!condition) throw Exception(msg); } bool Sane() const { return begin() <= end() && empty() == (size() == 0) && empty() == (begin() == end()) && size() <= max_size() && capacity() <= max_size() && size() <= capacity(); } struct Invariant; friend struct Invariant; struct Invariant {#ifndef NDEBUG Invariant(const flex_string& s) : s_(s) { assert(s_.Sane()); } ~Invariant() { assert(s_.Sane()); } private: const flex_string& s_;#else Invariant(const flex_string&) {} #endif Invariant& operator=(const Invariant&); }; public: // types typedef T traits_type; typedef typename traits_type::char_type value_type; typedef A allocator_type; typedef typename A::size_type size_type; typedef typename A::difference_type difference_type; typedef typename Storage::reference reference; typedef typename A::const_reference const_reference; typedef typename A::pointer pointer; typedef typename A::const_pointer const_pointer; typedef typename Storage::iterator iterator; typedef typename Storage::const_iterator const_iterator; typedef std::reverse_iterator<iterator#ifdef NO_ITERATOR_TRAITS , value_type#endif > reverse_iterator; typedef std::reverse_iterator<const_iterator#ifdef NO_ITERATOR_TRAITS , const value_type #endif > const_reverse_iterator; static const size_type npos; // = size_type(-1)private: static size_type Min(size_type lhs, size_type rhs) { return lhs < rhs ? lhs : rhs; } static size_type Max(size_type lhs, size_type rhs) { return lhs > rhs ? lhs : rhs; } static void Procust(size_type& n, size_type nmax) { if (n > nmax) n = nmax; } public: // 21.3.1 construct/copy/destroy explicit flex_string(const A& a = A()) : Storage(a) {} flex_string(const flex_string& str) : Storage(str) {} flex_string(const flex_string& str, size_type pos, size_type n = npos, const A& a = A()) : Storage(a) { assign(str, pos, n); } flex_string(const value_type* s, const A& a = A()) : Storage(s, traits_type::length(s), a) {} flex_string(const value_type* s, size_type n, const A& a = A()) : Storage(s, n, a) {} flex_string(size_type n, value_type c, const A& a = A()) : Storage(n, c, a) {} template <class InputIterator> flex_string(InputIterator begin, InputIterator end, const A& a = A()) : Storage(a) { assign(begin, end); } ~flex_string() {} flex_string& operator=(const flex_string& str) { Storage& s = *this; s = str; return *this; } flex_string& operator=(const value_type* s) { assign(s); return *this; } flex_string& operator=(value_type c) { assign(1, c); return *this; } // 21.3.2 iterators: iterator begin() { return Storage::begin(); } const_iterator begin() const { return Storage::begin(); } iterator end() { return Storage::end(); } const_iterator end() const { return Storage::end(); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } // 21.3.3 capacity: size_type size() const { return Storage::size(); } size_type length() const { return size(); } size_type max_size() const { return Storage::max_size(); } void resize(size_type n, value_type c) { Storage::resize(n, c); } void resize(size_type n) { resize(n, value_type()); } size_type capacity() const { return Storage::capacity(); } void reserve(size_type res_arg = 0) { Enforce(res_arg <= max_size(), static_cast<std::length_error*>(0), ""); Storage::reserve(res_arg); } void clear() { resize(0); } bool empty() const { return size() == 0; } // 21.3.4 element access: const_reference operator[](size_type pos) const { return *(c_str() + pos); } reference operator[](size_type pos) { return *(begin() + pos); } const_reference at(size_type n) const { Enforce(n <= size(), static_cast<std::out_of_range*>(0), ""); return (*this)[n]; } reference at(size_type n) { Enforce(n < size(), static_cast<std::out_of_range*>(0), ""); return (*this)[n]; } // 21.3.5 modifiers: flex_string& operator+=(const flex_string& str) { return append(str); } flex_string& operator+=(const value_type* s) { return append(s); } flex_string& operator+=(const value_type c) { push_back(c); return *this; } flex_string& append(const flex_string& str) { return append(str.data(), str.length()); } flex_string& append(const flex_string& str, const size_type pos, size_type n) { const size_type sz = str.size(); Enforce(pos <= sz, static_cast<std::out_of_range*>(0), ""); Procust(n, sz - pos); return append(str.data() + pos, n); } flex_string& append(const value_type* s, const size_type n) { Invariant checker(*this); (void) checker; static std::less_equal<const value_type*> le; if (le(&*begin(), s) && le(s, &*end())) // aliasing { const size_type offset = s - &*begin(); Storage::reserve(size() + n); s = &*begin() + offset; } Storage::append(s, s + n); return *this; } flex_string& append(const value_type* s) { return append(s, traits_type::length(s)); } flex_string& append(size_type n, value_type c) { resize(size() + n, c); return *this; } template<class InputIterator> flex_string& append(InputIterator first, InputIterator last) { insert(end(), first, last); return *this; } void push_back(const value_type c) // primitive { const size_type cap = capacity(); if (size() == cap) { reserve(cap << 1u); } Storage::append(&c, &c + 1); } flex_string& assign(const flex_string& str) { if (&str == this) return *this; return assign(str.data(), str.size()); } flex_string& assign(const flex_string& str, const size_type pos,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -