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

xtl_primary.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 
00070 // xtl_primary.h
00071 
00072 #ifndef _CTTL_XTL_PRIMARY_H_INCLUDED_
00073 #define _CTTL_XTL_PRIMARY_H_INCLUDED_
00074 
00075 #include <set>
00076 
00077 namespace cttl_impl {
00078 
00108 template< typename DerivedT >
00109 struct xtl_primary {
00110 
00135     template< typename UniverseT >
00136     size_t match( UniverseT& edge_ )
00137     {
00138         // check white space
00139         size_t saved_first_offset = edge_.space_policy().match( edge_ );
00140 
00141         if ( edge_.length() <= 0 ) {
00142             // restore original position
00143             edge_.first.offset( saved_first_offset );
00144             CTTL_TRACE_TEXT_RESULT( false, 'L', "empty universe" );
00145             return UniverseT::string_T::npos;
00146         }
00147 
00148         // edge_.first is now guaranteed to be outside white space
00149 
00150         size_t match_offset = static_cast< DerivedT* >( this )->internal_match( edge_ );
00151 
00152         if ( match_offset == UniverseT::string_T::npos ) {
00153             // match failed:
00154             // restore original position
00155             edge_.first.offset( saved_first_offset );
00156             return UniverseT::string_T::npos;
00157         }
00158 
00159         if ( edge_.length() < 0 ) {
00160             // although match suceeded, it is beyond universe bounds.
00161             // restore original position
00162             edge_.first.offset( saved_first_offset );
00163             CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme match out-of-universe bounds" );
00164             return UniverseT::string_T::npos;
00165         }
00166 
00167         // here:
00168         //  match_offset is starting position (upper boundary) of the matched symbol;
00169         //  edge_.first.offset() is symbol ending position (lower boundary);
00170         //  primary_length( match_offset, edge_ ) is symbol length.
00171 
00172         //  if primary_length() is greater than zero, then edge_.first.offset()
00173         //  minus 1 is points to the last character of the matched symbol.
00174 
00175         // check lower boundary of the lexeme against client regions:
00176         if ( primary_length( match_offset, edge_.first.offset() ) ) {
00177             // offset of the previous character
00178             size_t offset_minus_one = edge_.first.offset() - 1;
00179             if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
00180                 // No additional match attemts needed, because
00181                 // symbol is atomic object, it cannot be split by client regions.
00182                 // Upper bound of the symbol is inside client region.
00183                 // Restore original position and fail:
00184                 edge_.first.offset( saved_first_offset );
00185                 CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme match inside void space" );
00186                 return UniverseT::string_T::npos;
00187             }
00188         }
00189 
00190         // success
00191         return match_offset;
00192     }
00193 
00218     template< typename UniverseT >
00219     size_t find( UniverseT& edge_ )
00220     {
00221         size_t saved_first_offset = edge_.first.offset();
00222 
00223 replay_find:
00224         if ( edge_.length() <= 0 ) {
00225             // proposed universe is invalid
00226             // restore original position
00227             edge_.first.offset( saved_first_offset );
00228             CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: invalid universe" );
00229             return UniverseT::string_T::npos;
00230         }
00231 
00232         size_t offset_before_replay = edge_.first.offset();
00233         size_t match_offset = static_cast< DerivedT* >( this )->internal_find( edge_ );
00234 
00235         if ( match_offset == UniverseT::string_T::npos ) {
00236             // find failed:
00237             // restore original position
00238             edge_.first.offset( saved_first_offset );
00239             return UniverseT::string_T::npos;
00240         }
00241 
00242         // here:
00243         //  match_offset is starting position (upper boundary) of the matched symbol;
00244         //  edge_.first.offset() is symbol ending position (lower boundary);
00245         //  primary_length( match_offset, edge_ ) is symbol length.
00246 
00247         //  if primary_length() is greater than zero, then edge_.first.offset()
00248         //  minus 1 is points to the last character of the matched symbol.
00249 
00250         if ( edge_.length() < 0 ) {
00251             // find suceeded beyond lower boundary of the universe:
00252             // restore original position
00253             edge_.first.offset( saved_first_offset );
00254             CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: out-of-universe bounds" );
00255             return UniverseT::string_T::npos;
00256         }
00257 
00258         // Check if symbol boundaries are outside
00259         // existing client regions:
00260 
00261         if ( edge_.space_policy().lower_bound( match_offset, edge_ ) ) {
00262             // Upper boundary is inside of a client region.
00263             // Replay the search, if edge_.first.offset()
00264             // has made actual progress since last time:
00265             if ( offset_before_replay < edge_.first.offset() )
00266                 goto replay_find;
00267 
00268             edge_.first.offset( saved_first_offset );
00269             CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: lower bound inside void region" );
00270             return UniverseT::string_T::npos;
00271         }
00272 
00273         if ( primary_length( match_offset, edge_.first.offset() )
00274             &&
00275             edge_.space_policy().lower_bound( edge_.first.offset() - 1, edge_ ) )
00276         {
00277             // Lower boundary is inside a client region.
00278             // Replay the search, if edge_.first.offset()
00279             // has made actual progress since last time:
00280             if ( offset_before_replay < edge_.first.offset() )
00281                 goto replay_find;
00282 
00283             edge_.first.offset( saved_first_offset );
00284             CTTL_TRACE_TEXT_RESULT( false, 'L', "lexeme find: upper bound inside void region" );
00285             return UniverseT::string_T::npos;
00286         }
00287 
00288         // success
00289         return match_offset;
00290     }
00291 
00320     template< typename UniverseT >
00321     size_t bang_find( UniverseT& edge_ )
00322     {
00323         return find( edge_ );
00324     }
00325 
00326 protected:
00339     int primary_length( size_t upper_offset_, size_t lower_offset_ ) const
00340     {
00341         return lower_offset_ - upper_offset_;
00342     }
00343 
00344 };  // xtl_primary
00345 
00371 template< bool accept_emty_universe = false >
00372 class xtl_bool {
00373 
00374 private:
00375     bool m_value;
00376 
00377 public:
00378     // compile-time
00379 
00381     xtl_bool( bool value_ )
00382     : m_value( value_ )
00383     {
00384     }
00385 
00386     // run-time
00387 
00407     template< typename UniverseT >
00408     size_t match( UniverseT& edge_ )
00409     {
00410         if ( !accept_emty_universe && m_value && !edge_.length() ) {
00411             CTTL_TRACE_TEXT_RESULT( false, char( '0' + int( m_value ) ), "epsilon match: empty universe" );
00412             return UniverseT::string_T::npos;
00413         }
00414 
00415         return internal_match( edge_ );
00416     }
00417 
00437     template< typename UniverseT >
00438     size_t find( UniverseT& edge_ )
00439     {
00440         return internal_match( edge_ );
00441     }
00442 
00462     template< typename UniverseT >
00463     size_t bang_find( UniverseT& edge_ )
00464     {
00465         return internal_match( edge_ );
00466     }
00467 
00486     template< typename UniverseT >
00487     size_t internal_match( UniverseT& edge_ )
00488     {
00489         typedef typename UniverseT::char_T char_T;
00490         // edge state is ready;
00491         // set correct offset of this lexeme:
00492         if ( m_value ) {
00493             CTTL_TRACE_RESULT( true, char( '0' + int( m_value ) ) );
00494             return edge_.first.offset();
00495         } else {
00496             CTTL_TRACE_RESULT( false, char( '0' + int( m_value ) ) );
00497             return UniverseT::string_T::npos;
00498         }
00499     }
00500 
00501 };  // class xtl_bool
00502 
00503 
00515 template< typename StringT >
00516 class xtl_keyword {
00517 
00518 private:
00519     std::set< StringT > const& m_keywords;
00520 
00521 public:
00522     // compile-time
00523 
00525     xtl_keyword( std::set< StringT > const& keywords_ )
00526     : m_keywords( keywords_ )
00527     {
00528     }
00529 
00531     void operator=( xtl_keyword< StringT > const& ) const
00532     {
00533     }
00534 
00535     // run-time
00536 
00556     template< typename UniverseT >
00557     size_t match( UniverseT const& edge_ ) const
00558     {
00559         // edge state is ready;
00560         // return correct offset of this lexeme:
00561         if ( m_keywords.find( edge_.text() ) != m_keywords.end() ) {
00562             CTTL_TRACE_RESULT( true, 'S' );
00563             return edge_.first.offset();
00564         }
00565 
00566         CTTL_TRACE_RESULT( false, 'S' );
00567         return UniverseT::string_T::npos;
00568     }
00569 
00570 };  // xtl_keyword
00571 
00572 
00580 class xtl_char_symbol : public xtl_primary< xtl_char_symbol > {
00581 
00582 public:
00583 
00584     // run-time
00585 
00615     template< typename UniverseT >
00616     size_t find( UniverseT& edge_ )
00617     {
00618         return xtl_primary< xtl_char_symbol >::match( edge_ );
00619     }
00620 
00650     template< typename UniverseT >
00651     size_t bang_find( UniverseT& edge_ )
00652     {
00653         return xtl_primary< xtl_char_symbol >::match( edge_ );
00654     }
00655 
00686     template< typename UniverseT >
00687     size_t internal_match( UniverseT& edge_ )
00688     {
00689         // successful match
00690         // set match starting position
00691         size_t match_offset = edge_.first.offset();
00692         // set match ending position
00693         edge_.first.offset( match_offset + 1 );
00694         CTTL_TRACE_TEXT_RESULT( true, edge_.first[ -1 ], "symbol" );
00695         return match_offset;
00696     }
00697 
00698 };  // xtl_char_symbol
00699 
00700 
00711 template< typename CharT >
00712 class xtl_char : public xtl_primary< xtl_char< CharT > > {
00713 
00714 private:
00716     CharT m_char;
00717 
00718 public:
00719     // compile-time
00720 
00722     xtl_char( CharT char_ )
00723     : m_char( char_ )
00724     {
00725     }
00726 
00727     // run-time
00728 
00759     template< typename UniverseT >
00760     size_t internal_match( UniverseT& edge_ )
00761     {
00762         if ( edge_.parent().text()[ edge_.first.offset() ] == m_char ) {
00763             // successful match
00764             // set match starting position
00765             size_t match_offset = edge_.first.offset();
00766             // set match ending position
00767             edge_.first.offset( match_offset + 1 );
00768             CTTL_TRACE_TEXT_RESULT( true, m_char, "char" );
00769             return match_offset;
00770         }
00771 
00772         CTTL_TRACE_TEXT_RESULT( false, m_char, "char" );
00773         return UniverseT::string_T::npos;
00774     }
00775 
00806     template< typename UniverseT >
00807     size_t internal_find( UniverseT& edge_ )
00808     {
00809         size_t new_offset = edge_.parent().text().find( m_char, edge_.first.offset() );
00810         if ( new_offset != UniverseT::string_T::npos ) {
00811             // successful find
00812             // set find ending position
00813             edge_.first.offset( new_offset + 1 );
00814             CTTL_TRACE_TEXT_RESULT( true, m_char, "char" );
00815             return new_offset;
00816         }
00817 
00818         CTTL_TRACE_TEXT_RESULT( false, m_char, "char" );
00819         return UniverseT::string_T::npos;
00820     }
00821 };  // xtl_char
00822 
00823 
00835 template< typename CharT >
00836 class xtl_char_begin : public xtl_primary< xtl_char_begin< CharT > > {
00837 
00838 private:
00840     CharT m_char;
00841 
00842 public:
00843     // compile-time
00844 
00846     xtl_char_begin( CharT char_ )
00847     : m_char( char_ )
00848     {
00849     }
00850 
00851     // run-time
00852 
00871     template< typename UniverseT >
00872     size_t internal_match( UniverseT& edge_ )
00873     {
00874         if ( edge_.parent().text()[ edge_.first.offset() ] == m_char ) {
00875             // successful match
00876             CTTL_TRACE_TEXT_RESULT( true, m_char, "begin( char )" );
00877             // set match starting position
00878             return edge_.first.offset();
00879         }
00880 
00881         CTTL_TRACE_TEXT_RESULT( false, m_char, "begin( char )" );
00882         return UniverseT::string_T::npos;
00883     }
00884 
00903     template< typename UniverseT >
00904     size_t internal_find( UniverseT& edge_ )
00905     {
00906         size_t new_offset = edge_.parent().text().find( m_char, edge_.first.offset() );
00907         if ( new_offset != UniverseT::string_T::npos ) {
00908             // successful find
00909             // set find ending position
00910             edge_.first.offset( new_offset );
00911             CTTL_TRACE_TEXT_RESULT( true, m_char, "begin( char )" );
00912             return new_offset;
00913         }
00914 
00915         CTTL_TRACE_TEXT_RESULT( false, m_char, "begin( char )" );
00916         return UniverseT::string_T::npos;
00917     }
00918 
00919 };  // xtl_char_begin
00920 
00921 
00932 template< typename CharT >
00933 class xtl_char_end : public xtl_primary< xtl_char_end< CharT > > {
00934 
00935 private:
00937     CharT m_char;
00938 
00939 public:
00940     // compile-time
00941 
00943     xtl_char_end( CharT char_ )
00944     : m_char( char_ )
00945     {
00946     }
00947 
00948     // run-time
00949 
00968     template< typename UniverseT >
00969     size_t internal_match( UniverseT& edge_ )
00970     {
00971         if ( edge_.parent().text()[ edge_.first.offset() ] == m_char ) {
00972             // match starting and ending position are the same
00973             edge_.first.offset( edge_.first.offset() + 1 );
00974             CTTL_TRACE_TEXT_RESULT( true, m_char, "end( char )" );
00975             return edge_.first.offset();
00976         }
00977 
00978         CTTL_TRACE_TEXT_RESULT( false, m_char, "end( char )" );
00979         return UniverseT::string_T::npos;
00980     }
00981 
01000     template< typename UniverseT >
01001     size_t internal_find( UniverseT& edge_ )
01002     {
01003         size_t new_offset = edge_.parent().text().find( m_char, edge_.first.offset() );
01004         if ( new_offset != UniverseT::string_T::npos ) {
01005             // successful find
01006             // set find ending position
01007             edge_.first.offset( ++new_offset );
01008             CTTL_TRACE_TEXT_RESULT( true, m_char, "end( char )" );
01009             return new_offset;
01010         }
01011 
01012         CTTL_TRACE_TEXT_RESULT( false, m_char, "end( char )" );
01013         return UniverseT::string_T::npos;
01014     }
01015 };  // xtl_char_end
01016 
01017 
01018 
01026 class xtl_iswhat_begin : public xtl_primary< xtl_iswhat_begin > {
01027 
01028 private:
01030     iswhat_T m_iswhat;
01031 
01032 public:
01033     // compile-time
01034 
01036     xtl_iswhat_begin( iswhat_T iswhat_ )
01037     : m_iswhat( iswhat_ )
01038     {
01039     }
01040 
01041     // run-time
01042 
01061     template< typename UniverseT >
01062     size_t internal_match( UniverseT const& edge_ )
01063     {
01064         if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01065             // successful match: ending position is current:
01066             CTTL_TRACE_RESULT( true, '<' );
01067             return edge_.first.offset();
01068         }
01069         CTTL_TRACE_RESULT( false, '<' );
01070         return UniverseT::string_T::npos;
01071     }
01072 
01091     template< typename UniverseT >
01092     size_t internal_find( UniverseT& edge_ )
01093     {
01094         typename UniverseT::string_T const& str = edge_.parent().text();
01095         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01096 
01097         // find starting position
01098         it = std::find_if( it, str.end(), m_iswhat );
01099         if ( it == str.end() ) {
01100             CTTL_TRACE_RESULT( false, '<' );
01101             return UniverseT::string_T::npos;
01102         }
01103 
01104         size_t new_offset = std::distance( str.begin(), it );
01105         edge_.first.offset( new_offset );
01106         CTTL_TRACE_RESULT( true, '<' );
01107         return new_offset;
01108     }
01109 
01110 };  // xtl_iswhat_begin
01111 
01112 
01121 class xtl_iswhat_first : public xtl_primary< xtl_iswhat_first > {
01122 
01123 private:
01125     iswhat_T m_iswhat;
01126 
01127 public:
01128     // compile-time
01129 
01131     xtl_iswhat_first( iswhat_T iswhat_ )
01132     : m_iswhat( iswhat_ )
01133     {
01134     }
01135 
01136     // run-time
01137 
01168     template< typename UniverseT >
01169     size_t internal_match( UniverseT& edge_ )
01170     {
01171         if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01172             // successful match
01173             // set match starting position
01174             size_t match_offset = edge_.first.offset();
01175             // ending position:
01176             // at least one character in this entity is present
01177             edge_.first.offset( edge_.first.offset() + 1 );
01178             CTTL_TRACE_RESULT( true, 'F' );
01179             return match_offset;
01180         }
01181         CTTL_TRACE_RESULT( false, 'F' );
01182         return UniverseT::string_T::npos;
01183     }
01184 
01215     template< typename UniverseT >
01216     size_t internal_find( UniverseT& edge_ )
01217     {
01218         typename UniverseT::string_T const& str = edge_.parent().text();
01219         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01220 
01221         // find starting position
01222         it = std::find_if( it, str.end(), m_iswhat );
01223         if ( it == str.end() ) {
01224             CTTL_TRACE_RESULT( false, 'F' );
01225             return UniverseT::string_T::npos;
01226         }
01227 
01228         size_t new_offset = std::distance( str.begin(), it );
01229         // set find ending position:
01230         // at least one character in this entity is present
01231         edge_.first.offset( new_offset + 1 );
01232         CTTL_TRACE_RESULT( true, 'F' );
01233         return new_offset;
01234     }
01235 
01236 };  // xtl_iswhat_first
01237 
01238 
01246 class xtl_iswhat_end : public xtl_primary< xtl_iswhat_end > {
01247 
01248 private:
01250     iswhat_T m_iswhat;
01251 
01252 public:
01253     // compile-time
01254 
01256     xtl_iswhat_end( iswhat_T iswhat_ )
01257     : m_iswhat( iswhat_ )
01258     {
01259     }
01260 
01261     // run-time
01262 
01287     template< typename UniverseT >
01288     size_t match( UniverseT& edge_ )
01289     {
01290         size_t match_offset = xtl_primary< xtl_iswhat_end >::match( edge_ );
01291 
01292         if ( match_offset != UniverseT::string_T::npos ) {
01293             return edge_.first.offset();
01294         }
01295         return UniverseT::string_T::npos;
01296     }
01297 
01316     template< typename UniverseT >
01317     size_t internal_match( UniverseT& edge_ )
01318     {
01319         if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01320             // successful match
01321             // set match starting position
01322             size_t match_offset = edge_.first.offset();
01323 
01324             // find ending position
01325             typename UniverseT::string_T const& str = edge_.parent().text();
01326             typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01327             it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01328             // set ending position
01329             if ( it != str.end() )
01330                 edge_.first.offset( std::distance( str.begin(), it ) );
01331             else
01332                 edge_.first.offset( str.length() );
01333 
01334             CTTL_TRACE_RESULT( true, '>' );
01335             return match_offset;
01336 
01337         } else if ( edge_.first.offset() ) {
01338             // check if we are at the entity-end position:
01339             // offset of the previous character
01340             size_t offset_minus_one = edge_.first.offset() - 1;
01341             if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
01342                 // offset_minus_one is in the void space
01343                 CTTL_TRACE_RESULT( false, '>' );
01344                 return UniverseT::string_T::npos;
01345             }
01346 
01347             if ( m_iswhat( edge_.parent().text()[ offset_minus_one ] ) ) {
01348                 // successful match
01349                 CTTL_TRACE_RESULT( true, '>' );
01350                 return edge_.first.offset();
01351             }
01352         }
01353         CTTL_TRACE_RESULT( false, '>' );
01354         return UniverseT::string_T::npos;
01355     }
01356 
01375     template< typename UniverseT >
01376     size_t internal_find( UniverseT& edge_ )
01377     {
01378         typename UniverseT::string_T const& str = edge_.parent().text();
01379         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01380 
01381         // find starting position
01382         it = std::find_if( it, str.end(), m_iswhat );
01383         if ( it == str.end() ) {
01384             CTTL_TRACE_RESULT( false, '>' );
01385             return UniverseT::string_T::npos;
01386         }
01387 
01388         // find ending position
01389         size_t new_offset = UniverseT::string_T::npos;
01390         it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01391         if ( it != str.end() )
01392             new_offset = std::distance( str.begin(), it );
01393         else
01394             new_offset = str.length();
01395 
01396         // set find ending position
01397         edge_.first.offset( new_offset );
01398         CTTL_TRACE_RESULT( true, '>' );
01399         return new_offset;
01400     }
01401 
01402 };  // xtl_iswhat_end
01403 
01404 
01412 class xtl_iswhat_entity : public xtl_primary< xtl_iswhat_entity > {
01413 
01414 private:
01416     iswhat_T m_iswhat;
01417 
01418 public:
01419     // compile-time
01420 
01422     xtl_iswhat_entity( iswhat_T iswhat_ )
01423     : m_iswhat( iswhat_ )
01424     {
01425     }
01426 
01427     // run-time
01428 
01453     template< typename UniverseT >
01454     size_t internal_match( UniverseT& edge_ )
01455     {
01456         if ( m_iswhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01457             // successful match
01458             // set match starting position
01459             size_t match_offset = edge_.first.offset();
01460 
01461             // find ending position
01462             typename UniverseT::string_T const& str = edge_.parent().text();
01463             typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01464             it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01465             // set ending position
01466             if ( it != str.end() )
01467                 edge_.first.offset( std::distance( str.begin(), it ) );
01468             else
01469                 edge_.first.offset( str.length() );
01470 
01471             CTTL_TRACE_RESULT( true, '$' );
01472             return match_offset;
01473         }
01474         CTTL_TRACE_RESULT( false, '$' );
01475         return UniverseT::string_T::npos;
01476     }
01477 
01496     template< typename UniverseT >
01497     size_t internal_find( UniverseT& edge_ )
01498     {
01499         typename UniverseT::string_T const& str = edge_.parent().text();
01500         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01501 
01502         // find starting position
01503         it = std::find_if( it, str.end(), m_iswhat );
01504         if ( it == str.end() ) {
01505             CTTL_TRACE_RESULT( false, '$' );
01506             return UniverseT::string_T::npos;
01507         }
01508 
01509         size_t new_offset = std::distance( str.begin(), it );
01510         // set find starting position
01511         size_t match_offset = new_offset;
01512 
01513         // find ending position
01514         it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswhat ) ) );
01515         if ( it != str.end() )
01516             new_offset = std::distance( str.begin(), it );
01517         else
01518             new_offset = str.length();
01519 
01520         // set find ending position
01521         edge_.first.offset( new_offset );
01522         CTTL_TRACE_RESULT( true, '$' );
01523         return match_offset;
01524     }
01525 
01526 };  // xtl_iswhat_entity
01527 
01528 
01536 class xtl_iswwhat_begin : public xtl_primary< xtl_iswwhat_begin > {
01537 
01538 private:
01540     iswwhat_T m_iswwhat;
01541 
01542 public:
01543     // compile-time
01544 
01546     xtl_iswwhat_begin( iswwhat_T iswwhat_ )
01547     : m_iswwhat( iswwhat_ )
01548     {
01549     }
01550 
01551     // run-time
01552 
01571     template< typename UniverseT >
01572     size_t internal_match( UniverseT const& edge_ )
01573     {
01574         if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01575             // successful match: ending position is current:
01576             CTTL_TRACE_RESULT( true, '<' );
01577             return edge_.first.offset();
01578         }
01579         CTTL_TRACE_RESULT( false, '<' );
01580         return UniverseT::string_T::npos;
01581     }
01582 
01601     template< typename UniverseT >
01602     size_t internal_find( UniverseT& edge_ )
01603     {
01604         typename UniverseT::string_T const& str = edge_.parent().text();
01605         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01606 
01607         // find starting position
01608         it = std::find_if( it, str.end(), m_iswwhat );
01609         if ( it == str.end() ) {
01610             CTTL_TRACE_RESULT( false, '<' );
01611             return UniverseT::string_T::npos;
01612         }
01613 
01614         size_t new_offset = std::distance( str.begin(), it );
01615         // ending position is the same
01616         edge_.first.offset( new_offset );
01617         CTTL_TRACE_RESULT( true, '<' );
01618         return new_offset;
01619     }
01620 
01621 };  // xtl_iswwhat_begin
01622 
01623 
01632 class xtl_iswwhat_first : public xtl_primary< xtl_iswwhat_first > {
01633 
01634 private:
01636     iswwhat_T m_iswwhat;
01637 
01638 public:
01639     // compile-time
01640 
01642     xtl_iswwhat_first( iswwhat_T iswwhat_ )
01643     : m_iswwhat( iswwhat_ )
01644     {
01645     }
01646 
01647     // run-time
01648 
01679     template< typename UniverseT >
01680     size_t internal_match( UniverseT& edge_ )
01681     {
01682         if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01683             // successful match
01684             // set match starting position
01685             size_t match_offset = edge_.first.offset();
01686             // ending position: at least one character in this entity is present
01687             edge_.first.offset( edge_.first.offset() + 1 );
01688             CTTL_TRACE_RESULT( true, 'F' );
01689             return match_offset;
01690         }
01691         CTTL_TRACE_RESULT( false, 'F' );
01692         return UniverseT::string_T::npos;
01693     }
01694 
01725     template< typename UniverseT >
01726     size_t internal_find( UniverseT& edge_ )
01727     {
01728         typename UniverseT::string_T const& str = edge_.parent().text();
01729         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01730 
01731         // find starting position
01732         it = std::find_if( it, str.end(), m_iswwhat );
01733         if ( it == str.end() ) {
01734             CTTL_TRACE_RESULT( false, 'F' );
01735             return UniverseT::string_T::npos;
01736         }
01737 
01738         size_t new_offset = std::distance( str.begin(), it );
01739         // set find ending position: at least one character
01740         // in this entity is present
01741         edge_.first.offset( new_offset + 1 );
01742         CTTL_TRACE_RESULT( true, 'F' );
01743         return new_offset;
01744     }
01745 
01746 };  // xtl_iswwhat_first
01747 
01748 
01756 class xtl_iswwhat_end : public xtl_primary< xtl_iswwhat_end > {
01757 
01758 private:
01760     iswwhat_T m_iswwhat;
01761 
01762 public:
01763     // compile-time
01764 
01766     xtl_iswwhat_end( iswwhat_T iswwhat_ )
01767     : m_iswwhat( iswwhat_ )
01768     {
01769     }
01770 
01771     // run-time
01772 
01797     template< typename UniverseT >
01798     size_t match( UniverseT& edge_ )
01799     {
01800         size_t match_offset = xtl_primary< xtl_iswwhat_end >::match( edge_ );
01801 
01802         if ( match_offset != UniverseT::string_T::npos ) {
01803             return edge_.first.offset();
01804         }
01805         return UniverseT::string_T::npos;
01806     }
01807 
01826     template< typename UniverseT >
01827     size_t internal_match( UniverseT& edge_ )
01828     {
01829         if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01830             // successful match
01831             // set match starting position
01832             size_t match_offset = edge_.first.offset();
01833 
01834             // find ending position
01835             typename UniverseT::string_T const& str = edge_.parent().text();
01836             typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01837             it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
01838             // set ending position
01839             if ( it != str.end() )
01840                 edge_.first.offset( std::distance( str.begin(), it ) );
01841             else
01842                 edge_.first.offset( str.length() );
01843 
01844             CTTL_TRACE_RESULT( true, '>' );
01845             return match_offset;
01846 
01847         } else if ( edge_.first.offset() ) {
01848             // check if we are at the entity-end position:
01849             // offset of the previous character
01850             size_t offset_minus_one = edge_.first.offset() - 1;
01851             if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
01852                 // offset_minus_one is in the void space
01853                 CTTL_TRACE_RESULT( false, '>' );
01854                 return UniverseT::string_T::npos;
01855             }
01856 
01857             if ( m_iswwhat( edge_.parent().text()[ offset_minus_one ] ) ) {
01858                 // successful match
01859                 CTTL_TRACE_RESULT( true, '>' );
01860                 return edge_.first.offset();
01861             }
01862         }
01863         CTTL_TRACE_RESULT( false, '>' );
01864         return UniverseT::string_T::npos;
01865     }
01866 
01885     template< typename UniverseT >
01886     size_t internal_find( UniverseT& edge_ )
01887     {
01888         typename UniverseT::string_T const& str = edge_.parent().text();
01889         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01890 
01891         // find starting position
01892         it = std::find_if( it, str.end(), m_iswwhat );
01893         if ( it == str.end() ) {
01894             CTTL_TRACE_RESULT( false, '>' );
01895             return UniverseT::string_T::npos;
01896         }
01897 
01898         // find ending position
01899         size_t new_offset = UniverseT::string_T::npos;
01900         it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
01901         if ( it != str.end() )
01902             new_offset = std::distance( str.begin(), it );
01903         else
01904             new_offset = str.length();
01905 
01906         // set find ending position
01907         edge_.first.offset( new_offset );
01908         // note: LHS is always checked for void space.
01909         // because the length of this lexeme is zero,
01910         // test for RHS void space is never
01911         // attempted, which is the desired behavior
01912         CTTL_TRACE_RESULT( true, '>' );
01913         return new_offset;
01914     }
01915 
01916 };  // xtl_iswwhat_end
01917 
01918 
01926 class xtl_iswwhat_entity : public xtl_primary< xtl_iswwhat_entity > {
01927 
01928 private:
01930     iswwhat_T m_iswwhat;
01931 
01932 public:
01933     // compile-time
01934 
01936     xtl_iswwhat_entity( iswwhat_T iswwhat_ )
01937     : m_iswwhat( iswwhat_ )
01938     {
01939     }
01940 
01941     // run-time
01942 
01967     template< typename UniverseT >
01968     size_t internal_match( UniverseT& edge_ )
01969     {
01970         if ( m_iswwhat( edge_.parent().text()[ edge_.first.offset() ] ) ) {
01971             // successful match
01972             // set match starting position
01973             size_t match_offset = edge_.first.offset();
01974 
01975             // find ending position
01976             typename UniverseT::string_T const& str = edge_.parent().text();
01977             typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
01978             it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
01979             // set ending position
01980             if ( it != str.end() )
01981                 edge_.first.offset( std::distance( str.begin(), it ) );
01982             else
01983                 edge_.first.offset( str.length() );
01984 
01985             CTTL_TRACE_RESULT( true, '$' );
01986             return match_offset;
01987         }
01988         CTTL_TRACE_RESULT( false, '$' );
01989         return UniverseT::string_T::npos;
01990     }
01991 
02010     template< typename UniverseT >
02011     size_t internal_find( UniverseT& edge_ )
02012     {
02013         typename UniverseT::string_T const& str = edge_.parent().text();
02014         typename UniverseT::string_T::const_iterator it = str.begin() + edge_.first.offset();
02015 
02016         // find starting position
02017         it = std::find_if( it, str.end(), m_iswwhat );
02018         if ( it == str.end() ) {
02019             CTTL_TRACE_RESULT( false, '$' );
02020             return UniverseT::string_T::npos;
02021         }
02022 
02023         size_t new_offset = std::distance( str.begin(), it );
02024         // set find starting position
02025         size_t match_offset = new_offset;
02026 
02027         // find ending position
02028         it = std::find_if( it, str.end(), std::not1( std::ptr_fun( m_iswwhat ) ) );
02029         if ( it != str.end() )
02030             new_offset = std::distance( str.begin(), it );
02031         else
02032             new_offset = str.length();
02033 
02034         // set find ending position
02035         edge_.first.offset( new_offset );
02036         CTTL_TRACE_RESULT( true, '$' );
02037         return match_offset;
02038     }
02039 
02040 };  // xtl_iswwhat_entity
02041 
02042 
02054 template< typename StringT >
02055 class xtl_text_begin : public xtl_primary< xtl_text_begin< StringT > > {
02056 
02057 private:
02059     StringT m_any_text;
02060 
02061 public:
02062     // compile-time
02063 
02065     xtl_text_begin( StringT const& any_text_ )
02066         : m_any_text( any_text_ )
02067     {
02068     }
02069 
02070     // run-time
02071 
02090     template< typename UniverseT >
02091     size_t internal_match( UniverseT& edge_ )
02092     {
02093         typename UniverseT::string_T const& str = edge_.parent().text();
02094         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02095             // successful match
02096             // ending position is the same
02097             CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02098             return edge_.first.offset();
02099         }
02100 
02101         CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02102         return UniverseT::string_T::npos;
02103     }
02104 
02123     template< typename UniverseT >
02124     size_t internal_find( UniverseT& edge_ )
02125     {
02126         typename UniverseT::string_T const& str = edge_.parent().text();
02127         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02128         if ( new_offset != UniverseT::string_T::npos ) {
02129             // successful find
02130             // ending position is the same
02131             edge_.first.offset( new_offset );
02132             CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02133             return new_offset;
02134         }
02135 
02136         CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02137         return UniverseT::string_T::npos;
02138     }
02139 };  // xtl_text_begin
02140 
02141 
02153 template< typename StringT >
02154 class xtl_text_ref_begin : public xtl_primary< xtl_text_ref_begin< StringT > > {
02155 
02156 private:
02158     StringT const& m_any_text;
02159 
02160 public:
02161     // compile-time
02162 
02164     xtl_text_ref_begin( StringT const* str_ptr_ )
02165         : m_any_text( *str_ptr_ )
02166     {
02167     }
02168 
02170     void operator=( xtl_text_ref_begin< StringT > const& ) const
02171     {
02172     }
02173 
02174     // run-time
02175 
02194     template< typename UniverseT >
02195     size_t internal_match( UniverseT& edge_ )
02196     {
02197         typename UniverseT::string_T const& str = edge_.parent().text();
02198         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02199             // successful match
02200             // ending position is current
02201             CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02202             return edge_.first.offset();
02203         }
02204 
02205         CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02206         return UniverseT::string_T::npos;
02207     }
02208 
02227     template< typename UniverseT >
02228     size_t internal_find( UniverseT& edge_ )
02229     {
02230         typename UniverseT::string_T const& str = edge_.parent().text();
02231         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02232         if ( new_offset != UniverseT::string_T::npos ) {
02233             // successful find
02234             // ending position is the same
02235             edge_.first.offset( new_offset );
02236             CTTL_TRACE_TEXT_RESULT( true, '<', m_any_text.c_str() );
02237             return new_offset;
02238         }
02239 
02240         CTTL_TRACE_TEXT_RESULT( false, '<', m_any_text.c_str() );
02241         return UniverseT::string_T::npos;
02242     }
02243 };  // xtl_text_ref_begin
02244 
02245 
02257 template< typename StringT >
02258 class xtl_text_end : public xtl_primary< xtl_text_end< StringT > > {
02259 
02260 private:
02262     StringT m_any_text;
02263 
02264 public:
02265     // compile-time
02266 
02268     xtl_text_end( StringT const& any_text_ )
02269         : m_any_text( any_text_ )
02270     {
02271     }
02272 
02273     // run-time
02274 
02299     template< typename UniverseT >
02300     size_t match( UniverseT& edge_ )
02301     {
02302         size_t match_offset = xtl_primary< xtl_text_end >::match( edge_ );
02303         if ( match_offset != UniverseT::string_T::npos ) {
02304             return edge_.first.offset();
02305         }
02306         return UniverseT::string_T::npos;
02307     }
02308 
02327     template< typename UniverseT >
02328     size_t internal_match( UniverseT& edge_ )
02329     {
02330         typename UniverseT::string_T const& str = edge_.parent().text();
02331         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02332             // successful match
02333             // set match starting position
02334             size_t match_offset = edge_.first.offset();
02335 
02336             // find ending position
02337             size_t new_offset = str.find_first_not_of( m_any_text, edge_.first.offset() );
02338             if ( new_offset == UniverseT::string_T::npos )
02339                 new_offset = str.length();
02340 
02341             // set match ending position
02342             edge_.first.offset( new_offset );
02343             CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02344             return match_offset;
02345 
02346         } else if ( edge_.first.offset() ) {
02347             // check if we are at the entity-end position:
02348             // offset of the previous character
02349             size_t offset_minus_one = edge_.first.offset() - 1;
02350             if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
02351                 // offset_minus_one is in the void space
02352                 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02353                 return UniverseT::string_T::npos;
02354             }
02355 
02356             if ( m_any_text.find( str[ offset_minus_one ] ) != UniverseT::string_T::npos ) {
02357                 // successful match
02358                 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02359                 return edge_.first.offset();
02360             }
02361         }
02362 
02363         CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02364         return UniverseT::string_T::npos;
02365     }
02366 
02385     template< typename UniverseT >
02386     size_t internal_find( UniverseT& edge_ )
02387     {
02388         typename UniverseT::string_T const& str = edge_.parent().text();
02389         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02390         if ( new_offset != UniverseT::string_T::npos ) {
02391             // successful find
02392             // find ending position
02393             new_offset = str.find_first_not_of( m_any_text, new_offset );
02394             if ( new_offset == UniverseT::string_T::npos )
02395                 new_offset = str.length();
02396 
02397             // set ending position
02398             edge_.first.offset( new_offset );
02399             CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02400             return new_offset;
02401         }
02402 
02403         CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02404         return UniverseT::string_T::npos;
02405     }
02406 };  // xtl_text_end
02407 
02408 
02420 template< typename StringT >
02421 class xtl_text_ref_end : public xtl_primary< xtl_text_ref_end< StringT > > {
02422 
02423 private:
02425     StringT const& m_any_text;
02426 
02427 public:
02428     // compile-time
02429 
02431     xtl_text_ref_end( StringT const* str_ptr_ )
02432         : m_any_text( *str_ptr_ )
02433     {
02434     }
02435 
02437     void operator=( xtl_text_ref_end< StringT > const& ) const
02438     {
02439     }
02440 
02441     // run-time
02442 
02467     template< typename UniverseT >
02468     size_t match( UniverseT& edge_ )
02469     {
02470         size_t match_offset = xtl_primary< xtl_text_ref_end >::match( edge_ );
02471         if ( match_offset != UniverseT::string_T::npos ) {
02472             return edge_.first.offset();
02473         }
02474         return UniverseT::string_T::npos;
02475     }
02476 
02495     template< typename UniverseT >
02496     size_t internal_match( UniverseT& edge_ )
02497     {
02498         typename UniverseT::string_T const& str = edge_.parent().text();
02499         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02500             // successful match
02501             // set match starting position
02502             size_t match_offset = edge_.first.offset();
02503 
02504             // find ending position
02505             size_t new_offset = str.find_first_not_of( m_any_text, edge_.first.offset() );
02506             if ( new_offset == UniverseT::string_T::npos )
02507                 new_offset = str.length();
02508 
02509             // set match ending position
02510             edge_.first.offset( new_offset );
02511             CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02512             return match_offset;
02513 
02514         } else if ( edge_.first.offset() ) {
02515             // check if we are at the entity end position:
02516             // offset of the previous character
02517             size_t offset_minus_one = edge_.first.offset() - 1;
02518             if ( offset_minus_one != edge_.space_policy().lower_bound( offset_minus_one, edge_.second.offset() ) ) {
02519                 // offset_minus_one is in the void space
02520                 CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02521                 return UniverseT::string_T::npos;
02522             }
02523 
02524             if ( m_any_text.find( str[ offset_minus_one ] ) != UniverseT::string_T::npos ) {
02525                 // successful match
02526                 CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02527                 return edge_.first.offset();
02528             }
02529         }
02530 
02531         CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02532         return UniverseT::string_T::npos;
02533     }
02534 
02553     template< typename UniverseT >
02554     size_t internal_find( UniverseT& edge_ )
02555     {
02556         typename UniverseT::string_T const& str = edge_.parent().text();
02557         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02558         if ( new_offset != UniverseT::string_T::npos ) {
02559             // successful find
02560             // find ending position
02561             new_offset = str.find_first_not_of( m_any_text, new_offset );
02562             if ( new_offset == UniverseT::string_T::npos )
02563                 new_offset = str.length();
02564 
02565             // set ending position
02566             edge_.first.offset( new_offset );
02567             CTTL_TRACE_TEXT_RESULT( true, '>', m_any_text.c_str() );
02568             return new_offset;
02569         }
02570 
02571         CTTL_TRACE_TEXT_RESULT( false, '>', m_any_text.c_str() );
02572         return UniverseT::string_T::npos;
02573     }
02574 };  // xtl_text_ref_end
02575 
02576 
02588 template< typename StringT >
02589 class xtl_text_first : public xtl_primary< xtl_text_first< StringT > > {
02590 
02591 private:
02593     StringT m_any_text;
02594 
02595 public:
02596     // compile-time
02597 
02599     xtl_text_first( StringT const& any_text_ )
02600         : m_any_text( any_text_ )
02601     {
02602     }
02603 
02604     // run-time
02605 
02636     template< typename UniverseT >
02637     size_t internal_match( UniverseT& edge_ )
02638     {
02639         typename UniverseT::string_T const& str = edge_.parent().text();
02640         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02641             // successful match
02642             // set match starting position
02643             size_t match_offset = edge_.first.offset();
02644             // ending position: at least one character in this entity is present
02645             edge_.first.offset( edge_.first.offset() + 1 );
02646             CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02647             return match_offset;
02648         }
02649 
02650         CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02651         return UniverseT::string_T::npos;
02652     }
02653 
02684     template< typename UniverseT >
02685     size_t internal_find( UniverseT& edge_ )
02686     {
02687         typename UniverseT::string_T const& str = edge_.parent().text();
02688         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02689         if ( new_offset != UniverseT::string_T::npos ) {
02690             // successful find
02691             // set find ending position: at least one
02692             // character in this entity is present
02693             edge_.first.offset( new_offset + 1 );
02694             CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02695             return new_offset;
02696         }
02697 
02698         CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02699         return UniverseT::string_T::npos;
02700     }
02701 };  // xtl_text_first
02702 
02703 
02715 template< typename StringT >
02716 class xtl_text_ref_first : public xtl_primary< xtl_text_ref_first< StringT > > {
02717 
02718 private:
02720     StringT const& m_any_text;
02721 
02722 public:
02723     // compile-time
02724 
02726     xtl_text_ref_first( StringT const* str_ptr_ )
02727         : m_any_text( *str_ptr_ )
02728     {
02729     }
02730 
02732     void operator=( xtl_text_ref_first< StringT > const& ) const
02733     {
02734     }
02735 
02736     // run-time
02737 
02768     template< typename UniverseT >
02769     size_t internal_match( UniverseT& edge_ )
02770     {
02771         typename UniverseT::string_T const& str = edge_.parent().text();
02772         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02773             // successful match
02774             // set match starting position
02775             size_t match_offset = edge_.first.offset();
02776             // ending position: at least one character
02777             // in this entity is present
02778             edge_.first.offset( edge_.first.offset() + 1 );
02779             CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02780             return match_offset;
02781         }
02782 
02783         CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02784         return UniverseT::string_T::npos;
02785     }
02786 
02817     template< typename UniverseT >
02818     size_t internal_find( UniverseT& edge_ )
02819     {
02820         typename UniverseT::string_T const& str = edge_.parent().text();
02821         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02822         if ( new_offset != UniverseT::string_T::npos ) {
02823             // successful find
02824             // set find ending position: at least one character
02825             // in this entity is present
02826             edge_.first.offset( new_offset + 1 );
02827             CTTL_TRACE_TEXT_RESULT( true, 'F', m_any_text.c_str() );
02828             return new_offset;
02829         }
02830 
02831         CTTL_TRACE_TEXT_RESULT( false, 'F', m_any_text.c_str() );
02832         return UniverseT::string_T::npos;
02833     }
02834 };  // xtl_text_ref_first
02835 
02836 
02848 template< typename StringT >
02849 class xtl_text_entity : public xtl_primary< xtl_text_entity< StringT > > {
02850 
02851 private:
02853     StringT m_any_text;
02854 
02855 public:
02856     // compile-time
02857 
02859     xtl_text_entity( typename StringT::value_type const* any_text_ )
02860         : m_any_text( any_text_ )
02861     {
02862     }
02863 
02865     xtl_text_entity( StringT const& any_text_ )
02866         : m_any_text( any_text_ )
02867     {
02868     }
02869 
02870     // run-time
02871 
02890     template< typename UniverseT >
02891     size_t internal_match( UniverseT& edge_ )
02892     {
02893         typename UniverseT::string_T const& str = edge_.parent().text();
02894         if ( m_any_text.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
02895             // successful match
02896             // set match starting position
02897             size_t match_offset = edge_.first.offset();
02898 
02899             // find ending position
02900             size_t new_offset = str.find_first_not_of( m_any_text, edge_.first.offset() );
02901             if ( new_offset == UniverseT::string_T::npos )
02902                 new_offset = str.length();
02903 
02904             // set match ending position
02905             edge_.first.offset( new_offset );
02906             CTTL_TRACE_TEXT_RESULT( true, '$', m_any_text.c_str() );
02907             return match_offset;
02908         }
02909 
02910         CTTL_TRACE_TEXT_RESULT( false, '$', m_any_text.c_str() );
02911         return UniverseT::string_T::npos;
02912     }
02913 
02932     template< typename UniverseT >
02933     size_t internal_find( UniverseT& edge_ )
02934     {
02935         typename UniverseT::string_T const& str = edge_.parent().text();
02936         size_t new_offset = str.find_first_of( m_any_text, edge_.first.offset() );
02937         if ( new_offset != UniverseT::string_T::npos ) {
02938             // successful find
02939             // set find starting position
02940             size_t match_offset = new_offset;
02941 
02942             // find ending position
02943             new_offset = str.find_first_not_of( m_any_text, new_offset );
02944             if ( new_offset == UniverseT::string_T::npos )
02945                 new_offset = str.length();
02946 
02947             // set ending position
02948             edge_.first.offset( new_offset );
02949             CTTL_TRACE_TEXT_RESULT( true, '$', m_any_text.c_str() );
02950             return match_offset;
02951         }
02952 
02953         CTTL_TRACE_TEXT_RESULT( false, '$', m_any_text.c_str() );
02954         return UniverseT::string_T::npos;
02955     }
02956 };  // xtl_text_entity
02957 
02958 
02970 template< typename StringT >
02971 class xtl_text_ref_entity : public xtl_primary< xtl_text_ref_entity< StringT > > {
02972 
02973 private:
02975     StringT const& m_str_ref;
02976 
02977 public:
02978     // compile-time
02979 
02981     xtl_text_ref_entity( StringT const* str_ptr_ )
02982         : m_str_ref( *str_ptr_ )
02983     {
02984     }
02985 
02987     void operator=( xtl_text_ref_entity< StringT > const& ) const
02988     {
02989     }
02990 
02991     // run-time
02992 
03011     template< typename UniverseT >
03012     size_t internal_match( UniverseT& edge_ )
03013     {
03014         typename UniverseT::string_T const& str = edge_.parent().text();
03015         if ( m_str_ref.find( str[ edge_.first.offset() ] ) != UniverseT::string_T::npos ) {
03016             // successful match
03017             // set match starting position
03018             size_t match_offset = edge_.first.offset();
03019 
03020             // find ending position
03021             size_t new_offset = str.find_first_not_of( m_str_ref, edge_.first.offset() );
03022             if ( new_offset == UniverseT::string_T::npos )
03023                 new_offset = str.length();
03024 
03025             // set match ending position
03026             edge_.first.offset( new_offset );
03027             CTTL_TRACE_TEXT_RESULT( true, '$', m_str_ref.c_str() );
03028             return match_offset;
03029         }
03030 
03031         CTTL_TRACE_TEXT_RESULT( false, '$', m_str_ref.c_str() );
03032         return UniverseT::string_T::npos;
03033     }
03034 
03053     template< typename UniverseT >
03054     size_t internal_find( UniverseT& edge_ )
03055     {
03056         typename UniverseT::string_T const& str = edge_.parent().text();
03057         size_t new_offset = str.find_first_of( m_str_ref, edge_.first.offset() );
03058         if ( new_offset != UniverseT::string_T::npos ) {
03059             // successful find
03060             // set find starting position
03061             size_t match_offset = new_offset;
03062 
03063             // find ending position
03064             new_offset = str.find_first_not_of( m_str_ref, new_offset );
03065             if ( new_offset == UniverseT::string_T::npos )
03066                 new_offset = str.length();
03067 
03068             edge_.first.offset( new_offset );   // set ending position
03069             CTTL_TRACE_TEXT_RESULT( true, '$', m_str_ref.c_str() );
03070             return match_offset;
03071         }
03072 
03073         CTTL_TRACE_TEXT_RESULT( false, '$', m_str_ref.c_str() );
03074         return UniverseT::string_T::npos;
03075     }
03076 };  // xtl_text_ref_entity
03077 
03078 
03089 template< typename StringT >
03090 class xtl_text_symbol : public xtl_primary< xtl_text_symbol< StringT > > {
03091 
03092 private:
03094     StringT m_text;
03095 
03096 public:
03097     // compile-time
03098 
03100     xtl_text_symbol( StringT const& str_ref_ )
03101         : m_text( str_ref_ )
03102     {
03103     }
03104 
03105     // run-time
03106 
03137     template< typename UniverseT >
03138     size_t internal_match( UniverseT& edge_ )
03139     {
03140         typename UniverseT::string_T const& str = edge_.parent().text();
03141         if ( edge_.first.offset() + m_text.length() <= str.length() ) {
03142             if ( str.substr( edge_.first.offset(), m_text.length() ) == m_text ) {
03143                 // successful match
03144                 // set match starting position
03145                 size_t match_offset = edge_.first.offset();
03146                 // set match ending position
03147                 edge_.first.offset( edge_.first.offset() + m_text.length() );
03148                 CTTL_TRACE_TEXT_RESULT( true, 'T', m_text.c_str() );
03149                 return match_offset;
03150             }
03151         }
03152         
03153         CTTL_TRACE_TEXT_RESULT( false, 'T', m_text.c_str() );
03154         return UniverseT::string_T::npos;
03155     }
03156 
03187     template< typename UniverseT >
03188     size_t internal_find( UniverseT& edge_ )
03189     {
03190         size_t new_offset = edge_.parent().text().find( m_text, edge_.first.offset() );
03191         if ( new_offset != UniverseT::string_T::npos ) {
03192             // successful find
03193             // set find ending position
03194             edge_.first.offset( new_offset + m_text.length() );
03195             CTTL_TRACE_TEXT_RESULT( true, 'T', m_text.c_str() );
03196             return new_offset;
03197         }
03198 
03199         CTTL_TRACE_TEXT_RESULT( false, 'T', m_text.c_str() );
03200         return UniverseT::string_T::npos;
03201     }
03202 };  // xtl_text_symbol
03203 
03204 
03215 template< typename StringT >
03216 class xtl_text_ref_symbol : public xtl_primary< xtl_text_ref_symbol< StringT > > {
03217 
03218 private:
03220     StringT const& m_text_ref;
03221 
03222 public:
03223     // compile-time
03224 
03226     xtl_text_ref_symbol( StringT const* str_ptr_ )
03227         : m_text_ref( *str_ptr_ )
03228     {
03229     }
03230 
03232     void operator=( xtl_text_ref_symbol< StringT > const& )const
03233     {
03234     }
03235 
03236     // run-time
03237 
03268     template< typename UniverseT >
03269     size_t internal_match( UniverseT& edge_ )
03270     {
03271         typename UniverseT::string_T const& str = edge_.parent().text();
03272         if ( edge_.first.offset() + m_text_ref.length() <= str.length() ) {
03273             if ( str.substr( edge_.first.offset(), m_text_ref.length() ) == m_text_ref ) {
03274                 // successful match
03275                 // set match starting position
03276                 size_t match_offset = edge_.first.offset();
03277                 // set match ending position
03278                 edge_.first.offset( edge_.first.offset() + m_text_ref.length() );
03279                 CTTL_TRACE_TEXT_RESULT( true, 'T', m_text_ref.c_str() );
03280                 return match_offset;
03281             }
03282         }
03283 
03284         CTTL_TRACE_TEXT_RESULT( false, 'T', m_text_ref.c_str() );
03285         return UniverseT::string_T::npos;
03286     }
03287 
03318     template< typename UniverseT >
03319     size_t internal_find( UniverseT& edge_ )
03320     {
03321         size_t new_offset = edge_.parent().text().find(
03322             m_text_ref,
03323             edge_.first.offset()
03324             );
03325 
03326         if ( new_offset != UniverseT::string_T::npos ) {
03327             // successful find
03328             // set find ending position
03329             edge_.first.offset( new_offset + m_text_ref.length() );
03330             CTTL_TRACE_TEXT_RESULT( true, 'T', m_text_ref.c_str() );
03331             return new_offset;
03332         }
03333 
03334         CTTL_TRACE_TEXT_RESULT( false, 'T', m_text_ref.c_str() );
03335         return UniverseT::string_T::npos;
03336     }
03337 };  // xtl_text_ref_symbol
03338 
03339 
03347 class xtl_position_bof {
03348 
03349 public:
03350     // compile-time
03351     // nothing to do
03352 
03353     // run-time
03354 
03371     template< typename UniverseT >
03372     static size_t match( UniverseT& edge_ )
03373     {
03374         if ( edge_.first.offset() == 0 ) {
03375             CTTL_TRACE_RESULT( true, 'A' );
03376             return 0;
03377         }
03378         
03379         CTTL_TRACE_RESULT( false, 'A' );
03380         return UniverseT::string_T::npos;
03381     }
03382 
03397     template< typename UniverseT >
03398     static size_t find( UniverseT& edge_ )
03399     {
03400         // set beginning of the universe
03401         edge_.first.offset( 0 );
03402         CTTL_TRACE_RESULT( true, 'A' );
03403         return 0;
03404     }
03405 
03420     template< typename UniverseT >
03421     static size_t bang_find( UniverseT& edge_ )
03422     {
03423         return find( edge_ );
03424     }
03425 
03426 };  // xtl_position_bof
03427 
03428 
03436 class xtl_position_eof {
03437 
03438 public:
03439     // compile-time
03440     // nothing to do
03441 
03442     // run-time
03443 
03463     template< typename UniverseT >
03464     static size_t match( UniverseT& edge_ )
03465     {
03466         if ( !edge_.length() ) {
03467             CTTL_TRACE_STATIC_RESULT( true, 'Z', "EOF" );
03468             return edge_.second.offset();
03469         }
03470 
03471         if ( edge_.length() < 0 )
03472             return find( edge_ );
03473 
03474         // check for void/white space
03475         size_t saved_first_offset = edge_.space_policy().match( edge_ );
03476 
03477         if ( !edge_.length() ) {
03478             CTTL_TRACE_STATIC_RESULT( true, 'Z', "EOF" );
03479             return edge_.second.offset();
03480         }
03481 
03482         // restore original position
03483         edge_.first.offset( saved_first_offset );
03484         CTTL_TRACE_STATIC_RESULT( false, 'Z', "EOF" );
03485         return UniverseT::string_T::npos;
03486     }
03487 
03505     template< typename UniverseT >
03506     static size_t find( UniverseT& edge_ )
03507     {
03508         // set find ending position
03509         edge_.first.offset( edge_.second.offset() );
03510         CTTL_TRACE_STATIC_RESULT( true, 'Z', "EOF" );
03511         return edge_.second.offset();
03512     }
03513 
03531     template< typename UniverseT >
03532     static size_t bang_find( UniverseT& edge_ )
03533     {
03534         return find( edge_ );
03535     }
03536 
03537 };  // xtl_position_eof
03538 
03539 
03555 template< typename Static_predicateT >
03556 class xtl_predicate {
03557 
03559     Static_predicateT m_predicate;
03560 
03561 public:
03562 
03564     xtl_predicate( Static_predicateT const& predicate_ )
03565         :
03566         m_predicate( predicate_ )
03567     {
03568     }
03569 
03586     template< typename UniverseT >
03587     size_t match( UniverseT& edge_ )
03588     {
03589         CTTL_TRACE_LEVEL_MATCH( 'R' );
03590         return m_predicate( edge_ );
03591     }
03592 
03609     template< typename UniverseT >
03610     size_t find( UniverseT& edge_ )
03611     {
03612         CTTL_TRACE_LEVEL_FIND( 'R' );
03613         edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
03614         return m_predicate( edge_ );
03615     }
03616 
03633     template< typename UniverseT >
03634     size_t bang_find( UniverseT& edge_ )
03635     {
03636         CTTL_TRACE_LEVEL_BANG( 'R' );
03637         edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
03638         return m_predicate( edge_ );
03639     }
03640 
03641 };  // xtl_predicate
03642 
03643 
03659 template< typename ObjectT, typename Member_predicateT >
03660 class xtl_member_predicate {
03661 
03663     ObjectT& m_object;
03664 
03666     Member_predicateT m_predicate;
03667 
03668 public:
03669 
03671     xtl_member_predicate(
03672         ObjectT& object_ref_,
03673         Member_predicateT& predicate_
03674         )
03675         :
03676         m_object( object_ref_ ),
03677         m_predicate( predicate_ )
03678     {
03679     }
03680 
03682     void operator=( xtl_member_predicate< ObjectT, Member_predicateT > const& ) const
03683     {
03684     }
03685 
03702     template< typename UniverseT >
03703     size_t match( UniverseT& edge_ )
03704     {
03705         CTTL_TRACE_LEVEL_MATCH( 'R' );
03706         return std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ );
03707     }
03708 
03725     template< typename UniverseT >
03726     size_t find( UniverseT& edge_ )
03727     {
03728         CTTL_TRACE_LEVEL_FIND( 'R' );
03729         edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
03730         return std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ );
03731     }
03732 
03749     template< typename UniverseT >
03750     size_t bang_find( UniverseT& edge_ )
03751     {
03752         CTTL_TRACE_LEVEL_BANG( 'R' );
03753         edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
03754         return std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ );
03755     }
03756 
03757 };  // xtl_member_predicate
03758 
03759 
03765 struct xtl_traced_predicate_base {
03766 
03768     int m_line;
03769 
03771     std::string m_rule_name;
03772 
03774     xtl_traced_predicate_base( int line_, char const* rule_name_ )
03775         :
03776         m_line( line_ ),
03777         m_rule_name( rule_name_ )
03778     {
03779     }
03780 
03782     template< typename UniverseT >
03783     void trace_prolog( UniverseT& edge_, char const* mode_ )
03784     {
03785         xtl_trace_grammar::depth( +1 );
03786         std::cout << xtl_trace_grammar::exact_edge2text( edge_, true ).c_str();
03787         xtl_trace_grammar::build_skyline( '-' );
03788 
03789         std::cout
03790             << m_line
03791             << "->"
03792             << mode_
03793             << m_rule_name
03794             << '@'
03795             << edge_.first.offset()
03796             << '-'
03797             << edge_.second.offset()
03798             << std::endl
03799             ;
03800     }
03801 
03803     template< typename UniverseT >
03804     size_t trace_epilog( UniverseT& edge_, size_t result_ )
03805     {
03806         if ( result_ != CTTL_STD_STRING::npos ) {
03807             size_t begin_offset = result_;
03808             size_t end_offset = std::min(
03809                 begin_offset + xtl_trace_grammar::fragment_length,
03810                 edge_.first.offset()
03811                 );
03812 
03813             // needed in case if underlying fragment mutates:
03814             begin_offset = std::min( begin_offset, end_offset );
03815             end_offset = std::max( begin_offset, end_offset );
03816             std::string str_temp = edge_.parent().container().text_absolute_substring(
03817                 begin_offset,
03818                 end_offset
03819                 ).c_str();
03820 
03821             std::cout << xtl_trace_grammar::exact_edge2text( edge_, true ).c_str();
03822             xtl_trace_grammar::build_skyline( '+' );
03823             std::cout
03824                 << m_line
03825                 << "<-"
03826                 << m_rule_name
03827                 << '@'
03828                 << begin_offset
03829                 << '-'
03830                 << std::max( end_offset, edge_.first.offset() )
03831                 << '\t'
03832                 << '\''
03833                 << xtl_trace_grammar::whitespace2monospace( str_temp )
03834                 << '\''
03835                 << std::endl
03836                 ;
03837 
03838         } else {
03839             std::cout << xtl_trace_grammar::exact_edge2text( edge_, false ).c_str();
03840             xtl_trace_grammar::build_skyline( '~' );
03841             std::cout
03842                 << m_line
03843                 << "<-"
03844                 << m_rule_name
03845                 << '@'
03846                 << edge_.first.offset()
03847                 << std::endl
03848                 ;
03849         }
03850         xtl_trace_grammar::depth( -1 );
03851         return result_;
03852     }
03853 
03854 };  // xtl_traced_predicate_base
03855 
03856 
03872 template< typename ObjectT, typename Member_predicateT >
03873 class xtl_member_traced_predicate : public xtl_traced_predicate_base {
03874 
03876     ObjectT& m_object;
03877 
03879     Member_predicateT m_predicate;
03880 
03881 public:
03882 
03884     xtl_member_traced_predicate(
03885         int line_,
03886         char const* rule_name_,
03887         ObjectT& object_ref_,
03888         Member_predicateT& predicate_
03889         )
03890         :
03891         xtl_traced_predicate_base( line_, rule_name_ ),
03892         m_object( object_ref_ ),
03893         m_predicate( predicate_ )
03894     {
03895     }
03896 
03898     void operator=( xtl_member_traced_predicate< ObjectT, Member_predicateT > const& ) const
03899     {
03900     }
03901 
03918     template< typename UniverseT >
03919     size_t match( UniverseT& edge_ )
03920     {
03921         trace_prolog( edge_, "" );
03922         return trace_epilog(
03923             edge_,
03924             std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ )
03925             );
03926     }
03927 
03944     template< typename UniverseT >
03945     size_t find( UniverseT& edge_ )
03946     {
03947         edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
03948         trace_prolog( edge_, "!" );
03949         return trace_epilog(
03950             edge_,
03951             std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ )
03952             );
03953     }
03954 
03971     template< typename UniverseT >
03972     size_t bang_find( UniverseT& edge_ )
03973     {
03974         edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
03975         trace_prolog( edge_, "!!" );
03976         return trace_epilog(
03977             edge_,
03978             std::mem_fun< size_t, ObjectT, UniverseT& >( m_predicate )( &m_object, edge_ )
03979             );
03980     }
03981 
03982 };  // xtl_member_traced_predicate
03983 
03984 
03999 template< typename Static_predicateT >
04000 class xtl_static_traced_predicate : public xtl_traced_predicate_base {
04001 
04003     Static_predicateT m_predicate;
04004 
04005 public:
04006 
04008     xtl_static_traced_predicate(
04009         int line_,
04010         char const* rule_name_,
04011         Static_predicateT const& predicate_
04012         )
04013         :
04014         xtl_traced_predicate_base( line_, rule_name_ ),
04015         m_predicate( predicate_ )
04016     {
04017     }
04018 
04035     template< typename UniverseT >
04036     size_t match( UniverseT& edge_ )
04037     {
04038         trace_prolog( edge_, "" );
04039         return trace_epilog( edge_, m_predicate( edge_ ) );
04040     }
04041 
04058     template< typename UniverseT >
04059     size_t find( UniverseT& edge_ )
04060     {
04061         edge_.parent().container().m_flags.set( xtl_flag_runtime_find );
04062         trace_prolog( edge_, "!" );
04063         return trace_epilog( edge_, m_predicate( edge_ ) );
04064     }
04065 
04082     template< typename UniverseT >
04083     size_t bang_find( UniverseT& edge_ )
04084     {
04085         edge_.parent().container().m_flags.set( xtl_flag_runtime_bang_find );
04086         trace_prolog( edge_, "!!" );
04087         return trace_epilog( edge_, m_predicate( edge_ ) );
04088     }
04089 
04090 };  // xtl_static_traced_predicate
04091 
04092 
04118 template< typename Static_predicateT >
04119 inline xtl_wrap< xtl_static_traced_predicate< Static_predicateT > >
04120 xtl_traced_rule( int line_, char const* rule_name_, const Static_predicateT pred_ )
04121 {
04122     return xtl_wrap< xtl_static_traced_predicate< Static_predicateT > >(
04123         xtl_static_traced_predicate< Static_predicateT >(
04124             line_,
04125             rule_name_,
04126             pred_
04127             )
04128         );
04129 }
04130 
04160 template< typename ObjectT, typename PredicateT >
04161 inline xtl_wrap< xtl_member_traced_predicate< ObjectT, PredicateT > >
04162 xtl_traced_rule( int line_, char const* rule_name_, ObjectT& object_ref_, PredicateT pred_ )
04163 {
04164     return xtl_wrap< xtl_member_traced_predicate< ObjectT, PredicateT > >(
04165         xtl_member_traced_predicate< ObjectT, PredicateT >(
04166             line_,
04167             rule_name_,
04168             object_ref_,
04169             pred_ 
04170             )
04171         );
04172 }
04173 
04174 }   // namespace cttl_impl
04175 
04176 #endif // _CTTL_XTL_PRIMARY_H_INCLUDED_

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