00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00050
00051
00052 #ifndef _CTTL_XTL_OP_IMPL_H_INCLUDED_
00053 #define _CTTL_XTL_OP_IMPL_H_INCLUDED_
00054
00055 namespace cttl_impl {
00056
00058
00060
00071 template< typename ExprT >
00072 class xtl_op_base_unary {
00073
00074 protected:
00076 ExprT m_expr;
00077
00078 public:
00079
00080
00082 xtl_op_base_unary( ExprT const& expr_ )
00083 : m_expr( expr_ )
00084 {
00085 }
00086
00087 protected:
00111 template< typename UniverseT >
00112 size_t kleene_list( UniverseT& edge_, size_t upper_limit_ = 0 )
00113 {
00114
00115
00116 typename UniverseT::offset_manager_T iteration_offset( edge_.parent().container(), UniverseT::string_T::npos );
00117 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), UniverseT::string_T::npos );
00118
00119
00120
00121 size_t saved_end_offset = edge_.second.offset();
00122
00123 size_t cnt = 0;
00124 while ( ( match_offset = m_expr.match( edge_ ) ) != UniverseT::string_T::npos ) {
00125
00126
00127
00128
00129
00130
00131 if ( saved_end_offset == edge_.second.offset() ) {
00132 if ( iteration_offset == edge_.first.offset() ) {
00133 CTTL_TRACE_TEXT( 'i', "kleene_list: iteration made no progress: bailing out" );
00134 break;
00135 }
00136
00137 ++cnt;
00138
00139 if ( match_offset == edge_.first.offset() ) {
00140
00141
00142 CTTL_TRACE_TEXT( 'i', "kleene_list: epsilon match: bailing out" );
00143 break;
00144 }
00145
00146 } else {
00147 ++cnt;
00148 saved_end_offset = edge_.second.offset();
00149 }
00150
00151 if ( upper_limit_ && ( cnt == upper_limit_ ) ) {
00152 CTTL_TRACE_TEXT( 'i', "kleene_list: user-specified match limit: bailing out" );
00153 break;
00154 }
00155
00156 iteration_offset = edge_.first.offset();
00157 }
00158 return cnt;
00159 }
00160
00161 };
00162
00163
00180 template< typename Left_exprT, typename Right_exprT >
00181 class xtl_op_base_binary {
00182
00183 protected:
00185 Left_exprT m_expr_lhs;
00186
00188 Right_exprT m_expr_rhs;
00189
00190 public:
00191
00192
00193
00213 xtl_op_base_binary( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
00214 : m_expr_lhs( lhs_expr_ ), m_expr_rhs( rhs_expr_ )
00215 {
00216 }
00217
00218 };
00219
00220
00222
00224
00236 template< typename ExprT >
00237 struct xtl_opunarbang : public xtl_op_base_unary< ExprT > {
00238
00239
00240
00242 xtl_opunarbang( ExprT const& expr_ )
00243 : xtl_op_base_unary< ExprT >( expr_ )
00244 {
00245 }
00246
00247
00248
00265 template< typename UniverseT >
00266 size_t match( UniverseT& edge_ )
00267 {
00268 CTTL_TRACE_LEVEL_MATCH( '!' );
00269 return this->m_expr.find( edge_ );
00270 }
00271
00291 template< typename UniverseT >
00292 size_t find( UniverseT& edge_ )
00293 {
00294 CTTL_TRACE_LEVEL_FIND( '!' );
00295 return this->m_expr.bang_find( edge_ );
00296 }
00297
00318 template< typename UniverseT >
00319 size_t bang_find( UniverseT& edge_ )
00320 {
00321 CTTL_TRACE_LEVEL_BANG( '!' );
00322 return this->m_expr.bang_find( edge_ );
00323 }
00324
00325 };
00326
00327
00339 template< typename ExprT >
00340 class xtl_opunarstar : public xtl_op_base_unary< ExprT > {
00341
00342 protected:
00343
00345 size_t m_upper_limit;
00346
00347 public:
00348
00349
00359 xtl_opunarstar( ExprT const& expr_, size_t upper_limit_ = 0 )
00360 : xtl_op_base_unary< ExprT >( expr_ ), m_upper_limit( upper_limit_ )
00361 {
00362 }
00363
00364
00365
00390 template< typename UniverseT >
00391 size_t match( UniverseT& edge_ )
00392 {
00393
00394 CTTL_TRACE_LEVEL_MATCH( '*' );
00395 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
00396
00397
00398
00399 size_t saved_end_offset = edge_.second.offset();
00400 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), this->m_expr.match( edge_ ) );
00401
00402 if ( match_offset != UniverseT::string_T::npos ) {
00403
00404
00405
00406
00407
00408
00409 if ( saved_end_offset == edge_.second.offset() ) {
00410 if ( saved_first_offset == edge_.first.offset() ) {
00411
00412
00413 return match_offset;
00414 }
00415 }
00416
00417 if ( m_upper_limit ) {
00418
00419
00420
00421 if ( m_upper_limit == 1 ) {
00422
00423
00424 return match_offset;
00425 }
00426
00427
00428
00429 kleene_list( edge_, m_upper_limit - 1 );
00430
00431 } else
00432
00433 kleene_list( edge_ );
00434
00435 } else {
00436
00437
00438 return saved_first_offset;
00439 }
00440
00441 return match_offset;
00442 }
00443
00468 template< typename UniverseT >
00469 size_t find( UniverseT& edge_ )
00470 {
00471
00472 CTTL_TRACE_LEVEL_FIND( '*' );
00473 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
00474
00475
00476
00477
00478 size_t saved_end_offset = edge_.second.offset();
00479 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), this->m_expr.find( edge_ ) );
00480
00481 if ( match_offset != UniverseT::string_T::npos ) {
00482
00483
00484
00485
00486
00487 if ( saved_end_offset == edge_.second.offset() ) {
00488 if ( saved_first_offset == edge_.first.offset() ) {
00489
00490
00491 return match_offset;
00492 }
00493 }
00494
00495 if ( m_upper_limit ) {
00496
00497
00498
00499 if ( m_upper_limit == 1 ) {
00500
00501
00502 return match_offset;
00503 }
00504
00505
00506
00507 kleene_list( edge_, m_upper_limit - 1 );
00508
00509 } else
00510
00511 kleene_list( edge_ );
00512
00513 } else {
00514
00515
00516 return saved_first_offset;
00517 }
00518
00519 return match_offset;
00520 }
00521
00547 template< typename UniverseT >
00548 size_t bang_find( UniverseT& edge_ )
00549 {
00550
00551 CTTL_TRACE_LEVEL_BANG( '*' );
00552 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
00553
00554
00555
00556 size_t saved_end_offset = edge_.second.offset();
00557 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), this->m_expr.bang_find( edge_ ) );
00558
00559 if ( match_offset != UniverseT::string_T::npos ) {
00560
00561
00562
00563
00564
00565
00566 if ( saved_end_offset == edge_.second.offset() ) {
00567 if ( saved_first_offset == edge_.first.offset() ) {
00568
00569
00570 return match_offset;
00571 }
00572 }
00573
00574 if ( m_upper_limit ) {
00575
00576
00577
00578 if ( m_upper_limit == 1 ) {
00579
00580
00581 return match_offset;
00582 }
00583
00584
00585
00586 kleene_list( edge_, m_upper_limit - 1 );
00587
00588 } else
00589
00590 kleene_list( edge_ );
00591
00592 } else {
00593
00594
00595 return saved_first_offset;
00596 }
00597
00598 return match_offset;
00599 }
00600
00601 };
00602
00603
00615 template< typename ExprT >
00616 class xtl_opunarminus : public xtl_op_base_unary< ExprT > {
00617
00618 public:
00619
00620
00627 xtl_opunarminus( ExprT const& expr_ )
00628 : xtl_op_base_unary< ExprT >( expr_ )
00629 {
00630 }
00631
00632
00633
00654 template< typename UniverseT >
00655 size_t match( UniverseT& edge_ )
00656 {
00657
00658 CTTL_TRACE_LEVEL_MATCH( '-' );
00659 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
00660 size_t match_offset = this->m_expr.match( edge_ );
00661
00662 if ( match_offset != UniverseT::string_T::npos ) {
00663
00664
00665 edge_.first.offset( saved_first_offset );
00666 CTTL_TRACE_RESULT( false, '-' );
00667 return UniverseT::string_T::npos;
00668 }
00669
00670
00671
00672 return saved_first_offset;
00673 }
00674
00675
00696 template< typename UniverseT >
00697 size_t find( UniverseT& edge_ )
00698 {
00699
00700 CTTL_TRACE_LEVEL_FIND( '-' );
00701 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
00702 size_t match_offset = this->m_expr.find( edge_ );
00703
00704 if ( match_offset != UniverseT::string_T::npos ) {
00705
00706
00707 edge_.first.offset( saved_first_offset );
00708 CTTL_TRACE_RESULT( false, '-' );
00709 return UniverseT::string_T::npos;
00710 }
00711
00712
00713
00714 return saved_first_offset;
00715 }
00716
00717
00739 template< typename UniverseT >
00740 size_t bang_find( UniverseT& edge_ )
00741 {
00742
00743 CTTL_TRACE_LEVEL_BANG( '-' );
00744 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
00745 size_t match_offset = this->m_expr.bang_find( edge_ );
00746
00747 if ( match_offset != UniverseT::string_T::npos ) {
00748
00749
00750 edge_.first.offset( saved_first_offset );
00751 CTTL_TRACE_RESULT( false, '-' );
00752 return UniverseT::string_T::npos;
00753 }
00754
00755
00756
00757 return saved_first_offset;
00758 }
00759
00760 };
00761
00762
00779 template< typename ExprT >
00780 class xtl_opunarplus : public xtl_op_base_unary< ExprT > {
00781
00782 protected:
00784 size_t m_upper_limit;
00785
00787 size_t m_lower_limit;
00788
00807 template< typename UniverseT >
00808 size_t unarplus( UniverseT& edge_, size_t saved_end_offset_, size_t first_match_offset_ )
00809 {
00810 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), first_match_offset_ );
00811
00812 if ( match_offset != UniverseT::string_T::npos ) {
00813
00814
00815
00816
00817
00818 if ( saved_end_offset_ == edge_.second.offset() ) {
00819 if ( match_offset == edge_.first.offset() ) {
00820
00821
00822 if ( !m_upper_limit )
00823 return match_offset;
00824
00825 if ( ( m_lower_limit <= 1 ) && ( 1 <= m_upper_limit ) )
00826 return match_offset;
00827
00828 CTTL_TRACE_TEXT_RESULT( false, '+', "kleene plus: too few matches (one epsilon found)" );
00829 return UniverseT::string_T::npos;
00830 }
00831 }
00832
00833 if ( m_upper_limit ) {
00834 if ( m_upper_limit == 1 )
00835
00836 return match_offset;
00837
00838
00839
00840 if ( m_lower_limit ) {
00841
00842 size_t cnt = kleene_list( edge_, m_upper_limit ) + 1;
00843 if ( cnt > m_upper_limit ) {
00844 CTTL_TRACE_TEXT_RESULT( false, '+', "kleene plus: too many matches" );
00845 return UniverseT::string_T::npos;
00846
00847 }
00848
00849 if ( cnt < m_lower_limit ) {
00850
00851 CTTL_TRACE_TEXT_RESULT( false, '+', "kleene plus: too few matches" );
00852 return UniverseT::string_T::npos;
00853 }
00854
00855 } else {
00856
00857
00858 kleene_list( edge_, m_upper_limit - 1 );
00859 }
00860
00861 } else
00862
00863
00864 kleene_list( edge_ );
00865
00866 return match_offset;
00867 }
00868
00869 CTTL_TRACE_RESULT( false, '+' );
00870 return UniverseT::string_T::npos;
00871 }
00872
00873 public:
00874
00875
00876
00889 xtl_opunarplus( ExprT const& expr_, size_t upper_limit_ = 0, size_t lower_limit_ = 0 )
00890 : xtl_op_base_unary< ExprT >( expr_ ), m_upper_limit( upper_limit_ ), m_lower_limit( lower_limit_ )
00891 {
00892 }
00893
00894
00895
00896
00922 template< typename UniverseT >
00923 size_t match( UniverseT& edge_ )
00924 {
00925
00926 CTTL_TRACE_LEVEL_MATCH( '+' );
00927 size_t saved_end_offset = edge_.second.offset();
00928 return unarplus( edge_, saved_end_offset, this->m_expr.match( edge_ ) );
00929 }
00930
00931
00957 template< typename UniverseT >
00958 size_t find( UniverseT& edge_ )
00959 {
00960
00961 CTTL_TRACE_LEVEL_FIND( '+' );
00962 size_t saved_end_offset = edge_.second.offset();
00963 return unarplus( edge_, saved_end_offset, this->m_expr.find( edge_ ) );
00964 }
00965
00966
00992 template< typename UniverseT >
00993 size_t bang_find( UniverseT& edge_ )
00994 {
00995
00996 CTTL_TRACE_LEVEL_BANG( '+' );
00997 size_t saved_end_offset = edge_.second.offset();
00998 return unarplus( edge_, saved_end_offset, this->m_expr.bang_find( edge_ ) );
00999 }
01000
01001 };
01002
01003
01016 template< typename ExprT >
01017 struct xtl_entity : public xtl_op_base_unary< ExprT > {
01018
01019
01020
01027 xtl_entity( ExprT const& expr_ )
01028 : xtl_op_base_unary< ExprT >( expr_ )
01029 {
01030 }
01031
01032
01033
01058 template< typename UniverseT >
01059 size_t match( UniverseT& edge_ )
01060 {
01061 CTTL_TRACE_LEVEL_MATCH( 'E' );
01062 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), this->m_expr.match( edge_ ) );
01063 if ( ( match_offset != UniverseT::string_T::npos ) && ( match_offset != edge_.first.offset() ) )
01064 return match_offset;
01065
01066 return UniverseT::string_T::npos;
01067 }
01068
01069
01094 template< typename UniverseT >
01095 size_t find( UniverseT& edge_ )
01096 {
01097 CTTL_TRACE_LEVEL_FIND( 'E' );
01098 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), this->m_expr.find( edge_ ) );
01099 if ( ( match_offset != UniverseT::string_T::npos ) && ( match_offset != edge_.first.offset() ) )
01100 return match_offset;
01101
01102 return UniverseT::string_T::npos;
01103 }
01104
01105
01130 template< typename UniverseT >
01131 size_t bang_find( UniverseT& edge_ )
01132 {
01133 CTTL_TRACE_LEVEL_BANG( 'E' );
01134 typename UniverseT::offset_manager_T match_offset( edge_.parent().container(), this->m_expr.bang_find( edge_ ) );
01135 if ( ( match_offset != UniverseT::string_T::npos ) && ( match_offset != edge_.first.offset() ) )
01136 return match_offset;
01137
01138 return UniverseT::string_T::npos;
01139 }
01140
01141 };
01142
01143
01145
01147
01165 template< typename Left_exprT, typename Right_exprT >
01166 struct xtl_opbinplus : public xtl_op_base_binary< Left_exprT, Right_exprT > {
01167
01168
01169
01189 xtl_opbinplus( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
01190 : xtl_op_base_binary< Left_exprT, Right_exprT >( lhs_expr_, rhs_expr_ )
01191 {
01192 }
01193
01194
01195
01220 template< typename UniverseT >
01221 size_t match( UniverseT& edge_ )
01222 {
01223
01224
01225 CTTL_TRACE_LEVEL_MATCH( ';' );
01226 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
01227 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.match( edge_ ) );
01228
01229 if (
01230 ( match_lhs_offset != UniverseT::string_T::npos )
01231 &&
01232 ( this->m_expr_rhs.match( edge_ ) != UniverseT::string_T::npos )
01233 )
01234 return match_lhs_offset;
01235
01236
01237 edge_.first.offset( saved_first_offset );
01238 return UniverseT::string_T::npos;
01239 }
01240
01241
01266 template< typename UniverseT >
01267 size_t find( UniverseT& edge_ )
01268 {
01269
01270 CTTL_TRACE_LEVEL_FIND( ';' );
01271 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
01272 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.find( edge_ ) );
01273
01274 if (
01275 ( match_lhs_offset != UniverseT::string_T::npos )
01276 &&
01277 ( this->m_expr_rhs.match( edge_ ) != UniverseT::string_T::npos )
01278 )
01279 return match_lhs_offset;
01280
01281 edge_.first.offset( saved_first_offset );
01282 return UniverseT::string_T::npos;
01283 }
01284
01285
01310 template< typename UniverseT >
01311 size_t bang_find( UniverseT& edge_ )
01312 {
01313
01314 CTTL_TRACE_LEVEL_BANG( ';' );
01315 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
01316 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), UniverseT::string_T::npos );
01317
01318 typename UniverseT::offset_manager_T iteration_offset( edge_.parent().container(), UniverseT::string_T::npos );
01319
01320 while ( ( match_lhs_offset = this->m_expr_lhs.bang_find( edge_ ) ) != UniverseT::string_T::npos ) {
01321 if ( this->m_expr_rhs.match( edge_ ) != UniverseT::string_T::npos )
01322 return match_lhs_offset;
01323
01324 if ( iteration_offset == edge_.first.offset() ) {
01325 CTTL_TRACE_TEXT( '+', "!!expr + expr: iteration has not made any progress: bailing out" );
01326 break;
01327 }
01328
01329 iteration_offset = edge_.first.offset();
01330 }
01331
01332
01333 edge_.first.offset( saved_first_offset );
01334 return UniverseT::string_T::npos;
01335 }
01336
01337 };
01338
01339
01357 template< typename Left_exprT, typename Right_exprT >
01358 struct xtl_opbinpipe : public xtl_op_base_binary< Left_exprT, Right_exprT > {
01359
01360
01361
01362
01382 xtl_opbinpipe( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
01383 : xtl_op_base_binary< Left_exprT, Right_exprT >( lhs_expr_, rhs_expr_ )
01384 {
01385 }
01386
01387
01388
01413 template< typename UniverseT >
01414 size_t match( UniverseT& edge_ )
01415 {
01416
01417
01418 CTTL_TRACE_LEVEL_MATCH( '|' );
01419 size_t match_offset = this->m_expr_lhs.match( edge_ );
01420 if ( match_offset != UniverseT::string_T::npos )
01421 return match_offset;
01422
01423 match_offset = this->m_expr_rhs.match( edge_ );
01424 if ( match_offset != UniverseT::string_T::npos )
01425 return match_offset;
01426
01427 CTTL_TRACE_RESULT( false, '|' );
01428 return UniverseT::string_T::npos;
01429 }
01430
01431
01456 template< typename UniverseT >
01457 size_t find( UniverseT& edge_ )
01458 {
01459
01460
01461 CTTL_TRACE_LEVEL_FIND( '|' );
01462 size_t match_offset = this->m_expr_lhs.find( edge_ );
01463 if ( match_offset != UniverseT::string_T::npos )
01464 return match_offset;
01465
01466 match_offset = this->m_expr_rhs.find( edge_ );
01467 if ( match_offset != UniverseT::string_T::npos )
01468 return match_offset;
01469
01470 CTTL_TRACE_RESULT( false, '|' );
01471 return UniverseT::string_T::npos;
01472 }
01473
01474
01499 template< typename UniverseT >
01500 size_t bang_find( UniverseT& edge_ )
01501 {
01502
01503
01504 CTTL_TRACE_LEVEL_BANG( '|' );
01505 size_t match_offset = this->m_expr_lhs.bang_find( edge_ );
01506 if ( match_offset != UniverseT::string_T::npos )
01507 return match_offset;
01508
01509 match_offset = this->m_expr_rhs.bang_find( edge_ );
01510 if ( match_offset != UniverseT::string_T::npos )
01511 return match_offset;
01512
01513 CTTL_TRACE_RESULT( false, '|' );
01514 return UniverseT::string_T::npos;
01515 }
01516
01517 };
01518
01519
01537 template< typename Left_exprT, typename Right_exprT >
01538 struct xtl_opbin2pipe : public xtl_op_base_binary< Left_exprT, Right_exprT > {
01539
01540
01541
01561 xtl_opbin2pipe( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
01562 : xtl_op_base_binary< Left_exprT, Right_exprT >( lhs_expr_, rhs_expr_ )
01563 {
01564 }
01565
01566
01567
01592 template< typename UniverseT >
01593 size_t match( UniverseT& edge_ )
01594 {
01595
01596
01597 CTTL_TRACE_LEVEL_MATCH( '|' );
01598
01599 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
01600
01601
01602 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.match( edge_ ) );
01603 if ( match_lhs_offset != UniverseT::string_T::npos )
01604
01605
01606 saved_lhs_edge.swap( edge_ );
01607
01608
01609 typename UniverseT::offset_manager_T match_rhs_offset( edge_.parent().container(), this->m_expr_rhs.match( edge_ ) );
01610 if ( match_rhs_offset != UniverseT::string_T::npos ) {
01611
01612 if ( match_lhs_offset == UniverseT::string_T::npos )
01613
01614 return match_rhs_offset;
01615
01616
01617
01618 if (
01619 ( match_lhs_offset == match_rhs_offset )
01620 &&
01621 ( saved_lhs_edge.first - match_lhs_offset < edge_.first.offset() - match_rhs_offset )
01622 )
01623
01624 return match_rhs_offset;
01625
01626
01627 else if ( match_rhs_offset < match_lhs_offset )
01628
01629 return match_rhs_offset;
01630
01631
01632 }
01633
01634 if ( match_lhs_offset != UniverseT::string_T::npos ) {
01635
01636
01637 saved_lhs_edge.restore( edge_ );
01638 return match_lhs_offset;
01639 }
01640
01641
01642
01643 CTTL_TRACE_TEXT_RESULT( false, '|', "||" );
01644 return UniverseT::string_T::npos;
01645 }
01646
01647
01672 template< typename UniverseT >
01673 size_t find( UniverseT& edge_ )
01674 {
01675
01676
01677 CTTL_TRACE_LEVEL_FIND( '|' );
01678
01679 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
01680
01681
01682 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.find( edge_ ) );
01683 if ( match_lhs_offset != UniverseT::string_T::npos )
01684
01685
01686 saved_lhs_edge.swap( edge_ );
01687
01688
01689 typename UniverseT::offset_manager_T match_rhs_offset( edge_.parent().container(), this->m_expr_rhs.find( edge_ ) );
01690 if ( match_rhs_offset != UniverseT::string_T::npos ) {
01691
01692 if ( match_lhs_offset == UniverseT::string_T::npos )
01693
01694 return match_rhs_offset;
01695
01696
01697
01698 if (
01699 ( match_lhs_offset == match_rhs_offset )
01700 &&
01701 ( saved_lhs_edge.first - match_lhs_offset < edge_.first.offset() - match_rhs_offset )
01702 )
01703
01704 return match_rhs_offset;
01705
01706
01707 else if ( match_rhs_offset < match_lhs_offset )
01708
01709 return match_rhs_offset;
01710
01711
01712
01713 }
01714
01715 if ( match_lhs_offset != UniverseT::string_T::npos ) {
01716
01717
01718 saved_lhs_edge.restore( edge_ );
01719 return match_lhs_offset;
01720 }
01721
01722
01723
01724 CTTL_TRACE_TEXT_RESULT( false, '|', "||" );
01725 return UniverseT::string_T::npos;
01726
01727 }
01728
01729
01754 template< typename UniverseT >
01755 size_t bang_find( UniverseT& edge_ )
01756 {
01757
01758
01759 CTTL_TRACE_LEVEL_BANG( '|' );
01760 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
01761
01762
01763 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.bang_find( edge_ ) );
01764 if ( match_lhs_offset != UniverseT::string_T::npos )
01765
01766
01767 saved_lhs_edge.swap( edge_ );
01768
01769
01770 typename UniverseT::offset_manager_T match_rhs_offset( edge_.parent().container(), this->m_expr_rhs.bang_find( edge_ ) );
01771 if ( match_rhs_offset != UniverseT::string_T::npos ) {
01772
01773 if ( match_lhs_offset == UniverseT::string_T::npos )
01774
01775 return match_rhs_offset;
01776
01777
01778
01779 if (
01780 ( match_lhs_offset == match_rhs_offset )
01781 &&
01782 ( saved_lhs_edge.first - match_lhs_offset < edge_.first.offset() - match_rhs_offset )
01783 )
01784
01785 return match_rhs_offset;
01786
01787
01788 else if ( match_rhs_offset < match_lhs_offset )
01789
01790 return match_rhs_offset;
01791
01792
01793
01794 }
01795
01796 if ( match_lhs_offset != UniverseT::string_T::npos ) {
01797
01798
01799 saved_lhs_edge.restore( edge_ );
01800 return match_lhs_offset;
01801 }
01802
01803
01804
01805 CTTL_TRACE_TEXT_RESULT( false, '|', "||" );
01806 return UniverseT::string_T::npos;
01807
01808 }
01809
01810 };
01811
01812
01830 template< typename Left_exprT, typename Right_exprT >
01831 struct xtl_opbinconcat : public xtl_op_base_binary< Left_exprT, Right_exprT > {
01832
01833
01834
01854 xtl_opbinconcat( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
01855 : xtl_op_base_binary< Left_exprT, Right_exprT >( lhs_expr_, rhs_expr_ )
01856 {
01857 }
01858
01859
01860
01861
01886 template< typename UniverseT >
01887 size_t match( UniverseT& edge_ )
01888 {
01889
01890
01891 CTTL_TRACE_LEVEL_MATCH( '^' );
01892 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
01893
01894 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.match( edge_ ) );
01895
01896 if ( match_lhs_offset != UniverseT::string_T::npos ) {
01897 typename UniverseT::strict_edge_T strict_universe( edge_ );
01898 if ( this->m_expr_rhs.match( strict_universe ) != UniverseT::string_T::npos )
01899 return match_lhs_offset;
01900 }
01901
01902 edge_.first.offset( saved_first_offset );
01903 CTTL_TRACE_RESULT( false, '^' );
01904 return UniverseT::string_T::npos;
01905 }
01906
01907
01932 template< typename UniverseT >
01933 size_t find( UniverseT& edge_ )
01934 {
01935
01936 CTTL_TRACE_LEVEL_FIND( '^' );
01937 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
01938
01939 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.find( edge_ ) );
01940
01941 if ( match_lhs_offset != UniverseT::string_T::npos ) {
01942 typename UniverseT::strict_edge_T strict_universe( edge_ );
01943 if ( this->m_expr_rhs.match( strict_universe ) != UniverseT::string_T::npos )
01944 return match_lhs_offset;
01945 }
01946
01947 edge_.first.offset( saved_first_offset );
01948 CTTL_TRACE_RESULT( false, '^' );
01949 return UniverseT::string_T::npos;
01950 }
01951
01952
01977 template< typename UniverseT >
01978 size_t bang_find( UniverseT& edge_ )
01979 {
01980
01981 CTTL_TRACE_LEVEL_BANG( '^' );
01982 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
01983 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), UniverseT::string_T::npos );
01984
01985 typename UniverseT::offset_manager_T iteration_offset( edge_.parent().container(), UniverseT::string_T::npos );
01986
01987 while ( ( match_lhs_offset = this->m_expr_lhs.bang_find( edge_ ) ) != UniverseT::string_T::npos ) {
01988 typename UniverseT::strict_edge_T strict_universe( edge_ );
01989 if ( this->m_expr_rhs.match( strict_universe ) != UniverseT::string_T::npos )
01990 return match_lhs_offset;
01991
01992 if ( iteration_offset == edge_.first.offset() ) {
01993 CTTL_TRACE_TEXT( '^', "!!expr ^ expr: iteration has not made any progress: bailing out" );
01994 break;
01995 }
01996
01997 iteration_offset = edge_.first.offset();
01998 }
01999
02000 edge_.first.offset( saved_first_offset );
02001 CTTL_TRACE_RESULT( false, '^' );
02002 return UniverseT::string_T::npos;
02003 }
02004
02005 };
02006
02007
02025 template< typename Left_exprT, typename Right_exprT >
02026 struct xtl_opbinminus : public xtl_op_base_binary< Left_exprT, Right_exprT > {
02027
02028
02029
02049 xtl_opbinminus( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
02050 : xtl_op_base_binary< Left_exprT, Right_exprT >( lhs_expr_, rhs_expr_ )
02051 {
02052 }
02053
02054
02055
02056
02081 template< typename UniverseT >
02082 size_t match( UniverseT& edge_ )
02083 {
02084
02085
02086 CTTL_TRACE_LEVEL_MATCH( '-' );
02087 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
02088 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
02089
02090
02091 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.match( edge_ ) );
02092 if ( match_lhs_offset != UniverseT::string_T::npos ) {
02093 saved_lhs_edge.save( edge_ );
02094 edge_.second.offset( edge_.first.offset() );
02095 edge_.first.offset( match_lhs_offset );
02096 typename UniverseT::strict_edge_T strict_universe( edge_ );
02097 if ( this->m_expr_rhs.match( strict_universe ) == UniverseT::string_T::npos ) {
02098
02099 saved_lhs_edge.restore( edge_ );
02100 return match_lhs_offset;
02101 }
02102 }
02103
02104
02105 edge_.first.offset( saved_first_offset );
02106 edge_.second.offset( saved_lhs_edge.second );
02107 CTTL_TRACE_RESULT( false, '-' );
02108 return UniverseT::string_T::npos;
02109 }
02110
02111
02136 template< typename UniverseT >
02137 size_t find( UniverseT& edge_ )
02138 {
02139
02140 CTTL_TRACE_LEVEL_FIND( '-' );
02141 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
02142 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
02143
02144
02145 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.find( edge_ ) );
02146 if ( match_lhs_offset != UniverseT::string_T::npos ) {
02147 saved_lhs_edge.save( edge_ );
02148 edge_.second.offset( edge_.first.offset() );
02149 edge_.first.offset( match_lhs_offset );
02150 typename UniverseT::strict_edge_T strict_universe( edge_ );
02151 if ( this->m_expr_rhs.match( strict_universe ) == UniverseT::string_T::npos ) {
02152
02153 saved_lhs_edge.restore( edge_ );
02154 return match_lhs_offset;
02155 }
02156 }
02157
02158
02159 edge_.first.offset( saved_first_offset );
02160 edge_.second.offset( saved_lhs_edge.second );
02161 CTTL_TRACE_RESULT( false, '-' );
02162 return UniverseT::string_T::npos;
02163 }
02164
02165
02190 template< typename UniverseT >
02191 size_t bang_find( UniverseT& edge_ )
02192 {
02193
02194 CTTL_TRACE_LEVEL_BANG( '-' );
02195 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
02196 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), UniverseT::string_T::npos );
02197 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
02198
02199 typename UniverseT::offset_manager_T iteration_offset( edge_.parent().container(), UniverseT::string_T::npos );
02200
02201 while ( ( match_lhs_offset = this->m_expr_lhs.bang_find( edge_ ) ) != UniverseT::string_T::npos ) {
02202 saved_lhs_edge.save( edge_ );
02203 edge_.second.offset( edge_.first.offset() );
02204 edge_.first.offset( match_lhs_offset );
02205 typename UniverseT::strict_edge_T strict_universe( edge_ );
02206 if ( this->m_expr_rhs.match( strict_universe ) == UniverseT::string_T::npos ) {
02207
02208 saved_lhs_edge.restore( edge_ );
02209 return match_lhs_offset;
02210 }
02211
02212
02213 saved_lhs_edge.restore( edge_ );
02214
02215 if ( iteration_offset == edge_.first.offset() ) {
02216 CTTL_TRACE_TEXT( '-', "!!expr - expr: iteration has not made any progress: bailing out" );
02217 break;
02218 }
02219
02220 iteration_offset = edge_.first.offset();
02221 }
02222
02223 edge_.first.offset( saved_first_offset );
02224 CTTL_TRACE_RESULT( false, '-' );
02225 return UniverseT::string_T::npos;
02226 }
02227
02228 };
02229
02230
02248 template< typename Left_exprT, typename Right_exprT >
02249 struct xtl_opbinand : public xtl_op_base_binary< Left_exprT, Right_exprT > {
02250
02251
02252
02272 xtl_opbinand( Left_exprT const& lhs_expr_, Right_exprT const& rhs_expr_ )
02273 : xtl_op_base_binary< Left_exprT, Right_exprT >( lhs_expr_, rhs_expr_ )
02274 {
02275 }
02276
02277
02278
02279
02304 template< typename UniverseT >
02305 size_t match( UniverseT& edge_ )
02306 {
02307
02308
02309 CTTL_TRACE_LEVEL_MATCH( '&' );
02310 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
02311 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
02312
02313
02314 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.match( edge_ ) );
02315 if ( match_lhs_offset != UniverseT::string_T::npos ) {
02316 saved_lhs_edge.save( edge_ );
02317 edge_.second.offset( edge_.first.offset() );
02318 edge_.first.offset( match_lhs_offset );
02319 typename UniverseT::strict_edge_T strict_universe( edge_ );
02320 if ( this->m_expr_rhs.match( strict_universe ) != UniverseT::string_T::npos ) {
02321
02322 saved_lhs_edge.restore( edge_ );
02323 return match_lhs_offset;
02324 }
02325 }
02326
02327 edge_.first.offset( saved_first_offset );
02328 edge_.second.offset( saved_lhs_edge.second );
02329 CTTL_TRACE_RESULT( false, '&' );
02330 return UniverseT::string_T::npos;
02331 }
02332
02333
02358 template< typename UniverseT >
02359 size_t find( UniverseT& edge_ )
02360 {
02361
02362 CTTL_TRACE_LEVEL_FIND( '&' );
02363 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
02364 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
02365
02366
02367 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), this->m_expr_lhs.find( edge_ ) );
02368 if ( match_lhs_offset != UniverseT::string_T::npos ) {
02369 saved_lhs_edge.save( edge_ );
02370 edge_.second.offset( edge_.first.offset() );
02371 edge_.first.offset( match_lhs_offset );
02372 typename UniverseT::strict_edge_T strict_universe( edge_ );
02373 if ( this->m_expr_rhs.match( strict_universe ) != UniverseT::string_T::npos ) {
02374
02375 saved_lhs_edge.restore( edge_ );
02376 return match_lhs_offset;
02377 }
02378 }
02379
02380 edge_.first.offset( saved_first_offset );
02381 edge_.second.offset( saved_lhs_edge.second );
02382 CTTL_TRACE_RESULT( false, '&' );
02383 return UniverseT::string_T::npos;
02384 }
02385
02386
02411 template< typename UniverseT >
02412 size_t bang_find( UniverseT& edge_ )
02413 {
02414
02415 CTTL_TRACE_LEVEL_BANG( '&' );
02416 typename UniverseT::offset_manager_T saved_first_offset( edge_.parent().container(), edge_.first.offset() );
02417 xtl_edge_offset_manager< UniverseT > saved_lhs_edge( edge_ );
02418
02419 typename UniverseT::offset_manager_T iteration_offset( edge_.parent().container(), UniverseT::string_T::npos );
02420
02421 typename UniverseT::offset_manager_T match_lhs_offset( edge_.parent().container(), UniverseT::string_T::npos );
02422 while ( ( match_lhs_offset = this->m_expr_lhs.bang_find( edge_ ) ) != UniverseT::string_T::npos ) {
02423 saved_lhs_edge.save( edge_ );
02424 edge_.second.offset( edge_.first.offset() );
02425 edge_.first.offset( match_lhs_offset );
02426 typename UniverseT::strict_edge_T strict_universe( edge_ );
02427 if ( this->m_expr_rhs.match( strict_universe ) != UniverseT::string_T::npos ) {
02428
02429 saved_lhs_edge.restore( edge_ );
02430 return match_lhs_offset;
02431 }
02432
02433
02434 saved_lhs_edge.restore( edge_ );
02435
02436 if ( iteration_offset == edge_.first.offset() ) {
02437 CTTL_TRACE_TEXT( '&', "!!expr & expr: iteration has not made any progress: bailing out" );
02438 break;
02439 }
02440
02441 iteration_offset = edge_.first.offset();
02442 }
02443
02444 edge_.first.offset( saved_first_offset );
02445 CTTL_TRACE_RESULT( false, '&' );
02446 return UniverseT::string_T::npos;
02447 }
02448
02449 };
02450
02452
02454
02456 typedef xtl_wrap< xtl_opbinplus< relaxed_bool_T, xtl_wrap< xtl_opunarbang< xtl_wrap< xtl_position_eof > > > > >
02457 universe_T;
02458
02459 }
02460
02461 #endif // _CTTL_XTL_OP_IMPL_H_INCLUDED_