文章标题 SGI的base_string解析
来源:互联网 发布:cydia添加源网络错误 编辑:程序博客网 时间:2024/06/15 10:40
SGI的base_string解析
首先介绍一下SGI的base_string。我用的版本sgi-stl-2.91.57,base_string有两个文件一个std/bastring.h一个std/bastring.cc。base_string使用引用计数节约内存的消耗,这也使得编程变得麻烦一些。base_string内有一个内部类Rep,整个base_string 只有一个静态的Rep成员(用于空字符串)和一个dat(base_string实际字符内存的首地址),对于非空字符串base_string使用隐藏的Rep来实现(在构造base_string时实际上的内存为sizeof(Rep)+base_string的字符容量,也就是Rep数据成员之后就是dat指向的地址)Rep的数据成员是len、res、ref 、selfish(base_string的长度、容量、引用计数、是否为私有标记)<我不懂replace函数为什么不用有的不需要重新分配内存呢?有会的给我讲讲啊!!!>
1. 首先看一下base_string的模板的参数
template <class charT, class traits = string_char_traits<charT>, class Allocator = alloc >class basic_string{//...}
关于Alloc这里就不说了,string_char_traits是一个模板,他有两个特化版本参数分别为char和wchar_t。再看base_string有必要看看string_char_traits。因为他用到了string_char_traits里的一些函数。代码很简单直接就能看懂
#ifndef __STRING_CHAR_TRAITS__#define __STRING_CHAR_TRAITS__#ifdef __GNUG__// For string_char_traits <char>#pragma interface "std/straits.h"#endif#include <cstddef>extern "C++" {template <class charT>struct string_char_traits { typedef charT char_type; // for users to acquire the basic character type // constraints static void assign (char_type& c1, const char_type& c2) { c1 = c2; } static bool eq (const char_type& c1, const char_type& c2) { return (c1 == c2); } static bool ne (const char_type& c1, const char_type& c2) { return !(c1 == c2); } static bool lt (const char_type& c1, const char_type& c2) { return (c1 < c2); } static char_type eos () { return char_type(); } // the null character static bool is_del(char_type a) { return 0; } // characteristic function for delimiters of charT // speed-up functions static int compare (const char_type* s1, const char_type* s2, size_t n) { size_t i; for (i = 0; i < n; ++i) if (ne (s1[i], s2[i])) return lt (s1[i], s2[i]) ? -1 : 1; return 0; } static size_t length (const char_type* s) { size_t l = 0; while (ne (*s++, eos ())) ++l; return l; } static char_type* copy (char_type* s1, const char_type* s2, size_t n) { for (; n--; ) assign (s1[n], s2[n]); return s1; } static char_type* move (char_type* s1, const char_type* s2, size_t n) { char_type a[n]; size_t i; for (i = 0; i < n; ++i) assign (a[i], s2[i]); for (i = 0; i < n; ++i) assign (s1[i], a[i]); return s1; } static char_type* set (char_type* s1, const char_type& c, size_t n) { for (; n--; ) assign (s1[n], c); return s1; }};class istream;class ostream;#include <cctype>#include <cstring>struct string_char_traits <char> { typedef char char_type; static void assign (char_type& c1, const char_type& c2) { c1 = c2; } static bool eq (const char_type & c1, const char_type& c2) { return (c1 == c2); } static bool ne (const char_type& c1, const char_type& c2) { return (c1 != c2); } static bool lt (const char_type& c1, const char_type& c2) { return (c1 < c2); } static char_type eos () { return 0; } static bool is_del(char_type a) { return isspace(a); } static int compare (const char_type* s1, const char_type* s2, size_t n) { return memcmp (s1, s2, n); } static size_t length (const char_type* s) { return strlen (s); } static char_type* copy (char_type* s1, const char_type* s2, size_t n) { return (char_type*) memcpy (s1, s2, n); } static char_type* move (char_type* s1, const char_type* s2, size_t n) { return (char_type*) memmove (s1, s2, n); } static char_type* set (char_type* s1, const char_type& c, size_t n) { return (char_type*) memset (s1, c, n); }};#if 0#include <cwctype>struct string_char_traits <wchar_t> { typedef wchar_t char_type; static void assign (char_type& c1, const char_type& c2) { c1 = c2; } static bool eq (const char_type & c1, const char_type& c2) { return (c1 == c2); } static bool ne (const char_type& c1, const char_type& c2) { return (c1 != c2); } static bool lt (const char_type& c1, const char_type& c2) { return (c1 < c2); } static char_type eos () { return 0; } static bool is_del(char_type a) { return iswspace(a); } static int compare (const char_type* s1, const char_type* s2, size_t n) { return wmemcmp (s1, s2, n); } static size_t length (const char_type* s) { return wcslen (s); } static char_type* copy (char_type* s1, const char_type* s2, size_t n) { return wmemcpy (s1, s2, n); } static char_type* set (char_type* s1, const char_type& c, size_t n) { return wmemset (s1, c, n); }};#endif} // extern "C++"#endif
- base-string的头文件
#ifndef __BASTRING__#define __BASTRING__#ifdef __GNUG__#pragma interface#endif#include <cstddef>#include <std/straits.h>// NOTE : This does NOT conform to the draft standard and is likely to change#include <alloc.h>extern "C++" {class istream; class ostream;#include <iterator>#ifdef __STL_USE_EXCEPTIONS//外部函数声明extern void __out_of_range (const char *);extern void __length_error (const char *);//这两个宏用于判断cond; cond必须要能转化为bool类型//如果cond为真则调用对应的函数#define OUTOFRANGE(cond) \ do { if (cond) __out_of_range (#cond); } while (0)#define LENGTHERROR(cond) \ do { if (cond) __length_error (#cond); } while (0)#else#include <cassert>#define OUTOFRANGE(cond) assert (!(cond))#define LENGTHERROR(cond) assert (!(cond))#endif//注意这里的 string_char_traits alloc template <class charT, class traits = string_char_traits<charT>, class Allocator = alloc >class basic_string{private: //内部类 struct Rep { size_t len, res, ref;//string的字符长度、容量、引用技术 bool selfish;//是否为私有的标记 charT* data () { return reinterpret_cast<charT *>(this + 1); }//返回string的字符首地址 相当于&(*this)+sizeof(Rep) charT& operator[] (size_t s) { return data () [s]; }//返回string的第s+1个字符 //如果为私有则返回clone() ,否则增加引用计数、返回string元素首地址 charT* grab () { if (selfish) return clone (); ++ref; return data (); } void release () { if (--ref == 0) delete this; } //重载operator new(这里不是placement new),而是分配sizeof(Rep)+string的字符所需要的字节数 inline static void * operator new (size_t, size_t); //收回分配的内存 inline static void operator delete (void *); inline static Rep* create (size_t); charT* clone (); inline void copy (size_t, const charT *, size_t); inline void move (size_t, const charT *, size_t); inline void set (size_t, const charT, size_t); inline static bool excess_slop (size_t, size_t); inline static size_t frob_size (size_t); private: Rep &operator= (const Rep &);//禁止复制操作符 };public:// types: typedef traits traits_type; typedef typename traits::char_type value_type; typedef Allocator allocator_type; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef charT& reference; typedef const charT& const_reference; typedef charT* pointer; typedef const charT* const_pointer; typedef pointer iterator;//这里看出迭代器只是char*或wchar_t* typedef const_pointer const_iterator; typedef ::reverse_iterator<iterator> reverse_iterator; typedef ::reverse_iterator<const_iterator> const_reverse_iterator; static const size_type npos = static_cast<size_type>(-1);private: //由Rep的data()知道这里是Rep的首地址 Rep *rep() const { return reinterpret_cast<Rep *>(dat)-1; } void repup (Rep *p) { rep ()->release (); dat = p->data (); }public: const charT* data () const { return rep ()->data(); } size_type length () const { return rep ()->len; } size_type size () const { return rep ()->len; } size_type capacity () const { return rep ()->res; } size_type max_size () const { return (npos - 1)/sizeof (charT); } // XXX bool empty () const { return size () == 0; }// _lib.string.cons_ construct/copy/destroy: basic_string& operator= (const basic_string& str) { if (&str != this) { rep ()->release (); dat = str.rep ()->grab (); } return *this; } //构造函数 explicit basic_string (): dat (nilRep.grab ()) { } basic_string (const basic_string& str): dat (str.rep ()->grab ()) { } basic_string (const basic_string& str, size_type pos, size_type n = npos) : dat (nilRep.grab ()) { assign (str, pos, n); } basic_string (const charT* s, size_type n) : dat (nilRep.grab ()) { assign (s, n); } basic_string (const charT* s) : dat (nilRep.grab ()) { assign (s); } basic_string (size_type n, charT c) : dat (nilRep.grab ()) { assign (n, c); }#ifdef __STL_MEMBER_TEMPLATES template<class InputIterator> basic_string(InputIterator begin, InputIterator end)#else basic_string(const_iterator begin, const_iterator end)#endif : dat (nilRep.grab ()) { assign (begin, end); } //析构函数 ~basic_string () { rep ()->release (); } //这里看出交换string只是交换dat数据成员,避免大量的复制 void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; } //append函数 调用replace实现 basic_string& append (const basic_string& str, size_type pos = 0, size_type n = npos) { return replace (length (), 0, str, pos, n); } basic_string& append (const charT* s, size_type n) { return replace (length (), 0, s, n); } basic_string& append (const charT* s) { return append (s, traits::length (s)); } basic_string& append (size_type n, charT c) { return replace (length (), 0, n, c); }#ifdef __STL_MEMBER_TEMPLATES template<class InputIterator> basic_string& append(InputIterator first, InputIterator last)#else basic_string& append(const_iterator first, const_iterator last)#endif { return replace (iend (), iend (), first, last); } //assign函数 调用replace实现 basic_string& assign (const basic_string& str, size_type pos = 0, size_type n = npos) { return replace (0, npos, str, pos, n); } basic_string& assign (const charT* s, size_type n) { return replace (0, npos, s, n); } basic_string& assign (const charT* s) { return assign (s, traits::length (s)); } basic_string& assign (size_type n, charT c) { return replace (0, npos, n, c); }#ifdef __STL_MEMBER_TEMPLATES template<class InputIterator> basic_string& assign(InputIterator first, InputIterator last)#else basic_string& assign(const_iterator first, const_iterator last)#endif { return replace (ibegin (), iend (), first, last); } basic_string& operator= (const charT* s) { return assign (s); } basic_string& operator= (charT c) { return assign (1, c); } basic_string& operator+= (const basic_string& rhs) { return append (rhs); } basic_string& operator+= (const charT* s) { return append (s); } basic_string& operator+= (charT c) { return append (1, c); } basic_string& insert (size_type pos1, const basic_string& str, size_type pos2 = 0, size_type n = npos) { return replace (pos1, 0, str, pos2, n); } basic_string& insert (size_type pos, const charT* s, size_type n) { return replace (pos, 0, s, n); } basic_string& insert (size_type pos, const charT* s) { return insert (pos, s, traits::length (s)); } basic_string& insert (size_type pos, size_type n, charT c) { return replace (pos, 0, n, c); } iterator insert(iterator p, charT c) { size_type __o = p - ibegin (); insert (p - ibegin (), 1, c); selfish (); return ibegin () + __o; } iterator insert(iterator p, size_type n, charT c) { size_type __o = p - ibegin (); insert (p - ibegin (), n, c); selfish (); return ibegin () + __o; }#ifdef __STL_MEMBER_TEMPLATES template<class InputIterator> void insert(iterator p, InputIterator first, InputIterator last)#else void insert(iterator p, const_iterator first, const_iterator last)#endif { replace (p, p, first, last); } basic_string& erase (size_type pos = 0, size_type n = npos) { return replace (pos, n, (size_type)0, (charT)0); } iterator erase(iterator p) { size_type __o = p - begin(); replace (__o, 1, (size_type)0, (charT)0); selfish (); return ibegin() + __o; } iterator erase(iterator f, iterator l) { size_type __o = f - ibegin(); replace (__o, l-f, (size_type)0, (charT)0);selfish (); return ibegin() + __o; } basic_string& replace (size_type pos1, size_type n1, const basic_string& str, size_type pos2 = 0, size_type n2 = npos); basic_string& replace (size_type pos, size_type n1, const charT* s, size_type n2); basic_string& replace (size_type pos, size_type n1, const charT* s) { return replace (pos, n1, s, traits::length (s)); } basic_string& replace (size_type pos, size_type n1, size_type n2, charT c); basic_string& replace (size_type pos, size_type n, charT c) { return replace (pos, n, 1, c); } basic_string& replace (iterator i1, iterator i2, const basic_string& str) { return replace (i1 - ibegin (), i2 - i1, str); } basic_string& replace (iterator i1, iterator i2, const charT* s, size_type n) { return replace (i1 - ibegin (), i2 - i1, s, n); } basic_string& replace (iterator i1, iterator i2, const charT* s) { return replace (i1 - ibegin (), i2 - i1, s); } basic_string& replace (iterator i1, iterator i2, size_type n, charT c) { return replace (i1 - ibegin (), i2 - i1, n, c); }#ifdef __STL_MEMBER_TEMPLATES template<class InputIterator> basic_string& replace(iterator i1, iterator i2, InputIterator j1, InputIterator j2);#else basic_string& replace(iterator i1, iterator i2, const_iterator j1, const_iterator j2);#endifprivate: //返回char() 或 wchar_t() static charT eos () { return traits::eos (); } void unique () { if (rep ()->ref > 1) alloc (length (), true); } void selfish () { unique (); rep ()->selfish = true; }//很重要的函数public: charT operator[] (size_type pos) const { if (pos == length ()) return eos (); return data ()[pos];//不明白为什么不用dat } //返回reference所以需要selfish() reference operator[] (size_type pos) { selfish (); return (*rep ())[pos]; }//注意上面的data()、这里的*rep()、下面的*this //这里有两种情况:1、当ref = 1 时三个应该是一样的 //2、当ref > 1时 selfish() -> unique()当ref>1时 -> alloc()重新分配内存 -> repup()用于更新dat //(*rep ())[pos]会调用Rep::operator []哪里最后就会用到更新的dat reference at (size_type pos) { OUTOFRANGE (pos >= length ()); return (*this)[pos];//调用上面的因为第一个为const,所以这里不需要selfish() } const_reference at (size_type pos) const { OUTOFRANGE (pos >= length ()); return data ()[pos]; }private: void terminate () const//应该就是给string最后一个字符的后面赋值为cahr() 或 wchar_t() //basic_string内部字符串的有效范围是[0, length) // 这里仅仅是在字符串的外面修改了一个“本来随机”的字符串为“结尾符”, // 并没有修改原本有效的数据,也没有修改字符串的有效长度! { traits::assign ((*rep ())[length ()], eos ()); }public: const charT* c_str () const//返回C的字符串 { if (length () == 0) return ""; terminate (); return data (); } void resize (size_type n, charT c); void resize (size_type n) { resize (n, eos ()); } void reserve (size_type) { } size_type copy (charT* s, size_type n, size_type pos = 0) const; size_type find (const basic_string& str, size_type pos = 0) const { return find (str.data(), pos, str.length()); } size_type find (const charT* s, size_type pos, size_type n) const; size_type find (const charT* s, size_type pos = 0) const { return find (s, pos, traits::length (s)); } size_type find (charT c, size_type pos = 0) const; size_type rfind (const basic_string& str, size_type pos = npos) const { return rfind (str.data(), pos, str.length()); } size_type rfind (const charT* s, size_type pos, size_type n) const; size_type rfind (const charT* s, size_type pos = npos) const { return rfind (s, pos, traits::length (s)); } size_type rfind (charT c, size_type pos = npos) const; size_type find_first_of (const basic_string& str, size_type pos = 0) const { return find_first_of (str.data(), pos, str.length()); } size_type find_first_of (const charT* s, size_type pos, size_type n) const; size_type find_first_of (const charT* s, size_type pos = 0) const { return find_first_of (s, pos, traits::length (s)); } size_type find_first_of (charT c, size_type pos = 0) const { return find (c, pos); } size_type find_last_of (const basic_string& str, size_type pos = npos) const { return find_last_of (str.data(), pos, str.length()); } size_type find_last_of (const charT* s, size_type pos, size_type n) const; size_type find_last_of (const charT* s, size_type pos = npos) const { return find_last_of (s, pos, traits::length (s)); } size_type find_last_of (charT c, size_type pos = npos) const { return rfind (c, pos); } size_type find_first_not_of (const basic_string& str, size_type pos = 0) const { return find_first_not_of (str.data(), pos, str.length()); } size_type find_first_not_of (const charT* s, size_type pos, size_type n) const; size_type find_first_not_of (const charT* s, size_type pos = 0) const { return find_first_not_of (s, pos, traits::length (s)); } size_type find_first_not_of (charT c, size_type pos = 0) const; size_type find_last_not_of (const basic_string& str, size_type pos = npos) const { return find_last_not_of (str.data(), pos, str.length()); } size_type find_last_not_of (const charT* s, size_type pos, size_type n) const; size_type find_last_not_of (const charT* s, size_type pos = npos) const { return find_last_not_of (s, pos, traits::length (s)); } size_type find_last_not_of (charT c, size_type pos = npos) const; basic_string substr (size_type pos = 0, size_type n = npos) const { return basic_string (*this, pos, n); }//调用构造函数 int compare (const basic_string& str, size_type pos = 0, size_type n = npos) const; // There is no 'strncmp' equivalent for charT pointers. int compare (const charT* s, size_type pos, size_type n) const; int compare (const charT* s, size_type pos = 0) const { return compare (s, pos, traits::length (s)); } iterator begin () { selfish (); return &(*this)[0]; }//为啥不直接return &(*this)[0]呢?里面也有 selfish ()啊 iterator end () { selfish (); return &(*this)[length ()]; }private: iterator ibegin () const { return &(*rep ())[0]; } iterator iend () const { return &(*rep ())[length ()]; }public: const_iterator begin () const { return ibegin (); } const_iterator end () const { return iend (); } 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 ()); }private: void alloc (size_type size, bool save);//重新分配内存 static size_type _find (const charT* ptr, charT c, size_type xpos, size_type len); inline bool check_realloc (size_type s) const;//是否需要重新分配内存 static Rep nilRep;//静态Rep用于空string charT *dat;//唯一的一个数据成员};//replace 的一个实现#ifdef __STL_MEMBER_TEMPLATEStemplate <class charT, class traits, class Allocator> template <class InputIterator>basic_string <charT, traits, Allocator>&basic_string <charT, traits, Allocator>::replace (iterator i1, iterator i2, InputIterator j1, InputIterator j2)#elsetemplate <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>::replace (iterator i1, iterator i2, const_iterator j1, const_iterator j2)#endif{ //将[i1 i2) 换成[j1 j2)的内容 const size_type len = length ();//string的长度 size_type pos = i1 - ibegin ();//replace的偏移地址 size_type n1 = i2 - i1;//replace的个数 size_type n2 = j2 - j1; OUTOFRANGE (pos > len); if (n1 > len - pos) n1 = len - pos;//replace的个数大于实际可以replace的个数的时候 实际replace (len-pos)个字符 LENGTHERROR (len - n1 > max_size () - n2);//保证replace后的字符个数不会大于max_size() size_t newlen = len - n1 + n2; if (check_realloc (newlen))//是否要重新分配内存 { Rep *p = Rep::create (newlen); p->copy (0, data (), pos); p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); for (; j1 != j2; ++j1, ++pos) traits::assign ((*p)[pos], *j1); repup (p); } else { rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); for (; j1 != j2; ++j1, ++pos) traits::assign ((*rep ())[pos], *j1); } rep ()->len = newlen; return *this;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>operator+ (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ basic_string <charT, traits, Allocator> str (lhs); str.append (rhs); return str;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>operator+ (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ basic_string <charT, traits, Allocator> str (lhs); str.append (rhs); return str;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>operator+ (charT lhs, const basic_string <charT, traits, Allocator>& rhs){ basic_string <charT, traits, Allocator> str (1, lhs); str.append (rhs); return str;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>operator+ (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ basic_string <charT, traits, Allocator> str (lhs); str.append (rhs); return str;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>operator+ (const basic_string <charT, traits, Allocator>& lhs, charT rhs){ basic_string <charT, traits, Allocator> str (lhs); str.append (1, rhs); return str;}template <class charT, class traits, class Allocator>inline booloperator== (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ return (lhs.compare (rhs) == 0);}template <class charT, class traits, class Allocator>inline booloperator== (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ return (rhs.compare (lhs) == 0);}template <class charT, class traits, class Allocator>inline booloperator== (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ return (lhs.compare (rhs) == 0);}template <class charT, class traits, class Allocator>inline booloperator!= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ return (rhs.compare (lhs) != 0);}template <class charT, class traits, class Allocator>inline booloperator!= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ return (lhs.compare (rhs) != 0);}template <class charT, class traits, class Allocator>inline booloperator< (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ return (lhs.compare (rhs) < 0);}template <class charT, class traits, class Allocator>inline booloperator< (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ return (rhs.compare (lhs) > 0);}template <class charT, class traits, class Allocator>inline booloperator< (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ return (lhs.compare (rhs) < 0);}template <class charT, class traits, class Allocator>inline booloperator> (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ return (rhs.compare (lhs) < 0);}template <class charT, class traits, class Allocator>inline booloperator> (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ return (lhs.compare (rhs) > 0);}template <class charT, class traits, class Allocator>inline booloperator<= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ return (rhs.compare (lhs) >= 0);}template <class charT, class traits, class Allocator>inline booloperator<= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ return (lhs.compare (rhs) <= 0);}template <class charT, class traits, class Allocator>inline booloperator>= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs){ return (rhs.compare (lhs) <= 0);}template <class charT, class traits, class Allocator>inline booloperator>= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs){ return (lhs.compare (rhs) >= 0);}template <class charT, class traits, class Allocator>inline booloperator!= (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ return (lhs.compare (rhs) != 0);}template <class charT, class traits, class Allocator>inline booloperator> (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ return (lhs.compare (rhs) > 0);}template <class charT, class traits, class Allocator>inline booloperator<= (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ return (lhs.compare (rhs) <= 0);}template <class charT, class traits, class Allocator>inline booloperator>= (const basic_string <charT, traits, Allocator>& lhs, const basic_string <charT, traits, Allocator>& rhs){ return (lhs.compare (rhs) >= 0);}class istream; class ostream;template <class charT, class traits, class Allocator> istream&operator>> (istream&, basic_string <charT, traits, Allocator>&);template <class charT, class traits, class Allocator> ostream&operator<< (ostream&, const basic_string <charT, traits, Allocator>&);template <class charT, class traits, class Allocator> istream&getline (istream&, basic_string <charT, traits, Allocator>&, charT delim = '\n');} // extern "C++"#include <std/bastring.cc>#endif
- base_string的源文件
extern "C++" {template <class charT, class traits, class Allocator>inline void * basic_string <charT, traits, Allocator>::Rep::operator new (size_t s, size_t extra){//分配内存 Rep的大小 + string的字符 return Allocator::allocate(s + extra * sizeof (charT));}template <class charT, class traits, class Allocator>inline void basic_string <charT, traits, Allocator>::Rep::operator delete (void * ptr){//归还上面分配的内存 Allocator::deallocate(ptr, sizeof(Rep) + reinterpret_cast<Rep *>(ptr)->res * sizeof (charT)); }template <class charT, class traits, class Allocator>inline size_t basic_string <charT, traits, Allocator>::Rep::frob_size (size_t s){//string字符容量分配的大小 size_t i = 16; while (i < s) i *= 2; return i;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>::Rep *basic_string <charT, traits, Allocator>::Rep::create (size_t extra){ extra = frob_size (extra + 1); Rep *p = new (extra) Rep;//调用上面的operator new p->res = extra;//初始化,len会在new (extra) Rep调用Rep的构造函数是初始化为0 p->ref = 1; p->selfish = false; return p;}template <class charT, class traits, class Allocator>charT * basic_string <charT, traits, Allocator>::Rep::clone (){ Rep *p = Rep::create (len); p->copy (0, data (), len); p->len = len; return p->data ();}template <class charT, class traits, class Allocator>inline bool basic_string <charT, traits, Allocator>::Rep::excess_slop (size_t s, size_t r){ return 2 * (s <= 16 ? 16 : s) < r;}template <class charT, class traits, class Allocator>inline bool basic_string <charT, traits, Allocator>::check_realloc (basic_string::size_type s) const{ s += sizeof (charT); rep ()->selfish = false; return (rep ()->ref > 1//ref大于1 || s > capacity ()//新的分配的字符内存大于容量 || Rep::excess_slop (s, capacity ()));//新分配的字符内存*2还小于容量(用于减小多余的内存)}//重新分配内存的三个条件template <class charT, class traits, class Allocator>void basic_string <charT, traits, Allocator>::alloc (basic_string::size_type size, bool save){ if (! check_realloc (size)) return; Rep *p = Rep::create (size); if (save) { p->copy (0, data (), length ()); p->len = length (); } else p->len = 0; repup (p);}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>&basic_string <charT, traits, Allocator>::replace (size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2){ const size_t len2 = str.length (); if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2) return operator= (str);//正好满足operator= 的条件 OUTOFRANGE (pos2 > len2); if (n2 > len2 - pos2) n2 = len2 - pos2; return replace (pos1, n1, str.data () + pos2, n2);}template <class charT, class traits, class Allocator>inline void basic_string <charT, traits, Allocator>::Rep::copy (size_t pos, const charT *s, size_t n){ if (n) traits::copy (data () + pos, s, n);}template <class charT, class traits, class Allocator>inline void basic_string <charT, traits, Allocator>::Rep::move (size_t pos, const charT *s, size_t n){ if (n) traits::move (data () + pos, s, n);}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>&basic_string <charT, traits, Allocator>::replace (size_type pos, size_type n1, const charT* s, size_type n2){ const size_type len = length (); OUTOFRANGE (pos > len); if (n1 > len - pos) n1 = len - pos; LENGTHERROR (len - n1 > max_size () - n2); size_t newlen = len - n1 + n2; if (check_realloc (newlen)) { Rep *p = Rep::create (newlen); p->copy (0, data (), pos); p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); p->copy (pos, s, n2); repup (p); } else { rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); rep ()->copy (pos, s, n2); } rep ()->len = newlen; return *this;}template <class charT, class traits, class Allocator>inline void basic_string <charT, traits, Allocator>::Rep::set (size_t pos, const charT c, size_t n){ traits::set (data () + pos, c, n);}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>::replace (size_type pos, size_type n1, size_type n2, charT c){ const size_t len = length (); OUTOFRANGE (pos > len); if (n1 > len - pos) n1 = len - pos; LENGTHERROR (len - n1 > max_size () - n2); size_t newlen = len - n1 + n2; if (check_realloc (newlen)) { Rep *p = Rep::create (newlen); p->copy (0, data (), pos); p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); p->set (pos, c, n2); repup (p); } else { rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); rep ()->set (pos, c, n2); } rep ()->len = newlen; return *this;}template <class charT, class traits, class Allocator>void basic_string <charT, traits, Allocator>::resize (size_type n, charT c){ LENGTHERROR (n > max_size ()); if (n > length ()) append (n - length (), c); else erase (n);}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::copy (charT* s, size_type n, size_type pos) const{ OUTOFRANGE (pos > length ()); if (n > length () - pos) n = length () - pos; traits::copy (s, data () + pos, n); return n;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find (const charT* s, size_type pos, size_type n) const{ size_t xpos = pos; for (; xpos + n <= length (); ++xpos) if (traits::eq (data () [xpos], *s) && traits::compare (data () + xpos, s, n) == 0) return xpos; return npos;}template <class charT, class traits, class Allocator>inline basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::_find (const charT* ptr, charT c, size_type xpos, size_type len){ for (; xpos < len; ++xpos) if (traits::eq (ptr [xpos], c)) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find (charT c, size_type pos) const{ return _find (data (), c, pos, length ());}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::rfind (const charT* s, size_type pos, size_type n) const{ if (n > length ()) return npos; size_t xpos = length () - n; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0; ) if (traits::eq (data () [xpos], *s) && traits::compare (data () + xpos, s, n) == 0) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::rfind (charT c, size_type pos) const{ if (1 > length ()) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0; ) if (traits::eq (data () [xpos], c)) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find_first_of (const charT* s, size_type pos, size_type n) const{ size_t xpos = pos; for (; xpos < length (); ++xpos) if (_find (s, data () [xpos], 0, n) != npos) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find_last_of (const charT* s, size_type pos, size_type n) const{ if (length() == 0) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0;) if (_find (s, data () [xpos], 0, n) != npos) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find_first_not_of (const charT* s, size_type pos, size_type n) const{ size_t xpos = pos; for (; xpos < length (); ++xpos) if (_find (s, data () [xpos], 0, n) == npos) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find_first_not_of (charT c, size_type pos) const{ size_t xpos = pos; for (; xpos < length (); ++xpos) if (traits::ne (data () [xpos], c)) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find_last_not_of (const charT* s, size_type pos, size_type n) const{ if (length() == 0) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0;) if (_find (s, data () [xpos], 0, n) == npos) return xpos; return npos;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::find_last_not_of (charT c, size_type pos) const{ if (length() == 0) return npos; size_t xpos = length () - 1; if (xpos > pos) xpos = pos; for (++xpos; xpos-- > 0;) if (traits::ne (data () [xpos], c)) return xpos; return npos;}template <class charT, class traits, class Allocator>int basic_string <charT, traits, Allocator>::compare (const basic_string& str, size_type pos, size_type n) const{ OUTOFRANGE (pos > length ()); size_t rlen = length () - pos; if (rlen > n) rlen = n; if (rlen > str.length ()) rlen = str.length (); int r = traits::compare (data () + pos, str.data (), rlen); if (r != 0) return r; if (rlen == n) return 0; return (length () - pos) - str.length ();}template <class charT, class traits, class Allocator>int basic_string <charT, traits, Allocator>::compare (const charT* s, size_type pos, size_type n) const{ OUTOFRANGE (pos > length ()); size_t rlen = length () - pos; if (rlen > n) rlen = n; int r = traits::compare (data () + pos, s, rlen); if (r != 0) return r; return (length () - pos) - n;}#include <iostream.h>template <class charT, class traits, class Allocator>istream &operator>> (istream &is, basic_string <charT, traits, Allocator> &s){ int w = is.width (0); if (is.ipfx0 ()) { register streambuf *sb = is.rdbuf (); s.resize (0); while (1) { int ch = sb->sbumpc (); if (ch == EOF) { is.setstate (ios::eofbit); break; } else if (traits::is_del (ch)) { sb->sungetc (); break; } s += ch; if (--w == 1) break; } } is.isfx (); if (s.length () == 0) is.setstate (ios::failbit); return is;}template <class charT, class traits, class Allocator>ostream &operator<< (ostream &o, const basic_string <charT, traits, Allocator>& s){ return o.write (s.data (), s.length ());}template <class charT, class traits, class Allocator>istream&getline (istream &is, basic_string <charT, traits, Allocator>& s, charT delim){ if (is.ipfx1 ()) { _IO_size_t count = 0; streambuf *sb = is.rdbuf (); s.resize (0); while (1) { int ch = sb->sbumpc (); if (ch == EOF) { is.setstate (count == 0 ? (ios::failbit|ios::eofbit) : ios::eofbit); break; } ++count; if (ch == delim) break; s += ch; if (s.length () == s.npos - 1) { is.setstate (ios::failbit); break; } } } // We need to be friends with istream to do this. // is._gcount = count; is.isfx (); return is;}template <class charT, class traits, class Allocator>basic_string <charT, traits, Allocator>::Repbasic_string<charT, traits, Allocator>::nilRep = { 0, 0, 1, false };template <class charT, class traits, class Allocator>const basic_string <charT, traits, Allocator>::size_typebasic_string <charT, traits, Allocator>::npos;} // extern "C++"
阅读全文
0 0
- 文章标题 SGI的base_string解析
- 文章标题 SGI的vector
- 文章标题 SGI 的alloc
- C# 解析 SGI 图形
- 文章的标题
- 文章的标题2
- 文章的标题3
- 新添加的文章标题
- 文章标题 诡异的楼梯
- 文章标题pulltorefresh的使用
- 这是文章的标题
- 文章标题 map的用法
- sgi的内存泄露
- sgi的hashtable
- SGI的内存管理
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 修改环境变量
- SSH项目前台数据后台存储乱码问题
- HDOJ 2033 人见人爱A+B
- Pycharm2017版本设置启动时默认自动打开项目
- Ubuntu 备份与恢复
- 文章标题 SGI的base_string解析
- 构造函数,This、final、static关键字的初步认识
- LintCode 解题记录 17.6.19~17.6.25
- 进程操作
- mysql查询语句
- 冒泡排序与快速排序
- C++ 读取excel 之libxl VS 库的配置使用
- 20170619 老龄化才是平权的真正阻碍?
- java面向对象-成员变量和局部变量