00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00029
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
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
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
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
00336
00338 inode_writer< PreviousLinkT, NextLinkT, ContainerT >& operator<<=( int size_ )
00339 {
00340
00341
00342
00343
00344
00345
00346
00347
00348 assert( size_ );
00349
00350 if ( m_offset == m_ptr_container->size() ) {
00351 m_ptr_container->insert(
00352 m_ptr_container->end(),
00353 size_,
00354 value_type()
00355 );
00356
00357 } else {
00358
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()
00369 );
00370 }
00371
00372 if ( m_ptr_container->size() < m_offset + size_ ) {
00373 m_ptr_container->resize(
00374 m_offset + size_
00375
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
00401 if ( m_ptr_container->size() < m_offset + lambda_.capacity_ ) {
00402
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_;
00440 while ( child_.value( child_.next_link_field ) ) {
00441 child_.offset( child_.value( child_.next_link_field ) );
00442 *this -= 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
00464
00466 size_type m_offset;
00467
00469 ContainerT* m_ptr_container;
00470
00471 };
00472
00473
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
00507
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 }
00667
00668 #endif // _CTTL_INODE_WRITER_H_INCLUDED_