|
|
text.hpp説明を見る。00001 /* 00002 * TOPPERS/FDMP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Function Distributed Multiprocessor Kernel 00005 * 00006 * Copyright (C) 2005 by Takagi Nobuhisa 00007 * 00008 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 00009 * によって公表されている GNU General Public License の Version 2 に記 00010 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 00011 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 00012 * 利用と呼ぶ)することを無償で許諾する. 00013 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00014 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00015 * スコード中に含まれていること. 00016 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00017 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00018 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00019 * の無保証規定を掲載すること. 00020 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00021 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00022 * と. 00023 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00024 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00025 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00026 * 報告すること. 00027 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00028 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00029 * 00030 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00031 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 00032 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 00033 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 00034 * 00035 */ 00036 00046 #ifndef TOPPERS_TEXT_HPP_ 00047 #define TOPPERS_TEXT_HPP_ 00048 00049 #include "toppers/text_line.hpp" 00050 #include "toppers/misc.hpp" 00051 #include <iterator> 00052 #include <vector> 00053 #include <boost/iterator/iterator_facade.hpp> 00054 #include <boost/format.hpp> 00055 00056 namespace toppers 00057 { 00058 00069 template 00070 < 00071 template <typename, class> class Container, 00072 typename CharT, 00073 class Traits = std::char_traits<CharT>, 00074 class Allocator = std::allocator<CharT> 00075 > 00076 class basic_text 00077 { 00078 public: 00079 typedef basic_text<Container, CharT, Traits, Allocator> self_t; 00080 typedef std::basic_string<CharT, Traits, Allocator> string_type; 00081 typedef ::toppers::text_line line_type; 00082 typedef basic_line_buf<CharT, Traits, Allocator> line_buf; 00083 00084 // 以下は一般的なコンテナとの互換のための型定義 00086 typedef CharT value_type; 00087 typedef Container<line_buf, std::allocator<line_buf> > container; 00088 typedef value_type& reference; 00089 typedef const value_type& const_reference; 00090 typedef value_type* pointer; 00091 typedef const value_type* const_pointer; 00092 typedef Allocator allocator_type; 00093 typedef typename Allocator::difference_type difference_type; 00094 typedef typename Allocator::size_type size_type; 00095 00100 class const_iterator : public boost::iterator_facade<const_iterator, CharT, boost::random_access_traversal_tag, const CharT&> 00101 { 00102 friend class boost::iterator_core_access; 00103 public: 00104 typedef boost::iterator_facade<const_iterator, CharT, boost::random_access_traversal_tag, const CharT&> base_t; 00105 typedef typename container::const_iterator row_iterator; 00106 typedef typename base_t::value_type value_type; 00107 typedef typename base_t::reference reference; 00108 typedef typename base_t::pointer pointer; 00109 typedef typename base_t::difference_type difference_type; 00110 00111 const_iterator() : row_(), col_( 0 ) {} 00112 const_iterator( row_iterator row, size_type col ) : row_( row ), col_( col ) {} 00113 const line_type& line() const { return row_->line_; } 00114 const row_iterator& get_row() const { return row_; } 00115 size_type get_col() const { return col_; } 00116 protected: 00117 reference dereference() const { return row_->buf_[col_]; } 00118 bool equal( const const_iterator& rhs ) const { return row_ == rhs.row_ && col_ == rhs.col_; } 00119 void increment() { if ( ++col_ == row_->buf_.size() ) { col_ = 0; ++row_; } } 00120 void decrement() { if ( col_ == 0 ) col_ = ( --row_ )->buf_.size(); --col_; } 00121 void advance( difference_type n ) 00122 { 00123 typename container::const_iterator row = row_; 00124 size_type col = col_; 00125 while ( col + n > row->buf_.size() ) 00126 { 00127 n -= row->buf_.size() - col; 00128 ++row; 00129 col = 0; 00130 } 00131 col += n; 00132 if ( col == row->buf_.size() ) 00133 { 00134 col = 0; 00135 ++row; 00136 } 00137 row_ = row; 00138 col_ = col; 00139 } 00140 difference_type distance_to( const const_iterator& rhs ) const 00141 { 00142 difference_type n; 00143 typename container::const_iterator row = row_; 00144 if ( rhs.row_ < row_ ) 00145 { 00146 n = -static_cast<difference_type>( col_ + ( rhs.row_->buf_.size() - rhs.col_ ) ); 00147 while ( --row != rhs.row_ ) 00148 { 00149 n -= row->buf_.size(); 00150 } 00151 } 00152 else if ( row_ < rhs.row_ ) 00153 { 00154 n = col_ + rhs.col_; 00155 while ( ++row != rhs.row_ ) 00156 { 00157 n += row->buf_.size(); 00158 } 00159 } 00160 else 00161 { 00162 n = static_cast<difference_type>( rhs.col_ ) - static_cast<difference_type>( col_ ); 00163 } 00164 return n; 00165 } 00166 private: 00167 typename container::const_iterator row_; 00168 size_type col_; 00169 }; 00170 00175 class iterator : public const_iterator 00176 { 00177 public: 00178 typedef typename container::iterator row_iterator; 00179 typedef typename const_iterator::value_type value_type; 00180 typedef typename const_iterator::reference reference; 00181 typedef typename const_iterator::pointer pointer; 00182 typedef typename const_iterator::difference_type difference_type; 00183 00184 iterator() {} 00185 explicit iterator( row_iterator row, size_type col = 0 ) : const_iterator( row, col ) {} 00186 value_type& operator*() const { return const_cast<value_type&>( dereference() ); } 00187 iterator& operator++() { increment(); return *this; } 00188 iterator operator++( int ) { iterator t( *this ); increment(); return t; } 00189 iterator& operator--() { decrement(); return *this; } 00190 iterator operator--( int ) { iterator t( *this ); decrement(); return t; } 00191 }; 00192 00193 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00194 typedef std::reverse_iterator<iterator> reverse_iterator; 00195 00196 public: 00200 basic_text() {} 00201 00207 basic_text( const const_iterator& first, const const_iterator& last ) 00208 { 00209 if ( first != last ) 00210 { 00211 init( first, last ); 00212 } 00213 } 00214 00221 template <class ForwardIterator> 00222 basic_text( ForwardIterator first, ForwardIterator last ) 00223 { 00224 if ( first != last ) 00225 { 00226 init( first, last, append_directive ); 00227 } 00228 } 00229 00242 template <class ForwardIterator, class Directive> 00243 basic_text( ForwardIterator first, ForwardIterator last, Directive directive ) 00244 { 00245 if ( first != last ) 00246 { 00247 init( first, last, directive ); 00248 } 00249 } 00250 00256 basic_text( std::basic_istream<CharT, Traits>& istr ) 00257 { 00258 if ( first != last ) 00259 { 00260 init( istr, append_directive ); 00261 } 00262 } 00263 00275 template <class Directive> 00276 basic_text( std::basic_istream<CharT, Traits>& istr, Directive directive ) 00277 { 00278 init( istr, directive ); 00279 } 00280 00285 const_iterator begin() const 00286 { 00287 return const_iterator( container_.begin() ); 00288 } 00289 00294 iterator begin() 00295 { 00296 return iterator( container_.begin() ); 00297 } 00298 00303 const_iterator end() const 00304 { 00305 return const_iterator( container_.end() ); 00306 } 00307 00312 iterator end() 00313 { 00314 return iterator( container_.end() ); 00315 } 00316 00321 const_iterator rbegin() const 00322 { 00323 const string_type* pbuf = &container_.back().buf_; 00324 return const_reverse_iterator( container_.rbegin(), pbuf->empty() ? 0 : pbuf->size()-1 ); 00325 } 00326 00331 iterator rbegin() 00332 { 00333 string_type* pbuf = &container_.back().buf_; 00334 return reverse_iterator( container_.rbegin(), pbuf->empty() ? 0 : pbuf->size()-1 ); 00335 } 00336 00341 const_iterator rend() const 00342 { 00343 return const_reverse_iterator( container_.rend(), container_.back().buf_.size()-1 ); 00344 } 00345 00350 iterator rend() 00351 { 00352 return reverse_iterator( container_.rend() ); 00353 } 00354 00359 const_reference front() const 00360 { 00361 return container_.front().buf_[0]; 00362 } 00363 00368 reference front() 00369 { 00370 return container_.front().buf_[0]; 00371 } 00372 00377 const_reference back() const 00378 { 00379 const string_type* pbuf = &container_.back().buf_; 00380 return pbuf_->at( pbuf_->size()-1 ); 00381 } 00382 00387 reference back() 00388 { 00389 string_type* pbuf = &container_.back().buf_; 00390 return pbuf_->at( pbuf_->size()-1 ); 00391 } 00392 00397 const_reference at( size_type pos ) const 00398 { 00399 return container_.front().buf_[pos]; 00400 } 00401 00406 reference at( size_type pos ) 00407 { 00408 return container_.front().buf_[pos]; 00409 } 00410 00416 void append( const const_iterator& first, const const_iterator& last ) 00417 { 00418 if ( first != last ) 00419 { 00420 self_t t( *this ); 00421 t.init( first, last ); 00422 swap( t ); 00423 } 00424 } 00425 00433 template <class ForwardIterator> 00434 void append( ForwardIterator first, ForwardIterator last ) 00435 { 00436 append( first, last, append_directive ); 00437 } 00438 00452 template <class ForwardIterator, class Directive> 00453 void append( ForwardIterator first, ForwardIterator last, Directive directive ) 00454 { 00455 if ( first != last ) 00456 { 00457 self_t t( *this ); 00458 t.init( first, last, directive ); 00459 swap( t ); 00460 } 00461 } 00462 00469 void append( std::basic_istream<CharT, Traits>& istr ) 00470 { 00471 append( istr, append_directive ); 00472 } 00473 00486 template <class Directive> 00487 void append( std::basic_istream<CharT, Traits>& istr, Directive directive ) 00488 { 00489 self_t t( *this ); 00490 t.init( istr, directive ); 00491 swap( t ); 00492 } 00493 00499 void assign( const const_iterator& first, const const_iterator& last ) 00500 { 00501 self_t t( first, last ); 00502 swap( t ); 00503 } 00504 00511 template <class ForwardIterator> 00512 void assign( ForwardIterator first, ForwardIterator last ) 00513 { 00514 self_t t( first, last, append_directive ); 00515 swap( t ); 00516 } 00517 00530 template <class ForwardIterator, class Directive> 00531 void assign( ForwardIterator first, ForwardIterator last, Directive directive ) 00532 { 00533 self_t t( first, last, directive ); 00534 swap( t ); 00535 } 00536 00543 void assign( std::basic_istream<CharT, Traits>& istr ) 00544 { 00545 self_t t( istr, append_directive ); 00546 swap( t ); 00547 } 00548 00561 template <class Directive> 00562 void assign( std::basic_istream<CharT, Traits>& istr, Directive directive ) 00563 { 00564 self_t t( istr, directive ); 00565 swap( t ); 00566 } 00567 00572 void push_back( value_type value ) 00573 { 00574 if ( container_.empty() ) 00575 { 00576 line_buf buf( initial_line(), string_type( 1, value ) ); 00577 container_.push_back( buf ); 00578 } 00579 else 00580 { 00581 const string_type* pbuf = &container_.back().buf_; 00582 if ( pbuf_->at( pbuf_->size()-1 ) == widen( '\n' ) ) 00583 { 00584 line_buf buf( initial_line(), string_type( 1, value ) ); 00585 ++buf.line_.line_; 00586 container_.push_back( buf ); 00587 } 00588 else 00589 { 00590 container_.back().buf_ += value; 00591 } 00592 } 00593 } 00594 00598 void pop_back() 00599 { 00600 if ( container_.empty() ) 00601 { 00602 container_.pop_back(); 00603 } 00604 else 00605 { 00606 const string_type* pbuf = &container_.back().buf_; 00607 pbuf->resize( pbuf->size()-1 ); 00608 if ( container_.back().buf_.empty() ) 00609 { 00610 container_.pop_back(); 00611 } 00612 } 00613 } 00614 00619 bool empty() const 00620 { 00621 return container_.empty(); 00622 } 00623 00628 size_type size() const 00629 { 00630 return std::accumulate( container_.begin(), container_.end(), size_type( 0 ), add_line_size ); 00631 } 00632 00637 void swap( self_t& other ) 00638 { 00639 container_.swap( other.container_ ); 00640 line_.swap( other.line_ ); 00641 } 00642 00646 void clear() 00647 { 00648 container_.clear(); 00649 } 00650 private: 00652 void init( const const_iterator& first, const const_iterator& last ) 00653 { 00654 line_buf buf( *first.get_row() ); 00655 if ( first.get_col() > 0 ) 00656 { 00657 buf.buf_ = buf.buf_.substr( first.get_col() ); 00658 } 00659 container_.push_back( buf ); 00660 ++first; 00661 container_.append( first.get_row(), last.get_row() ); 00662 buf = *last.get_row(); 00663 buf.buf_ = buf.buf_.substr( 0, last.get_col() ); 00664 container_.push_back( buf ); 00665 } 00666 00668 template <class ForwardIterator, class Directive> 00669 void init( ForwardIterator first, ForwardIterator last, Directive directive ) 00670 { 00671 line_buf buf( initial_line() ); 00672 const value_type nl = widen( '\n' ); 00673 for ( ForwardIterator iter = first; iter != last; ++iter ) 00674 { 00675 value_type ch = *iter; 00676 buf.buf_ += ch; 00677 if ( ch == nl ) 00678 { 00679 directive( container_, buf ); 00680 line_ = buf.line_; 00681 } 00682 } 00683 if ( !buf.buf_.empty() ) 00684 { 00685 container_.push_back( buf ); 00686 } 00687 } 00688 00690 template <class Directive> 00691 void init( std::basic_istream<CharT, Traits>& istr, Directive directive ) 00692 { 00693 line_buf buf( initial_line() ); 00694 const value_type nl = widen( '\n' ); 00695 while ( istr ) 00696 { 00697 value_type ch; 00698 istr.get( ch ); 00699 buf.buf_ += ch; 00700 if ( ch == nl ) 00701 { 00702 directive( container_, buf ); 00703 line_ = buf.line_; 00704 } 00705 } 00706 if ( !buf.buf_.empty() ) 00707 { 00708 container_.push_back( buf ); 00709 } 00710 } 00711 00713 const line_type initial_line() const 00714 { 00715 if ( line_.line_ > 0 ) 00716 { 00717 return line_; 00718 } 00719 if ( container_.empty() ) 00720 { 00721 return line_type( "unknown", 1 ); 00722 } 00723 return container_.back().line_; 00724 } 00725 00727 static value_type widen( char ch ) 00728 { 00729 return ::toppers::widen<value_type>( ch ); 00730 } 00731 00733 static size_type add_line_size( size_type value, const line_buf& buf ) 00734 { 00735 return value + buf.buf_.size(); 00736 } 00737 00739 static void append_directive( container& cont, line_buf& buf ) 00740 { 00741 cont.push_back( buf ); 00742 ++buf.line_.line_; 00743 buf.buf_.clear(); 00744 } 00745 private: 00746 container container_; 00747 line_type line_; 00748 }; 00749 00750 typedef basic_text<std::vector, char> text; 00751 00752 inline const text_line& get_text_line( text::const_iterator iter ) 00753 { 00754 return iter.line(); 00755 } 00756 00757 inline const text_line& get_text_line( text::iterator iter ) 00758 { 00759 return iter.line(); 00760 } 00761 00762 } 00763 00764 #endif // ! TOPPERS_TEXT_HPP_ Copyright © 2006 by TAKAGI Nobuhisa. このページは Wed Apr 12 16:31:57 2006 に Doxygen によって生成されました。 |