📄 _string.h
字号:
/* * Copyright (c) 1997-1999 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */#ifndef _STLP_STRING_H#define _STLP_STRING_H#include <cstddef>#include <bits/STLPort/_config.h>#include <bits/STLPort/_alloc.h>#include <bits/STLPort/type_traits.h>#include <bits/STLPort/_ctraits_fns.h>#include <bits/stl_iterator_base_types.h>#include <bits/STLPort/_iterator_base.h>/*#ifndef _STLP_MEMORY# include <memory> #endif# ifndef _STLP_CCTYPE# include <cctype> # endif#ifndef _STLP_STRING_FWD_H# include <stl/_string_fwd.h> #endif#ifndef _STLP_INTERNAL_FUNCTION_BASE_H# include <stl/_function.h> #endif# include <stl/_ctraits_fns.h> #ifndef _STLP_INTERNAL_ALGOBASE_H# include <stl/_algobase.h> #endif#ifndef _STLP_INTERNAL_ITERATOR_H# include <stl/_iterator.h> #endif#if defined( __MWERKS__ ) && ! defined (_STLP_USE_OWN_NAMESPACE)// MSL implementation classes expect to see the definition of streampos// when this header is included. We expect this to be fixed in later MSL// implementations# if !defined( __MSL_CPP__ ) || __MSL_CPP__ < 0x4105# include <stl/msl_string.h> # endif#endif // __MWERKS__*/// Standard C++ string class. This class has performance// characteristics very much like vector<>, meaning, for example, that// it does not perform reference-count or copy-on-write, and that// concatenation of two strings is an O(N) operation. // There are three reasons why basic_string is not identical to// vector. First, basic_string always stores a null character at the// end; this makes it possible for c_str to be a fast operation.// Second, the C++ standard requires basic_string to copy elements// using char_traits<>::assign, char_traits<>::copy, and// char_traits<>::move. This means that all of vector<>'s low-level// operations must be rewritten. Third, basic_string<> has a lot of// extra functions in its interface that are convenient but, strictly// speaking, redundant.// Additionally, the C++ standard imposes a major restriction: according// to the standard, the character type _CharT must be a POD type. This// implementation weakens that restriction, and allows _CharT to be a// a user-defined non-POD type. However, _CharT must still have a// default constructor._STLP_BEGIN_NAMESPACE# ifdef _STLP_DEBUG# define basic_string _Nondebug_string# endif// A helper class to use a char_traits as a function object.template <class _Traits> struct _Not_within_traits : public unary_function< typename _Traits::char_type, bool> { typedef typename _Traits::char_type _CharT; const _CharT* _M_first; const _CharT* _M_last; _Not_within_traits(const typename _Traits::char_type* __f, const typename _Traits::char_type* __l) : _M_first(__f), _M_last(__l) {} bool operator()(const typename _Traits::char_type& __x) const { return find_if(_M_first, _M_last, _Eq_char_bound<_Traits>(__x)) == _M_last; }};// ------------------------------------------------------------// Class _String_base. // _String_base is a helper class that makes it it easier to write an// exception-safe version of basic_string. The constructor allocates,// but does not initialize, a block of memory. The destructor// deallocates, but does not destroy elements within, a block of// memory. The destructor assumes that _M_start either is null, or else// points to a block of memory that was allocated using _String_base's // allocator and whose size is _M_end_of_storage._M_data - _M_start.template <class _Tp, class _Alloc> class _String_base { public: _STLP_FORCE_ALLOCATORS(_Tp, _Alloc) typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; _Tp* _M_start; _Tp* _M_finish; _STLP_alloc_proxy<_Tp*, _Tp, allocator_type> _M_end_of_storage; // Precondition: 0 < __n <= max_size(). void _M_allocate_block(size_t); void _M_deallocate_block() { _M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start); } size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; } _String_base(const allocator_type& __a) : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0) {} _String_base(const allocator_type& __a, size_t __n) : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0) { _M_allocate_block(__n); } ~_String_base() { _M_deallocate_block(); } void _M_throw_length_error() const; void _M_throw_out_of_range() const;};# if defined (_STLP_USE_TEMPLATE_EXPORT)_STLP_EXPORT_TEMPLATE_CLASS _String_base<char, allocator<char> >;# if defined (_STLP_HAS_WCHAR_T)_STLP_EXPORT_TEMPLATE_CLASS _String_base<wchar_t, allocator<wchar_t> >;# endif# endif /* _STLP_USE_TEMPLATE_EXPORT */// ------------------------------------------------------------// Class basic_string. // Class invariants:// (1) [start, finish) is a valid range.// (2) Each iterator in [start, finish) points to a valid object// of type value_type.// (3) *finish is a valid object of type value_type; in particular,// it is value_type().// (4) [finish + 1, end_of_storage) is a valid range.// (5) Each iterator in [finish + 1, end_of_storage) points to // unininitialized memory.// Note one important consequence: a string of length n must manage// a block of memory whose size is at least n + 1. struct _String_reserve_t {};template <class _CharT, class _Traits, class _Alloc> class basic_string : protected _String_base<_CharT,_Alloc> { private: // Protected members inherited from base. typedef _String_base<_CharT,_Alloc> _Base; typedef basic_string<_CharT, _Traits, _Alloc> _Self; // fbp : used to optimize char/wchar_t cases, and to simplify // _STLP_DEFAULT_CONSTRUCTOR_BUG problem workaround typedef typename _Is_integer<_CharT>::_Integral _Char_Is_Integral; public: typedef _CharT value_type; typedef _Traits traits_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef random_access_iterator_tag _Iterator_category; typedef const value_type* const_iterator; typedef value_type* iterator; _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;# if defined(_STLP_STATIC_CONST_INIT_BUG) enum { npos = -1 };# elif __GNUC__ == 2 && __GNUC_MINOR__ == 96 // inline initializer conflicts with 'extern template' static const size_t npos ;# else static const size_t npos = ~(size_t)0;# endif typedef _String_reserve_t _Reserve_t;# if defined (_STLP_USE_NATIVE_STRING) && ! defined (_STLP_DEBUG)# if (defined(__IBMCPP__) && (500 <= __IBMCPP__) && (__IBMCPP__ < 600) ) // this typedef is being used for conversions typedef typename _STLP_VENDOR_STD::basic_string<_CharT,_Traits, typename _STLP_VENDOR_STD::allocator<_CharT> > __std_string;# else // this typedef is being used for conversions typedef _STLP_VENDOR_STD::basic_string<_CharT,_Traits, _STLP_VENDOR_STD::allocator<_CharT> > __std_string;# endif# endif public: // Constructor, destructor, assignment. typedef typename _String_base<_CharT,_Alloc>::allocator_type allocator_type; allocator_type get_allocator() const { return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_end_of_storage, _CharT); } basic_string(); explicit basic_string(const allocator_type& __a) : _String_base<_CharT,_Alloc>(__a, 8) { _M_terminate_string(); } basic_string(_Reserve_t, size_t __n, const allocator_type& __a = allocator_type()) : _String_base<_CharT,_Alloc>(__a, __n + 1) { _M_terminate_string(); } basic_string(const basic_string<_CharT, _Traits, _Alloc>&); basic_string(const _Self& __s, size_type __pos, size_type __n = npos, const allocator_type& __a = allocator_type()) : _String_base<_CharT,_Alloc>(__a) { if (__pos > __s.size()) this->_M_throw_out_of_range(); else _M_range_initialize(__s._M_start + __pos, __s._M_start + __pos + (min) (__n, __s.size() - __pos)); } basic_string(const _CharT* __s, size_type __n, const allocator_type& __a = allocator_type()) : _String_base<_CharT,_Alloc>(__a) { _STLP_FIX_LITERAL_BUG(__s) _M_range_initialize(__s, __s + __n); } basic_string(const _CharT* __s, const allocator_type& __a = allocator_type()); basic_string(size_type __n, _CharT __c, const allocator_type& __a = allocator_type()) : _String_base<_CharT,_Alloc>(__a, __n + 1) { this->_M_finish = uninitialized_fill_n(this->_M_start, __n, __c); _M_terminate_string(); } // Check to see if _InputIterator is an integer type. If so, then // it can't be an iterator.#if defined (_STLP_MEMBER_TEMPLATES) && !(defined(__MRC__)||(defined(__SC__) && !defined(__DMC__))) //*ty 04/30/2001 - mpw compilers choke on this ctor# ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS template <class _InputIterator> basic_string(_InputIterator __f, _InputIterator __l) : _String_base<_CharT,_Alloc>(allocator_type()) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__f, __l, _Integral()); }# endif template <class _InputIterator> basic_string(_InputIterator __f, _InputIterator __l, const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL) : _String_base<_CharT,_Alloc>(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__f, __l, _Integral()); }#else /* _STLP_MEMBER_TEMPLATES */ basic_string(const _CharT* __f, const _CharT* __l, const allocator_type& __a = allocator_type()) : _String_base<_CharT,_Alloc>(__a) { _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) _M_range_initialize(__f, __l); }#endif# if defined (_STLP_USE_NATIVE_STRING) && ! defined (_STLP_DEBUG) // these conversion operations still needed for // strstream, etc. basic_string (const __std_string& __x): _String_base<_CharT,_Alloc>(allocator_type()) { const _CharT* __s = __x.data(); _M_range_initialize(__s, __s + __x.size()); } operator __std_string() const { return __std_string(this->data(), this->size()); }# endif ~basic_string() { _STLP_STD::_Destroy(this->_M_start, this->_M_finish + 1); } _Self& operator=(const _Self& __s) { if (&__s != this) assign(__s._M_start, __s._M_finish); return *this; } _Self& operator=(const _CharT* __s) { _STLP_FIX_LITERAL_BUG(__s) return assign(__s, __s + traits_type::length(__s)); } _Self& operator=(_CharT __c) { return assign(__STATIC_CAST(size_type,1), __c); } static _CharT _STLP_CALL _M_null() { return _STLP_DEFAULT_CONSTRUCTED(_CharT); } private: // Helper functions used by constructors // and elsewhere. // fbp : simplify integer types (char, wchar) void _M_construct_null_aux(_CharT* __p, const __false_type&) { _Construct(__p); } void _M_construct_null_aux(_CharT* __p, const __true_type&) { *__p = 0; } void _M_construct_null(_CharT* __p) { _M_construct_null_aux(__p, _Char_Is_Integral()); } private: // Helper functions used by constructors. It is a severe error for // any of them to be called anywhere except from within constructors. void _M_terminate_string_aux(const __false_type&) { _STLP_TRY { _M_construct_null(this->_M_finish); } _STLP_UNWIND(_STLP_STD::_Destroy(this->_M_start, this->_M_finish)); } void _M_terminate_string_aux(const __true_type&) { *(this->_M_finish)=0; } void _M_terminate_string() { _M_terminate_string_aux(_Char_Is_Integral()); }#ifndef _STLP_MEMBER_TEMPLATES bool _M_inside(const _CharT* __s ) const { return (__s >= this->_M_start) && (__s < this->_M_finish); }#else template <class _InputIter> bool _M_inside(_InputIter __i) const { const _CharT* __s = __STATIC_CAST(const _CharT*, &(*__i)); return (__s >= this->_M_start) && (__s < this->_M_finish); }#endif /*_STLP_MEMBER_TEMPLATES*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -