📄 rope
字号:
// SGI's rope class -*- C++ -*-// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library. This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING. If not, write to the Free// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,// USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License./* * Copyright (c) 1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation 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. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. *//** @file ext/rope * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */#ifndef _ROPE#define _ROPE 1#include <bits/stl_algobase.h>#include <bits/stl_construct.h>#include <bits/stl_uninitialized.h>#include <bits/stl_algo.h>#include <bits/stl_function.h>#include <bits/stl_numeric.h>#include <bits/allocator.h>#include <ext/hash_fun.h># ifdef __GC# define __GC_CONST const# else# include <bits/gthr.h># define __GC_CONST // constant except for deallocation# endif#include <ext/memory> // For uninitialized_copy_nnamespace __gnu_cxx{ using std::size_t; using std::ptrdiff_t; using std::allocator; using std::iterator; using std::reverse_iterator; using std::_Destroy; // The _S_eos function is used for those functions that // convert to/from C-like strings to detect the end of the string. // The end-of-C-string character. // This is what the draft standard says it should be. template <class _CharT> inline _CharT _S_eos(_CharT*) { return _CharT(); } // Test for basic character types. // For basic character types leaves having a trailing eos. template <class _CharT> inline bool _S_is_basic_char_type(_CharT*) { return false; } template <class _CharT> inline bool _S_is_one_byte_char_type(_CharT*) { return false; } inline bool _S_is_basic_char_type(char*) { return true; } inline bool _S_is_one_byte_char_type(char*) { return true; } inline bool _S_is_basic_char_type(wchar_t*) { return true; } // Store an eos iff _CharT is a basic character type. // Do not reference _S_eos if it isn't. template <class _CharT> inline void _S_cond_store_eos(_CharT&) { } inline void _S_cond_store_eos(char& __c) { __c = 0; } inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } // char_producers are logically functions that generate a section of // a string. These can be convereted 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, size_t _Buf_sz = 100> class sequence_buffer : public iterator<std::output_iterator_tag, void, void, void, void> { public: typedef typename _Sequence::value_type value_type; 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 sequence_buffer& __x) { _M_prefix = __x._M_prefix; _M_buf_count = __x._M_buf_count; std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); } sequence_buffer(sequence_buffer& __x) { __x.flush(); _M_prefix = __x._M_prefix; _M_buf_count = 0; } sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) { } sequence_buffer& operator=(sequence_buffer& __x) { __x.flush(); _M_prefix = __x._M_prefix; _M_buf_count = 0; return *this; } sequence_buffer& operator=(const sequence_buffer& __x) { _M_prefix = __x._M_prefix; _M_buf_count = __x._M_buf_count; 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(value_type* __s, size_t __len) { if (__len + _M_buf_count <= _Buf_sz) { size_t __i = _M_buf_count; for (size_t __j = 0; __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); } } sequence_buffer& write(value_type* __s, size_t __len) { append(__s, __len); return *this; } sequence_buffer& put(value_type __x) { push_back(__x); return *this; } sequence_buffer& operator=(const value_type& __rhs) { push_back(__rhs); return *this; } sequence_buffer& operator*() { return *this; } sequence_buffer& operator++() { return *this; } sequence_buffer operator++(int) { return *this; } }; // The following should be treated as private, at least for now. template<class _CharT> class _Rope_char_consumer { public: // If we had member templates, these should not be virtual. // For now we need to use run-time parametrization where // compile-time would do. Hence this should all be private // for now. // The symmetry with char_producer is accidental and temporary. virtual ~_Rope_char_consumer() {}; virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; }; // 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, class _Alloc = allocator<_CharT> > class rope; template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation; 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; template<class _CharT, class _Alloc> bool operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> _Rope_const_iterator<_CharT, _Alloc> operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_const_iterator<_CharT, _Alloc> operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_const_iterator<_CharT, _Alloc> operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x); template<class _CharT, class _Alloc> bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> ptrdiff_t operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> _Rope_iterator<_CharT, _Alloc> operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_iterator<_CharT, _Alloc> operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_iterator<_CharT, _Alloc> operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x); template<class _CharT, class _Alloc> bool operator==(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> bool operator<(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> ptrdiff_t operator-(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, const rope<_CharT, _Alloc>& __right); template<class _CharT, class _Alloc> rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right); template<class _CharT, class _Alloc> rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, _CharT __right); // Some helpers, so we can use power 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 std::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> inline rope<_CharT, _Alloc> identity_element(_Rope_Concat_fn<_CharT, _Alloc>) { return rope<_CharT, _Alloc>(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -