Main Page | Namespace List | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

inode_writer.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 
00029 // inode_writer.h
00030 
00031 #ifndef _CTTL_INODE_WRITER_H_INCLUDED_
00032 #define _CTTL_INODE_WRITER_H_INCLUDED_
00033 
00034 #include <cassert>
00035 #include <vector>
00036 #include <iterator>
00037 #include <functional>
00038 
00039 namespace cttl {
00040 
00069 template< int PreviousLinkT = 1, int NextLinkT = 0, typename ContainerT = std::vector< int > >
00070 #ifdef __SGI_STL_PORT
00071 struct inode_writer : public stlport::bidirectional_iterator< inode_writer< PreviousLinkT, NextLinkT, ContainerT > > 
00072 #else
00073 struct inode_writer
00074 #endif
00075 {
00077     static const int previous_link_field = PreviousLinkT;
00078 
00080     static const int next_link_field = NextLinkT;
00081 
00083     typedef ContainerT container_T;
00084 
00086     typedef typename ContainerT::value_type        value_type;
00087 
00089     typedef inode_writer< PreviousLinkT, NextLinkT, ContainerT >       inode_T;
00090 
00092     typedef inode_writer< PreviousLinkT, NextLinkT, ContainerT >       iterator;
00093 
00095     typedef inode_writer< PreviousLinkT, NextLinkT, ContainerT >       const_iterator;
00096 
00098     typedef typename ContainerT::pointer       pointer;
00099 
00101     typedef typename ContainerT::reference        reference;
00102 
00104     typedef typename ContainerT::const_reference        const_reference;
00105 
00107     typedef typename ContainerT::size_type       size_type;
00108 
00110     typedef typename ContainerT::difference_type    difference_type;
00111 
00113     typedef std::bidirectional_iterator_tag iterator_category;
00114 
00115     // constructors
00116 
00118     inode_writer()
00119         :
00120         m_offset( 0 ),
00121         m_ptr_container( NULL )
00122     {
00123     }
00124 
00126     inode_writer( inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& other_ )
00127         :
00128         m_offset( other_.m_offset ),
00129         m_ptr_container( other_.m_ptr_container )
00130     {
00131     }
00132 
00134     inode_writer( ContainerT& container_ )
00135         :
00136         m_offset( container_.size() ),
00137         m_ptr_container( &container_ )
00138     {
00139     }
00140 
00142     inode_writer( ContainerT& container_, size_type offset_ )
00143         :
00144         m_offset( offset_ ),
00145         m_ptr_container( &container_ )
00146     {
00147     }
00148 
00150     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator=( inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& other_ )
00151     {
00152         if ( this != &other_ ) {
00153             m_offset = other_.m_offset;
00154             m_ptr_container = other_.m_ptr_container;
00155         }
00156 
00157         return *this;
00158     }
00159 
00161     const_reference operator*() const
00162     {
00163         return value( 0 );
00164     }
00165 
00167     reference operator*()
00168     {
00169         return value( 0 );
00170     }
00171 
00175     value_type const* operator->() const
00176     {
00177         return &value( 0 );
00178     }
00179 
00183     value_type* operator->()
00184     {
00185         return &value( 0 );
00186     }
00187 
00191     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator++()
00192     {
00193         ++m_offset;
00194         return *this;
00195     }
00196 
00200     inode_writer< PreviousLinkT, NextLinkT, ContainerT > operator++( int )
00201     {
00202         inode_writer< PreviousLinkT, NextLinkT, ContainerT > sibling( *this );
00203         ++m_offset;
00204         return sibling;
00205     }
00206 
00210     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator--()
00211     {
00212         --m_offset;
00213         return *this;
00214     }
00215 
00219     inode_writer< PreviousLinkT, NextLinkT, ContainerT > operator--( int )
00220     {
00221         inode_writer< PreviousLinkT, NextLinkT, ContainerT > sibling( *this );
00222         --m_offset;
00223         return sibling;
00224     }
00225 
00227     inode_writer< PreviousLinkT, NextLinkT, ContainerT > begin() const
00228     {
00229         return inode_writer< PreviousLinkT, NextLinkT, ContainerT >( *m_ptr_container, 0 );
00230     }
00231 
00233     inode_writer< PreviousLinkT, NextLinkT, ContainerT > begin( int offset_ ) const
00234     {
00235         return inode_writer< PreviousLinkT, NextLinkT, ContainerT >( *m_ptr_container, offset_ );
00236     }
00237 
00241     inode_writer< PreviousLinkT, NextLinkT, ContainerT > end() const
00242     {
00243         return begin( m_ptr_container->size() );
00244     }
00245 
00247     // Position and data access functions
00249 
00251     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator=( size_type size_ )
00252     {
00253         m_offset = size_;
00254         return *this;
00255     }
00257     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator+=( size_type size_ )
00258     {
00259         m_offset += size_;
00260         return *this;
00261     }
00263     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator-=( size_type size_ )
00264     {
00265         m_offset -= size_;
00266         return *this;
00267     }
00268 
00270     reference value( int field_ )
00271     {
00272         return (*m_ptr_container)[ m_offset + field_ ];
00273     }
00274 
00276     const_reference value( int field_ ) const
00277     {
00278         return (*m_ptr_container)[ m_offset + field_ ];
00279     }
00280 
00282     reference operator[] ( int field_ )
00283     {
00284         return value( field_ );
00285     }
00286 
00288     const_reference operator[] ( int field_ ) const
00289     {
00290         return value( field_ );
00291     }
00292 
00294     void offset( size_type offset_ )
00295     {
00296         m_offset = offset_;
00297     }
00298 
00300     size_type offset() const
00301     {
00302         return m_offset;
00303     }
00304 
00306     size_type& offset()
00307     {
00308         return m_offset;
00309     }
00310 
00312     // Link helper functions
00314 
00316     inode_writer< PreviousLinkT, NextLinkT, ContainerT > operator() ( int field_ ) const
00317     {
00318         return inode_writer< PreviousLinkT, NextLinkT, ContainerT >( *m_ptr_container, value( field_ ) );
00319     }
00320 
00322     int next_link() const
00323     {
00324         return NextLinkT;
00325     }
00326 
00328     int previous_link() const
00329     {
00330         return PreviousLinkT;
00331     }
00332 
00334     // Graph modeling functions
00336 
00338     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator<<=( int size_ )
00339     {
00340         // 0................m_ptr_container->size()
00341         // |                |
00342         // v                v
00343         // |--------|-fill->|<-resize->|
00344         //          ^                  ^
00345         //          |                  |
00346         //          m_offset...........size_
00347 
00348         assert( size_ ); // node size (number of elements to insert) should not be zero
00349 
00350         if ( m_offset == m_ptr_container->size() ) {
00351             m_ptr_container->insert(
00352                 m_ptr_container->end(), 
00353                 size_,          // number of elements to insert
00354                 value_type()    // value to insert
00355                 );
00356 
00357         } else {
00358             // is there an area to fill ?
00359             if ( m_offset < m_ptr_container->size() ) {
00360                 std::fill(
00361                     m_ptr_container->begin() + m_offset,
00362                     m_ptr_container->begin()
00363                     +
00364                     std::min(
00365                         m_offset + size_,
00366                         m_ptr_container->size()
00367                     ),
00368                     value_type()    // value to fill
00369                     );
00370             }
00371             // is there an area to resize ?
00372             if ( m_ptr_container->size() < m_offset + size_ ) {
00373                 m_ptr_container->resize(
00374                     m_offset + size_//,
00375                     //value_type()
00376                     );
00377             }
00378         }
00379 
00380         return *this;
00381     }
00382 
00383 #ifdef _XST_PAIR_H_INCLUDED_    // if lambda.h is included
00384 
00385     template< typename LambdaT >
00386     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator=( xst_lambda_wrap< LambdaT > const& lambda_ )
00387     {
00388         typedef typename ContainerT::iterator container_iterator_T;
00389         container_iterator_T container_iterator( m_ptr_container->begin() + m_offset );
00390         container_iterator << lambda_;
00391         return *this;
00392     }
00393 
00397     template< typename LambdaT >
00398     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator<<=( xst_lambda_wrap< LambdaT > const& lambda_ )
00399     {
00400         // is there enough space to accommodate lambda elements ?
00401         if ( m_ptr_container->size() < m_offset + lambda_.capacity_ ) {
00402             // yes
00403             m_ptr_container->resize( m_offset + lambda_.capacity_ );
00404         }
00405 
00406         return operator=( lambda_ );
00407     }
00408 #endif // _XST_PAIR_H_INCLUDED_
00409 
00411     template< typename RhsT >
00412     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator+= ( RhsT rhs_ )
00413     {
00414         value( NextLinkT ) = rhs_.offset();
00415         return *this;
00416     }
00417 
00419     template< typename RhsT >
00420     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator-= ( RhsT rhs_ )
00421     {
00422         rhs_.value( rhs_.previous_link() ) = offset();
00423         return *this;
00424     }
00425 
00427     template< typename RhsT >
00428     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator^= ( RhsT rhs_ )
00429     {
00430         *this += rhs_;
00431         *this -= rhs_;
00432         return *this;
00433     }
00434 
00436     template< typename RhsT >
00437     inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator*= ( RhsT child_ )
00438     {
00439         *this -= child_;         // negative link with first child
00440         while ( child_.value( child_.next_link_field )  ) {
00441             child_.offset( child_.value( child_.next_link_field ) );
00442             *this -= child_;     // negative link with next child
00443         }
00444 
00445         return *this;
00446     }
00447 
00449     ContainerT& container()
00450     {
00451         return *m_ptr_container;
00452     }
00453 
00455     ContainerT const& container() const
00456     {
00457         return *m_ptr_container;
00458     }
00459 
00460 protected:
00462     // inode_writer state variables
00464 
00466     size_type m_offset;
00467 
00469     ContainerT* m_ptr_container;
00470 
00471 }; // inode_writer
00472 
00473 // Overloaded binary operators
00474 
00479 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00480 inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& operator<<(
00481     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& lhs_,
00482     int size_
00483     )
00484 {
00485     inode_writer< PreviousLinkT, NextLinkT, ContainerT >* plhs_ = const_cast< inode_writer< PreviousLinkT, NextLinkT, ContainerT >* >( &lhs_ );
00486     plhs_->offset( lhs_.container().size() );
00487     if ( size_ ) {
00488         plhs_->container().resize( lhs_.offset() + size_ );
00489     }
00490 
00491     return lhs_;
00492 }
00493 
00494 #ifdef _XST_PAIR_H_INCLUDED_    // if lambda.h is included
00495 
00498 template< int PreviousLinkT, int NextLinkT, typename ContainerT, typename LambdaT >
00499 inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& operator<<(
00500     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& lhs_,
00501     xst_lambda_wrap< LambdaT > const& lambda_
00502     )
00503 {
00504     inode_writer< PreviousLinkT, NextLinkT, ContainerT >* plhs_ = const_cast< inode_writer< PreviousLinkT, NextLinkT, ContainerT >* >( &lhs_ );
00505     plhs_->offset( lhs_.container().size() );
00506     //container_inserter< ContainerT > inserter( plhs_->container() );
00507     //lambda_.traverse_top_down( inserter );
00508     std::back_insert_iterator< ContainerT > inserter( plhs_->container() );
00509     inserter << lambda_;
00510     return lhs_;
00511 }
00512 #endif // _XST_PAIR_H_INCLUDED_
00513 
00515 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00516 bool operator==(
00517     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_,
00518     typename ContainerT::size_type offset_
00519     )
00520 {
00521     return inode_.offset() == offset_;
00522 }
00523 
00525 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00526 bool operator==(
00527     typename ContainerT::size_type offset_,
00528     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00529     )
00530 {
00531     return offset_ == inode_.offset();
00532 }
00533 
00535 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00536 bool operator!=(
00537     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_,
00538     typename ContainerT::size_type offset_
00539     )
00540 {
00541     return inode_.offset() != offset_;
00542 }
00543 
00545 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00546 bool operator!=(
00547     typename ContainerT::size_type offset_,
00548     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00549     )
00550 {
00551     return offset_ != inode_.offset();
00552 }
00553 
00555 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00556 bool operator<(
00557     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_,
00558     typename ContainerT::size_type offset_
00559     )
00560 {
00561     return inode_.offset() < offset_;
00562 }
00563 
00565 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00566 bool operator<(
00567     typename ContainerT::size_type offset_,
00568     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00569     )
00570 {
00571     return offset_ < inode_.offset();
00572 }
00573 
00575 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00576 bool operator<=(
00577     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_,
00578     typename ContainerT::size_type offset_
00579     )
00580 {
00581     return inode_.offset() <= offset_;
00582 }
00583 
00585 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00586 bool operator<=(
00587     typename ContainerT::size_type offset_,
00588     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00589     )
00590 {
00591     return offset_ <= inode_.offset();
00592 }
00593 
00595 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00596 bool operator>(
00597     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_,
00598     typename ContainerT::size_type offset_
00599     )
00600 {
00601     return inode_.offset() > offset_;
00602 }
00603 
00605 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00606 bool operator>(
00607     typename ContainerT::size_type offset_,
00608     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00609     )
00610 {
00611     return offset_ > inode_.offset();
00612 }
00613 
00615 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00616 bool operator>=(
00617     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_,
00618     typename ContainerT::size_type offset_
00619     )
00620 {
00621     return inode_.offset() >= offset_;
00622 }
00623 
00625 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00626 bool operator>=(
00627     typename ContainerT::size_type offset_,
00628     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00629     )
00630 {
00631     return offset_ >= inode_.offset();
00632 }
00633 
00638 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00639 bool operator== (
00640     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& one_,
00641     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& another_
00642     )
00643 {
00644     return ( one_.offset() == another_.offset() );
00645 }
00646 
00648 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00649 bool operator!= (
00650     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& one_,
00651     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& another_
00652     )
00653 {
00654     return ( one_.offset() != another_.offset() );
00655 }
00656 
00658 template< int PreviousLinkT, int NextLinkT, typename ContainerT >
00659 bool operator! (
00660     inode_writer< PreviousLinkT, NextLinkT, ContainerT > const& inode_
00661     )
00662 {
00663     return !inode_.offset();
00664 }
00665 
00666 }   // namespace cttl
00667 
00668 #endif // _CTTL_INODE_WRITER_H_INCLUDED_

Generated on Thu Nov 2 17:43:39 2006 for CTTL Utility Classes and Functions by  doxygen 1.3.9.1