Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

node.h

Go to the documentation of this file.
00001 
00002 // Common Text Transformation Library
00003 // Copyright (C) 1997-2006 by Igor Kholodov. 
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the
00017 // Free Software Foundation, Inc.,
00018 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 //
00020 // mailto:cttl@users.sourceforge.net
00021 // http://sourceforge.net/projects/cttl/
00023 
00032 // node.h
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     // CONSTRUCTORS, CONVERSIONS, AND ASSIGNMENT OPERATORS OF THE NODE OBJECT //
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     // PROPERTIES OF THE NODE OBJECT //
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             // successful match found for the specified character class,
00188             // find ending position
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 ) ); // set ending position
00193             else
00194                 offset( str.length() ); // set ending position
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             // successful match found for the specified character class,
00213             // find beginning position for the character class:
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 ) );  // set beginning position
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     // VERBS OF THE NODE OBJECT //
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     // compile-time functions
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         // function-call operator must be a nonstatic member function
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; // nothing to do
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_, // a substring of the source string
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; // nothing to do
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; // nothing to do
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_, // a substring of the source string
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; // nothing to do
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 };  // class node
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 // Overloaded operators to compare nodes
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 }   // namespace cttl
00737 
00738 #endif // _CTTL_NODE_H_INCLUDED_

Generated on Thu Nov 2 17:44:06 2006 for Common Text Transformation Library by  doxygen 1.3.9.1