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

edge.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 
00034 // edge.h
00035 
00036 #ifndef _CTTL_EDGE_H_INCLUDED_
00037 #define _CTTL_EDGE_H_INCLUDED_
00038 
00039 #include "const_edge.h"
00040 
00041 namespace cttl {
00042 
00062 template< typename PolicyT = policy_default, typename StringT = CTTL_STD_STRING >
00063 class edge : public const_edge< PolicyT, StringT > {
00064 public:
00066     typedef StringT string_T;
00067 
00069     typedef typename StringT::value_type char_T;
00070 
00072     typedef xtl_mutable_offset_manager< StringT > offset_manager_T;
00073 
00075     typedef PolicyT policy_T;
00076 
00085     typedef typename PolicyT::strict_policy_T strict_policy_T;
00086 
00091     typedef edge< strict_policy_T, StringT > strict_edge_T;
00092 
00094     typedef node< StringT > node_T;
00095 
00096 
00098     // Base class constructors not inherited, so they need to be redefined
00100 
00113     edge( input< StringT >& inp_, int start_, int finish_ )
00114         :
00115         const_edge< PolicyT, StringT >( inp_, start_, finish_ )
00116     {
00117     }
00118 
00128     edge( node< StringT >& node_first_, node< StringT >& node_second_ )
00129         :
00130         const_edge< PolicyT, StringT >( node_first_, node_second_ )
00131     {
00132     }
00133 
00150     template< typename Other_policyT >
00151     edge( const_edge< Other_policyT, StringT > const& other_ )
00152         :
00153         const_edge< PolicyT, StringT >( other_ )
00154     {
00155     }
00156 
00158     edge( const_edge< PolicyT, StringT > const& other_ )
00159         :
00160         const_edge< PolicyT, StringT >( other_ )
00161     {
00162     }
00163 
00185     template< typename Other_policyT >
00186     edge( const_edge< Other_policyT, StringT > const& other_, PolicyT& policy_ )
00187         :
00188         const_edge< PolicyT, StringT >( other_, policy_ )
00189     {
00190     }
00191 
00193     void text( StringT const& str_ )
00194     {
00195         text_replace( str_ );
00196     }
00197 
00199     void text( const_edge< PolicyT, StringT > const& other_ )
00200     {
00201         text_replace(
00202             other_.parent().container().text(),
00203             other_.first.offset(),
00204             other_.second.offset()
00205             );
00206     }
00207 
00209     StringT text() const
00210     {
00211         return const_edge< PolicyT, StringT >::text();
00212     }
00213 
00226     void text_swap( edge< PolicyT, StringT >& other_ )
00227     {
00228         const StringT str_this = text();
00229         text( other_.text() );
00230         other_.text( str_this );
00231     }
00232 
00234     // Overloaded assignment operators are not inherited, so they need to be redefined
00236 
00248     edge< PolicyT, StringT >& operator=( const_edge< PolicyT, StringT > const& other_ )
00249     {
00250         const_edge< PolicyT, StringT >::operator=( other_ );
00251         return *this;
00252     }
00253 
00263     edge< PolicyT, StringT >& operator= ( StringT const& str_ )
00264     {
00265         text( str_ );
00266         return *this;
00267     }
00268 
00270     // Conversion operators are inherited.
00271     // typedefs are inherited
00273 
00274 private:
00281     void text_replace( StringT const& str_ )
00282     {
00283         size_t str_length = str_.length();
00284         size_t offset_from_i = this->first.offset();
00285         size_t offset_to_i = this->second.offset();
00286 
00287         assert( offset_from_i <= offset_to_i );
00288         assert( offset_from_i <= this->parent().container().text().length() );
00289         assert( ( offset_to_i - offset_from_i ) <= this->parent().container().text().length() );
00290 
00291         this->parent().container().text().replace(
00292             offset_from_i,
00293             offset_to_i - offset_from_i,
00294             str_
00295             );
00296         
00297         int delta_offset = 
00298             int( offset_from_i - offset_to_i ) // negative length of old underlying substring
00299             +
00300             str_length                  // positive length of new underlying substring
00301             ;
00302 
00303         if ( !delta_offset )
00304             return; // nothing else to do
00305 
00306         this->space_policy().region_erase(
00307             offset_from_i,
00308             offset_to_i
00309             );
00310         
00311         this->space_policy().region_adjust(
00312             offset_from_i,
00313             delta_offset
00314             );
00315 
00316         size_t idx = 0;
00317         if ( delta_offset < 0 ) {
00318             xtl_identity_collapse< StringT > collapse(
00319                 offset_to_i,
00320                 delta_offset
00321                 );
00322 
00323             for ( idx = 0; idx < this->parent().container().identity_vector().size(); ++idx )
00324                 collapse.adjust( this->parent().container().identity_vector()[ idx ] );
00325 
00326             for ( idx = 0; idx < this->parent().container().offset_stack().size(); ++idx )
00327                 collapse.adjust( this->parent().container().offset_stack()[ idx ] );
00328 
00329         } else {
00330             xtl_identity_insert_go< StringT > insert_and_go(
00331                 offset_to_i,
00332                 delta_offset
00333                 );
00334 
00335             for ( idx = 0; idx < this->parent().container().identity_vector().size(); ++idx )
00336                 insert_and_go.adjust( this->parent().container().identity_vector()[ idx ] );
00337 
00338             for ( idx = 0; idx < this->parent().container().offset_stack().size(); ++idx )
00339                 insert_and_go.adjust( this->parent().container().offset_stack()[ idx ] );
00340 
00341         }
00342 
00343         this->first.offset( offset_from_i );
00344     }
00345 
00368     void text_replace(
00369         StringT const& str_,
00370         size_t source_from_offset_,
00371         size_t source_to_offset_
00372         )
00373     {
00374         size_t str_length = str_.length();
00375         size_t offset_from_i = this->first.offset();
00376         size_t offset_to_i = this->second.offset();
00377 
00378         assert( offset_from_i <= offset_to_i );
00379         assert( offset_from_i <= this->parent().container().text().length() );
00380         assert( ( offset_to_i - offset_from_i ) <= this->parent().container().text().length() );
00381 
00382         str_length = source_to_offset_ - source_from_offset_;
00383         this->parent().container().text().replace(
00384             offset_from_i,
00385             offset_to_i - offset_from_i,
00386             str_,
00387             source_from_offset_,
00388             str_length
00389             );
00390         
00391         int delta_offset = 
00392             offset_from_i - offset_to_i // negative length of old underlying substring
00393             +
00394             str_length                  // positive length of new underlying substring
00395             ;
00396 
00397         if ( !delta_offset )
00398             return; // nothing else to do
00399 
00400         this->space_policy().region_erase(
00401             offset_from_i,
00402             offset_to_i
00403             );
00404         
00405         this->space_policy().region_adjust(
00406             offset_from_i,
00407             delta_offset
00408             );
00409 
00410         size_t idx = 0;
00411         if ( delta_offset < 0 ) {
00412             xtl_identity_collapse< StringT > collapse(
00413                 offset_to_i,
00414                 delta_offset
00415                 );
00416 
00417             for ( idx = 0; idx < this->parent().container().identity_vector().size(); ++idx )
00418                 collapse.adjust( this->parent().container().identity_vector()[ idx ] );
00419 
00420             for ( idx = 0; idx < this->parent().container().offset_stack().size(); ++idx )
00421                 collapse.adjust( this->parent().container().offset_stack()[ idx ] );
00422 
00423         } else {
00424             xtl_identity_insert_go< StringT > insert_and_go(
00425                 offset_to_i,
00426                 delta_offset
00427                 );
00428 
00429             for ( idx = 0; idx < this->parent().container().identity_vector().size(); ++idx )
00430                 insert_and_go.adjust( this->parent().container().identity_vector()[ idx ] );
00431 
00432             for ( idx = 0; idx < this->parent().container().offset_stack().size(); ++idx )
00433                 insert_and_go.adjust( this->parent().container().offset_stack()[ idx ] );
00434 
00435         }
00436 
00437         this->first.offset( offset_from_i );
00438     }
00439 
00440 
00441 };  // class edge
00442 
00443 }   // namespace cttl
00444 
00445 
00446 #endif // _CTTL_EDGE_H_INCLUDED_

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