00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00032
00033
00034 #ifndef _CTTL_NODE_H_INCLUDED_
00035 #define _CTTL_NODE_H_INCLUDED_
00036
00037 #include "input.h"
00038 #include "xtl_base.h"
00039
00040 namespace cttl {
00041
00055 template< typename StringT = CTTL_STD_STRING >
00056 class node
00057 {
00058 protected:
00063 int m_identity;
00064
00066 input< StringT >& m_input;
00067
00068 public:
00070
00072
00074 typedef StringT string_T;
00075
00077 typedef typename StringT::value_type char_T;
00078
00080 typedef typename StringT::value_type value_type;
00081
00083 node( input< StringT >& inp_, int identity_ )
00084 :
00085 m_identity( identity_ ),
00086 m_input( inp_ )
00087 {
00088 }
00089
00091 node( node< StringT > const& other_, int identity_ )
00092 :
00093 m_identity( identity_ ),
00094 m_input( other_.m_input )
00095 {
00096 parent().container().identity_assign( m_identity, other_.m_identity );
00097 }
00098
00100 node( node< StringT > const& other_ )
00101 :
00102 m_identity( other_.m_identity ),
00103 m_input( other_.m_input )
00104 {
00105 }
00106
00111 node< StringT >& operator= ( node< StringT > const& other_ )
00112 {
00113 if ( this != &other_ )
00114 m_identity = other_.m_identity;
00115
00116 return *this;
00117 }
00118
00122 node< StringT >& operator= ( size_t offset_ )
00123 {
00124 parent().container().identity_go_offset( m_identity, offset_ );
00125 return *this;
00126 }
00127
00131 node< StringT >& operator+= ( StringT const& str_ )
00132 {
00133 insert_go( str_ );
00134 return *this;
00135 }
00136
00140 node< StringT >& operator-= ( StringT const& str_ )
00141 {
00142 insert_stay( str_ );
00143 return *this;
00144 }
00145
00147
00149
00151 input< StringT >& parent()
00152 {
00153 return m_input;
00154 }
00155
00157 input< StringT > const& parent() const
00158 {
00159 return m_input;
00160 }
00161
00162 public:
00164 int identity() const
00165 {
00166 return m_identity;
00167 }
00168
00170 int identity( int identity_ )
00171 {
00172 m_identity = identity_;
00173 return m_identity;
00174 }
00175
00182 template< typename PredicateT >
00183 bool find_class( PredicateT ( *iswhat_ )( PredicateT ) )
00184 {
00185 StringT const& str = parent().container().text();
00186 if ( iswhat_( str[ offset() ] ) ) {
00187
00188
00189 typename StringT::const_iterator it = str.begin() + offset();
00190 it = std::find_if( it, str.end(), std::not1( std::ptr_fun( iswhat_ ) ) );
00191 if ( it != str.end() )
00192 offset( std::distance( str.begin(), it ) );
00193 else
00194 offset( str.length() );
00195
00196 return true;
00197 }
00198 return false;
00199 }
00200
00207 template< typename PredicateT >
00208 bool rfind_class( PredicateT ( *iswhat_ )( PredicateT ) )
00209 {
00210 StringT const& str = parent().container().text();
00211 if ( offset() && iswhat_( str[ offset() - 1 ] ) ) {
00212
00213
00214 typename StringT::const_reverse_iterator it( str.begin() + offset() );
00215 typename StringT::const_reverse_iterator it_end( str.begin() );
00216 it = std::find_if( it, it_end, std::not1( std::ptr_fun( iswhat_ ) ) );
00217 offset( std::distance( it, it_end ) );
00218
00219 return true;
00220 }
00221 return false;
00222 }
00223
00225 size_t offset() const
00226 {
00227 return parent().container().identity_offset( m_identity );
00228 }
00229
00236 size_t offset( size_t offset_ )
00237 {
00238 return parent().container().identity_go_offset( m_identity, offset_ );
00239 }
00240
00242 size_t line() const
00243 {
00244 return parent().container().identity_get_line( m_identity );
00245 }
00246
00253 size_t go_line( size_t line_ )
00254 {
00255 return parent().container().identity_go_line( m_identity, line_ );
00256 }
00257
00259
00261
00269 size_t push()
00270 {
00271 return parent().container().push_identity( m_identity );
00272 }
00273
00278 size_t pop()
00279 {
00280 return parent().container().pop_identity( m_identity );
00281 }
00282
00287 void pop_discard()
00288 {
00289 parent().container().pop_offset();
00290 }
00291
00292
00299 size_t go_bof()
00300 {
00301 return parent().container().identity_go_bof( m_identity );
00302 }
00303
00310 size_t go_eof()
00311 {
00312 return parent().container().identity_go_eof( m_identity );
00313 }
00314
00321 size_t go_line_next()
00322 {
00323 return parent().container().identity_go_next_line( m_identity );
00324 }
00325
00332 size_t go_line_previous()
00333 {
00334 size_t current_line = line();
00335 if ( --current_line )
00336 return go_line( current_line );
00337 return offset();
00338 }
00339
00346 size_t go_line_home()
00347 {
00348 return parent().container().identity_go_line_home( m_identity );
00349 }
00350
00360 size_t go_line_home( size_t line_ )
00361 {
00362 go_line( line_ );
00363 return parent().container().identity_go_line_home( m_identity );
00364 }
00365
00372 size_t go_line_end()
00373 {
00374 return parent().container().identity_go_line_end( m_identity );
00375 }
00376
00386 size_t go_line_end( size_t line_ )
00387 {
00388 go_line( line_ );
00389 return parent().container().identity_go_line_end( m_identity );
00390 }
00391
00406 size_t insert_go( StringT const& str_ )
00407 {
00408 text_insert_go( str_ );
00409 return offset();
00410 }
00411
00423 void insert_stay( StringT const& str_ )
00424 {
00425 text_insert_stay( str_ );
00426 }
00427
00435 char_T const& operator[] ( int subscript_ ) const
00436 {
00437 return parent().container().text()[ offset() + subscript_ ];
00438 }
00439
00447 char_T& operator[] ( int subscript_ )
00448 {
00449 return parent().container().text()[ offset() + subscript_ ];
00450 }
00451
00453
00455
00469 template< typename ExprT >
00470 xtl_wrap<
00471 xtl_node<
00472 node< StringT >,
00473 xtl_wrap< ExprT >
00474 >
00475 >
00476 operator() ( xtl_wrap< ExprT > const& expr_ )
00477 {
00478
00479 typedef
00480 xtl_node<
00481 node< StringT >,
00482 xtl_wrap< ExprT >
00483 > xtl_node_T;
00484
00485 return xtl_wrap< xtl_node_T >( xtl_node_T( *this, expr_ ) );
00486 }
00487
00488 private:
00490 void text_insert_go( StringT const& str_ )
00491 {
00492 size_t str_length = str_.length();
00493
00494 if ( !str_.length() )
00495 return;
00496
00497 size_t insertion_offset = offset();
00498
00499 parent().container().text().insert(
00500 insertion_offset,
00501 str_
00502 );
00503
00504 xtl_identity_insert_go< StringT > insert_go(
00505 insertion_offset,
00506 int( str_length )
00507 );
00508
00509 size_t idx = 0;
00510 for ( idx = 0; idx < parent().container().identity_vector().size(); ++idx )
00511 insert_go.adjust( parent().container().identity_vector()[ idx ] );
00512
00513 for ( idx = 0; idx < parent().container().offset_stack().size(); ++idx )
00514 insert_go.adjust( parent().container().offset_stack()[ idx ] );
00515 }
00516
00518 void text_insert_go(
00519 StringT const& str_,
00520 size_t source_from_offset_,
00521 size_t source_to_offset_
00522 )
00523 {
00524 size_t str_length = source_to_offset_ - source_from_offset_;
00525
00526 if ( !str_.length() )
00527 return;
00528
00529 size_t insertion_offset = offset();
00530
00531 parent().container().text().insert(
00532 insertion_offset,
00533 str_,
00534 source_from_offset_,
00535 str_length
00536 );
00537
00538 xtl_identity_insert_go< StringT > insert_go(
00539 insertion_offset,
00540 int( str_length )
00541 );
00542
00543 size_t idx = 0;
00544 for ( idx = 0; idx < parent().container().identity_vector().size(); ++idx )
00545 insert_go.adjust( parent().container().identity_vector()[ idx ] );
00546
00547 for ( idx = 0; idx < parent().container().offset_stack().size(); ++idx )
00548 insert_go.adjust( parent().container().offset_stack()[ idx ] );
00549 }
00550
00552 void text_insert_stay( StringT const& str_ )
00553 {
00554 size_t str_length = str_.length();
00555
00556 if ( !str_length )
00557 return;
00558
00559 size_t insertion_offset = offset();
00560
00561 parent().container().text().insert(
00562 insertion_offset,
00563 str_
00564 );
00565
00566 xtl_identity_insert_stay< StringT > insert_stay(
00567 insertion_offset,
00568 str_length
00569 );
00570
00571 size_t idx = 0;
00572 for ( idx = 0; idx < parent().container().identity_vector().size(); ++idx )
00573 insert_stay.adjust( parent().container().identity_vector()[ idx ] );
00574
00575 for ( idx = 0; idx < parent().container().offset_stack().size(); ++idx )
00576 insert_stay.adjust( parent().container().offset_stack()[ idx ] );
00577 }
00578
00580 void text_insert_stay(
00581 StringT const& str_,
00582 size_t source_from_offset_,
00583 size_t source_to_offset_
00584 )
00585 {
00586 size_t str_length = source_to_offset_ - source_from_offset_;
00587
00588 if ( !str_length )
00589 return;
00590
00591 size_t insertion_offset = offset();
00592
00593 parent().container().text().insert(
00594 insertion_offset,
00595 str_,
00596 source_from_offset_,
00597 str_length
00598 );
00599
00600 xtl_identity_insert_stay< StringT > insert_stay(
00601 insertion_offset,
00602 str_length
00603 );
00604
00605 size_t idx = 0;
00606 for ( idx = 0; idx < parent().container().identity_vector().size(); ++idx )
00607 insert_stay.adjust( parent().container().identity_vector()[ idx ] );
00608
00609 for ( idx = 0; idx < parent().container().offset_stack().size(); ++idx )
00610 insert_stay.adjust( parent().container().offset_stack()[ idx ] );
00611 }
00612
00613 };
00614
00615
00631 template< typename StringT >
00632 inline node< StringT >
00633 new_node( input< StringT >& inp_, size_t offset_ )
00634 {
00635 return node< StringT >( inp_, inp_.container().identity_vector_push_back( offset_ ) );
00636 }
00637
00650 template< typename StringT >
00651 inline node< StringT >
00652 new_node( input< StringT >& inp_ )
00653 {
00654 return new_node< StringT >( inp_, inp_.length() );
00655 }
00656
00666 template< typename StringT >
00667 inline node< StringT >
00668 new_node( node< StringT >& other_ )
00669 {
00670 return node< StringT >(
00671 other_.parent(),
00672 other_.parent().container().identity_vector_push_back( other_.offset() )
00673 );
00674 }
00675
00676
00677
00679 template< typename StringT >
00680 bool operator== ( node< StringT > const& one_, node< StringT > const& another_ )
00681 {
00682 return one_.offset() == another_.offset();
00683 }
00684
00686 template< typename StringT >
00687 bool operator!= ( node< StringT > const& one_, node< StringT > const& another_ )
00688 {
00689 return one_.offset() != another_.offset();
00690 }
00691
00693 template< typename StringT >
00694 bool operator> ( node< StringT > const& one_, node< StringT > const& another_ )
00695 {
00696 return one_.offset() > another_.offset();
00697 }
00698
00700 template< typename StringT >
00701 bool operator< ( node< StringT > const& one_, node< StringT > const& another_ )
00702 {
00703 return one_.offset() < another_.offset();
00704 }
00705
00707 template< typename StringT >
00708 bool operator>= ( node< StringT > const& one_, node< StringT > const& another_ )
00709 {
00710 return one_.offset() >= another_.offset();
00711 }
00712
00714 template< typename StringT >
00715 bool operator<= ( node< StringT > const& one_, node< StringT > const& another_ )
00716 {
00717 return one_.offset() <= another_.offset();
00718 }
00719
00721 template< typename StringT >
00722 node< StringT >& operator++ ( node< StringT >& node_ )
00723 {
00724 node_.offset( node_.offset() + 1 );
00725 return node_;
00726 }
00727
00729 template< typename StringT >
00730 node< StringT >& operator-- ( node< StringT >& node_ )
00731 {
00732 node_.offset( node_.offset() - 1 );
00733 return node_;
00734 }
00735
00736 }
00737
00738 #endif // _CTTL_NODE_H_INCLUDED_