_rope.h
来自「stl的源码」· C头文件 代码 · 共 1,929 行 · 第 1/5 页
H
1,929 行
/* * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1997 * Moscow Center for SPARC Technology * * 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. * *//* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */// rope<_CharT,_Alloc> is a sequence of _CharT.// Ropes appear to be mutable, but update operations// really copy enough of the data structure to leave the original// valid. Thus ropes can be logically copied by just copying// a pointer value.#ifndef _STLP_INTERNAL_ROPE_H#define _STLP_INTERNAL_ROPE_H#ifndef _STLP_INTERNAL_ALGOBASE_H# include <stl/_algobase.h>#endif#if !defined (_STLP_USE_NO_IOSTREAMS) && !defined (_STLP_INTERNAL_IOSFWD)# include <stl/_iosfwd.h>#endif#ifndef _STLP_INTERNAL_ALLOC_H# include <stl/_alloc.h>#endif#ifndef _STLP_INTERNAL_ITERATOR_H# include <stl/_iterator.h>#endif#ifndef _STLP_INTERNAL_ALGO_H# include <stl/_algo.h>#endif#ifndef _STLP_INTERNAL_FUNCTION_BASE_H# include <stl/_function_base.h>#endif#ifndef _STLP_INTERNAL_NUMERIC_H# include <stl/_numeric.h>#endif#ifndef _STLP_INTERNAL_HASH_FUN_H# include <stl/_hash_fun.h>#endif#ifndef _STLP_CHAR_TRAITS_H# include <stl/char_traits.h>#endif#ifndef _STLP_INTERNAL_THREADS_H# include <stl/_threads.h>#endif#ifdef _STLP_SGI_THREADS# include <mutex.h>#endif#ifndef _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE# define _STLP_CREATE_ALLOCATOR(__atype,__a, _Tp) (_Alloc_traits<_Tp,__atype>::create_allocator(__a))#else# define _STLP_CREATE_ALLOCATOR(__atype,__a, _Tp) __stl_alloc_create(__a,(_Tp*)0)#endif_STLP_BEGIN_NAMESPACE// First a lot of forward declarations. The standard seems to require// much stricter "declaration before use" than many of the implementations// that preceded it.template<class _CharT, _STLP_DFL_TMPL_PARAM(_Alloc, allocator<_CharT>) > class rope;template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation;template<class _CharT, class _Alloc> struct _Rope_RopeRep;template<class _CharT, class _Alloc> struct _Rope_RopeLeaf;template<class _CharT, class _Alloc> struct _Rope_RopeFunction;template<class _CharT, class _Alloc> struct _Rope_RopeSubstring;template<class _CharT, class _Alloc> class _Rope_iterator;template<class _CharT, class _Alloc> class _Rope_const_iterator;template<class _CharT, class _Alloc> class _Rope_char_ref_proxy;template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy;_STLP_MOVE_TO_PRIV_NAMESPACEtemplate <class _CharT>struct _BasicCharType { typedef __false_type _Ret; };_STLP_TEMPLATE_NULLstruct _BasicCharType<char> { typedef __true_type _Ret; };#ifdef _STLP_HAS_WCHAR_T_STLP_TEMPLATE_NULLstruct _BasicCharType<wchar_t> { typedef __true_type _Ret; };#endif// Some helpers, so we can use the power algorithm on ropes.// See below for why this isn't local to the implementation.// This uses a nonstandard refcount convention.// The result has refcount 0.template<class _CharT, class _Alloc>struct _Rope_Concat_fn : public binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>, rope<_CharT,_Alloc> > { rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { return __x + __y; }};template <class _CharT, class _Alloc>inlinerope<_CharT,_Alloc>__identity_element(_Rope_Concat_fn<_CharT, _Alloc>){ return rope<_CharT,_Alloc>(); }_STLP_MOVE_TO_STD_NAMESPACE// Store an eostemplate <class _CharT>inline void _S_construct_null_aux(_CharT *__p, const __true_type&){ *__p = 0; }template <class _CharT>inline void _S_construct_null_aux(_CharT *__p, const __false_type&){ _STLP_STD::_Construct(__p); }template <class _CharT>inline void _S_construct_null(_CharT *__p) { typedef typename _IsIntegral<_CharT>::_Ret _Char_Is_Integral; _S_construct_null_aux(__p, _Char_Is_Integral());}// char_producers are logically functions that generate a section of// a string. These can be converted to ropes. The resulting rope// invokes the char_producer on demand. This allows, for example,// files to be viewed as ropes without reading the entire file.template <class _CharT>class char_producer {public: virtual ~char_producer() {} virtual void operator()(size_t __start_pos, size_t __len, _CharT* __buffer) = 0; // Buffer should really be an arbitrary output iterator. // That way we could flatten directly into an ostream, etc. // This is thoroughly impossible, since iterator types don't // have runtime descriptions.};// Sequence buffers://// Sequence must provide an append operation that appends an// array to the sequence. Sequence buffers are useful only if// appending an entire array is cheaper than appending element by element.// This is true for many string representations.// This should perhaps inherit from ostream<sequence::value_type>// and be implemented correspondingly, so that they can be used// for formatted. For the sake of portability, we don't do this yet.//// For now, sequence buffers behave as output iterators. But they also// behave a little like basic_ostringstream<sequence::value_type> and a// little like containers.template<class _Sequence# if !(defined (_STLP_NON_TYPE_TMPL_PARAM_BUG) || \ defined ( _STLP_NO_DEFAULT_NON_TYPE_PARAM )) , size_t _Buf_sz = 100# if defined(__sgi) && !defined(__GNUC__)# define __TYPEDEF_WORKAROUND ,class _V = typename _Sequence::value_type# endif /* __sgi */# endif /* _STLP_NON_TYPE_TMPL_PARAM_BUG */ >// The 3rd parameter works around a common compiler bug.class sequence_buffer : public iterator <output_iterator_tag, void, void, void, void> {public:# ifndef __TYPEDEF_WORKAROUND typedef typename _Sequence::value_type value_type; typedef sequence_buffer<_Sequence# if !(defined (_STLP_NON_TYPE_TMPL_PARAM_BUG) || \ defined ( _STLP_NO_DEFAULT_NON_TYPE_PARAM )) , _Buf_sz > _Self;# else /* _STLP_NON_TYPE_TMPL_PARAM_BUG */ > _Self; enum { _Buf_sz = 100};# endif /* _STLP_NON_TYPE_TMPL_PARAM_BUG */ // # endif# else /* __TYPEDEF_WORKAROUND */ typedef _V value_type; typedef sequence_buffer<_Sequence, _Buf_sz, _V> _Self;# endif /* __TYPEDEF_WORKAROUND */protected: _Sequence* _M_prefix; value_type _M_buffer[_Buf_sz]; size_t _M_buf_count;public: void flush() { _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); _M_buf_count = 0; } ~sequence_buffer() { flush(); } sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} sequence_buffer(const _Self& __x) { _M_prefix = __x._M_prefix; _M_buf_count = __x._M_buf_count; _STLP_STD::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); } sequence_buffer(_Self& __x) { __x.flush(); _M_prefix = __x._M_prefix; _M_buf_count = 0; } sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} _Self& operator= (_Self& __x) { __x.flush(); _M_prefix = __x._M_prefix; _M_buf_count = 0; return *this; } _Self& operator= (const _Self& __x) { _M_prefix = __x._M_prefix; _M_buf_count = __x._M_buf_count; _STLP_STD::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); return *this; } void push_back(value_type __x) { if (_M_buf_count < _Buf_sz) { _M_buffer[_M_buf_count] = __x; ++_M_buf_count; } else { flush(); _M_buffer[0] = __x; _M_buf_count = 1; } } void append(const value_type *__s, size_t __len) { if (__len + _M_buf_count <= _Buf_sz) { size_t __i = _M_buf_count; size_t __j = 0; for (; __j < __len; __i++, __j++) { _M_buffer[__i] = __s[__j]; } _M_buf_count += __len; } else if (0 == _M_buf_count) { _M_prefix->append(__s, __s + __len); } else { flush(); append(__s, __len); } } _Self& write(const value_type *__s, size_t __len) { append(__s, __len); return *this; } _Self& put(value_type __x) { push_back(__x); return *this; } _Self& operator=(const value_type& __rhs) { push_back(__rhs); return *this; } _Self& operator*() { return *this; } _Self& operator++() { return *this; } _Self& operator++(int) { return *this; }};// The following should be treated as private, at least for now.template<class _CharT>class _Rope_char_consumer {#if !defined (_STLP_MEMBER_TEMPLATES)public: //Without member templates we have to use run-time parameterization. // The symmetry with char_producer is accidental and temporary. virtual ~_Rope_char_consumer() {} virtual bool operator()(const _CharT* __buffer, size_t __len) = 0;#endif};//// What follows should really be local to rope. Unfortunately,// that doesn't work, since it makes it impossible to define generic// equality on rope iterators. According to the draft standard, the// template parameters for such an equality operator cannot be inferred// from the occurence of a member class as a parameter.// (SGI compilers in fact allow this, but the __result wouldn't be// portable.)// Similarly, some of the static member functions are member functions// only to avoid polluting the global namespace, and to circumvent// restrictions on type inference for template functions.////// The internal data structure for representing a rope. This is// private to the implementation. A rope is really just a pointer// to one of these.//// A few basic functions for manipulating this data structure// are members of _RopeRep. Most of the more complex algorithms// are implemented as rope members.//// Some of the static member functions of _RopeRep have identically// named functions in rope that simply invoke the _RopeRep versions.//template<class _CharT, class _Alloc>struct _Rope_RopeRep : public _Refcount_Base{ typedef _Rope_RopeRep<_CharT, _Alloc> _Self;public: // // GAB: 11/09/05 // // "__ROPE_DEPTH_SIZE" is set to one more then the "__ROPE_MAX_DEPTH". // This was originally just an addition of "__ROPE_MAX_DEPTH + 1" // but this addition causes the sunpro compiler to complain about // multiple declarations during the initialization of "_S_min_len". // Changed to be a fixed value and the sunpro compiler appears to // be happy??? //# define __ROPE_MAX_DEPTH 45# define __ROPE_DEPTH_SIZE 46 // __ROPE_MAX_DEPTH + 1 enum { _S_max_rope_depth = __ROPE_MAX_DEPTH }; enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; // Apparently needed by VC++ // The data fields of leaves are allocated with some // extra space, to accomodate future growth and for basic // character types, to hold a trailing eos character. enum { _S_alloc_granularity = 8 }; _Tag _M_tag:8; bool _M_is_balanced:8; _STLP_FORCE_ALLOCATORS(_CharT, _Alloc) typedef _Alloc allocator_type; allocator_type get_allocator() const { return allocator_type(_M_size); } unsigned char _M_depth; _CharT* _STLP_VOLATILE _M_c_string; _STLP_PRIV _STLP_alloc_proxy<size_t, _CharT, allocator_type> _M_size;#ifdef _STLP_NO_ARROW_OPERATOR _Rope_RopeRep() : _Refcount_Base(1), _M_size(allocator_type(), 0) {# if defined (_STLP_CHECK_RUNTIME_COMPATIBILITY) _STLP_CHECK_RUNTIME_COMPATIBILITY();# endif }#endif /* Flattened version of string, if needed. */ /* typically 0. */ /* If it's not 0, then the memory is owned */ /* by this node. */ /* In the case of a leaf, this may point to */ /* the same memory as the data field. */ _Rope_RopeRep(_Tag __t, unsigned char __d, bool __b, size_t _p_size, allocator_type __a) : _Refcount_Base(1), _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0), _M_size(__a, _p_size) {#if defined (_STLP_CHECK_RUNTIME_COMPATIBILITY) _STLP_CHECK_RUNTIME_COMPATIBILITY();#endif }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?