00001
00002
00111
00112
00113
00114 #include <stack>
00115 #include <iterator>
00116 #include <utility>
00117
00118
00119 #include "pbori_defs.h"
00120
00121
00122 #include "pbori_func.h"
00123
00124
00125 #include "pbori_traits.h"
00126
00127 #include "pbori_routines.h"
00128
00129
00130 #include <boost/iterator/indirect_iterator.hpp>
00131
00132 #include "BooleEnv.h"
00133 #include "CDegreeCache.h"
00134 #include "CBidirectTermIter.h"
00135
00136
00137 #ifndef CTermStack_h_
00138 #define CTermStack_h_
00139
00140 BEGIN_NAMESPACE_PBORI
00141
00143 template<class NavigatorType>
00144 struct cached_deg {
00145 typedef CDegreeCache<> cache_type;
00146 typedef typename cache_type::manager_type manager_type;
00147 cached_deg(const manager_type & mgr): m_deg_cache(mgr) {}
00148
00149 typename NavigatorType::size_type
00150 operator()(NavigatorType navi) const {
00151 return dd_cached_degree(m_deg_cache, navi);
00152 }
00153 cache_type m_deg_cache;
00154 };
00155
00157
00158 template <class NavigatorType>
00159 class cached_block_deg {
00160 public:
00161 typedef typename NavigatorType::idx_type idx_type;
00162
00163 typedef cached_block_deg<NavigatorType> self;
00164
00166 typedef std::vector<idx_type> block_idx_type;
00167
00169 typedef typename block_idx_type::const_iterator block_iterator;
00170 typedef CBlockDegreeCache<CCacheTypes::block_degree, CTypes::dd_type>
00171 cache_type;
00172 typedef typename cache_type::manager_type manager_type;
00173
00174 cached_block_deg(const manager_type& mgr):
00175
00176 m_current_block(BooleEnv::blockBegin()),
00177 m_deg_cache(mgr) { }
00178
00179 typename NavigatorType::size_type
00180 operator()(NavigatorType navi) const {
00181 return dd_cached_block_degree(m_deg_cache, navi, max());
00182 }
00183
00184 idx_type min() const {
00185 assert(*m_current_block != 0);
00186 return *(m_current_block - 1);
00187 }
00188
00189 idx_type max() const {
00190 return *m_current_block;
00191 }
00192 self& operator++(){
00193 assert(max() != CTypes::max_idx);
00194 ++m_current_block;
00195 return *this;
00196 }
00197
00198 self& operator--(){
00199 assert(min() != 0);
00200 --m_current_block;
00201 return *this;
00202 }
00203
00204 private:
00205
00206 block_iterator m_current_block;
00207
00208 cache_type m_deg_cache;
00209 };
00210
00211
00212
00213
00221 template <class NavigatorType, class BaseType = internal_tag>
00222 class CTermStackBase:
00223 public BaseType {
00224
00225 public:
00226
00227 template <class, class> friend class CTermStackBase;
00228
00229 typedef CTermStackBase<NavigatorType, BaseType> self;
00230
00232 typedef NavigatorType navigator;
00234 typedef typename navigator::idx_type idx_type;
00235
00237 typedef typename navigator::size_type size_type;
00238 typedef typename navigator::deg_type deg_type;
00239 typedef typename navigator::bool_type bool_type;
00240
00241
00243 typedef std::deque<navigator> stack_type;
00244
00245 typedef typename stack_type::reference reference;
00246 typedef typename stack_type::const_reference const_reference;
00247
00248 typedef boost::indirect_iterator<typename stack_type::const_iterator,
00249 typename navigator::value_type,
00250 boost::use_default,
00251 typename navigator::reference>
00252 const_iterator;
00253
00254 typedef typename stack_type::const_iterator stack_iterator;
00255
00256 typedef typename stack_type::const_reverse_iterator stack_reverse_iterator;
00257
00258 typedef boost::indirect_iterator<typename stack_type::const_reverse_iterator,
00259 typename navigator::value_type,
00260 boost::use_default,
00261 typename navigator::reference>
00262 const_reverse_iterator;
00263
00264 private:
00265 void pop() { m_stack.pop_back(); }
00266
00267 protected:
00268 void push(navigator __x) { m_stack.push_back(__x); }
00269
00270 void clear() { m_stack.clear(); }
00271
00272
00273 public:
00274 bool_type empty() const { return m_stack.empty(); }
00275 const_reference top() const {
00276 assert(!empty());
00277 return m_stack.back();
00278 }
00279 idx_type index() const { return *top(); }
00280 size_type size() const { return m_stack.size(); }
00281
00282 const_iterator begin() const { return stackBegin(); }
00283 const_iterator end() const { return stackEnd(); }
00284
00285 const_reverse_iterator rbegin() const { return stackRBegin(); }
00286
00287 const_reverse_iterator rend() const { return stackREnd(); }
00288
00290 navigator navigation() const {
00291 assert(m_stack.begin() != m_stack.end());
00292 return *m_stack.begin();
00293 }
00294
00296 typedef typename stack_type::value_type top_type;
00297
00299 CTermStackBase(): BaseType(), m_stack() { }
00300
00302 CTermStackBase(navigator navi): BaseType(), m_stack() {
00303 push(navi);
00304 }
00305
00307
00308
00310 bool_type equal(const self& rhs) const {
00311
00312 if(empty() || rhs.empty())
00313 return (empty() && rhs.empty());
00314 else
00315 return (m_stack == rhs.m_stack);
00316 }
00317
00318 void incrementThen() {
00319 assert(!top().isConstant());
00320
00321 push(top());
00322 m_stack.back().incrementThen();
00323 }
00324 void incrementElse() {
00325 assert(!isConstant());
00326 m_stack.back().incrementElse();
00327 }
00328
00329 void decrementNode() {
00330 assert(!empty());
00331 pop();
00332 }
00333
00334 bool_type isConstant() const {
00335 assert(!empty());
00336 return top().isConstant();
00337 }
00338
00339 bool_type isTerminated() const {
00340 assert(!empty());
00341 return top().isTerminated();
00342 }
00343
00344 bool_type isInvalid() const {
00345 assert(!empty());
00346 return top().isEmpty();
00347 }
00348
00349 void followThen() {
00350 assert(!empty());
00351 while(!isConstant())
00352 incrementThen();
00353 }
00354
00355 void markOne() {
00356 assert(empty());
00357 push(navigator());
00358 }
00359
00360 bool_type markedOne() const {
00361 if UNLIKELY(empty())
00362 return false;
00363 else
00364 return !m_stack.front().isValid();
00365 }
00366
00367 void clearOne() {
00368 pop();
00369 assert(empty());
00370 }
00371
00372 deg_type deg() const {
00373 return (markedOne()? 0: (deg_type)size());
00374 }
00375
00376 void invalidate() {
00377 push(BooleEnv::zero().navigation());
00378 }
00379
00380 void restart(navigator navi) {
00381 assert(empty());
00382 push(navi);
00383 }
00384
00385 bool isOne() const { return markedOne(); }
00386 bool isZero() const { return empty(); }
00387
00388 bool atBegin() const { return empty(); }
00389
00390 bool atEnd() const { return atEnd(top()); }
00391 bool atEnd(navigator navi) const { return navi.isConstant(); }
00392
00393 bool validEnd() const { return validEnd(top()); }
00394 bool validEnd(navigator navi) const {
00395 while(!navi.isConstant()) {
00396 navi.incrementElse();
00397 }
00398 return navi.terminalValue();
00399 }
00400
00401 void print() const{
00402 std::cout <<"(";
00403 std::copy(begin(), end(), std::ostream_iterator<int>(cout, ", "));
00404 std::cout <<")";
00405 }
00406
00407 stack_iterator stackBegin() const {
00408 if (markedOne())
00409 return m_stack.end();
00410 else
00411 return m_stack.begin();
00412 }
00413
00414 stack_iterator stackEnd() const {
00415 return m_stack.end();
00416 }
00417
00418 stack_reverse_iterator stackRBegin() const {
00419 if (markedOne())
00420 return m_stack.rend();
00421 else
00422 return m_stack.rbegin();
00423 }
00424
00425 stack_reverse_iterator stackREnd() const {
00426 return m_stack.rend();
00427 }
00428 protected:
00429
00430 template <class TermStack>
00431 void append(const TermStack& rhs) {
00432 assert(empty() || rhs.empty() || ((*rhs.begin()) > (*top())) );
00433 m_stack.insert(m_stack.end(), rhs.m_stack.begin(), rhs.m_stack.end());
00434 }
00435
00436
00437 private:
00438 stack_type m_stack;
00439 };
00440
00441
00442
00448 template <class NavigatorType, class Category, class BaseType = internal_tag>
00449 class CTermStack:
00450 public CTermStackBase<NavigatorType, BaseType> {
00451
00452 public:
00453 typedef CTermStackBase<NavigatorType, BaseType> base;
00454 typedef CTermStack<NavigatorType, Category, BaseType> self;
00455
00457 typedef CTermStack<NavigatorType, Category, internal_tag> purestack_type;
00458 typedef Category iterator_category;
00459
00460 typedef typename base::navigator navigator;
00461 typedef typename on_same_type<Category, std::forward_iterator_tag,
00462 project_ith<0>,
00463 handle_else<NavigatorType> >::type
00464 else_handler;
00465
00466 else_handler handleElse;
00467
00468 using base::incrementThen;
00469 using base::followThen;
00470
00472 CTermStack(): base() { }
00473
00475 CTermStack(navigator navi): base(navi) { }
00476
00479 template <class Dummy>
00480 CTermStack(navigator navi, const Dummy&): base(navi) { }
00481
00482 void init() {
00483 followThen();
00484 terminate();
00485 }
00486
00487 void initLast() {
00488 followElse();
00489 terminate();
00490 }
00491
00492 void incrementElse() {
00493 handleElse(base::top());
00494 base::incrementElse();
00495 }
00496
00497 void next() {
00498
00499 bool invalid = true;
00500 while (!base::empty() && invalid) {
00501 incrementElse();
00502 if (invalid = base::isInvalid())
00503 base::decrementNode();
00504 }
00505 }
00506
00507 void previous() {
00508 previous(Category());
00509 }
00510
00511
00512 void increment() {
00513 assert(!base::empty());
00514 if UNLIKELY(base::markedOne()) {
00515 base::clearOne();
00516 return;
00517 }
00518
00519 next();
00520 if UNLIKELY(!base::empty()) {
00521 followThen();
00522 terminate();
00523 }
00524
00525 }
00526
00527 void decrement() {
00528
00529 if UNLIKELY(base::markedOne()) {
00530 base::clearOne();
00531 }
00532 previous();
00533 if UNLIKELY(!base::empty()){
00534 followElse();
00535 base::decrementNode();
00536 }
00537
00538 }
00539
00540 void terminate() {
00541 assert(!base::empty());
00542
00543 bool isZero = base::isInvalid();
00544 base::decrementNode();
00545 if UNLIKELY(base::empty() && !isZero)
00546 base::markOne();
00547 }
00548
00549
00550 void followElse() {
00551 while( !base::isConstant() )
00552 incrementValidElse();
00553 }
00554
00555 void incrementValidElse() {
00556 assert(!base::empty() && !base::isConstant());
00557 if(!base::top().elseBranch().isEmpty())
00558 incrementElse();
00559 else
00560 incrementThen();
00561 }
00562
00563 protected:
00564 template <class TermStack>
00565 void append(const TermStack& rhs) {
00566 base::append(rhs);
00567 append(rhs, Category());
00568 }
00569
00570 private:
00571 void previous(std::forward_iterator_tag);
00572 void previous(std::bidirectional_iterator_tag);
00573
00574 template <class TermStack>
00575 void append(const TermStack&, std::forward_iterator_tag){}
00576
00577 template <class TermStack>
00578 void append(const TermStack& rhs, std::bidirectional_iterator_tag){
00579 handleElse.append(rhs.handleElse);
00580 }
00581 };
00582
00583
00584 template <class NavigatorType, class Category, class BaseType>
00585 inline void CTermStack<NavigatorType, Category, BaseType>::previous(
00586 std::forward_iterator_tag) { }
00587
00588 template <class NavigatorType, class Category, class BaseType>
00589 inline void CTermStack<NavigatorType, Category, BaseType>::previous(
00590 std::bidirectional_iterator_tag) {
00591
00592 if(handleElse.empty()) {
00593 base::clear();
00594 return;
00595 }
00596
00597 navigator navi = handleElse.top();
00598 assert(base::empty() || base::top().isValid());
00599
00600 while(!base::empty() && (base::index() >= *navi) ) {
00601 base::decrementNode();
00602 }
00603
00604 handleElse.pop();
00605 base::push(navi);
00606 incrementThen();
00607 }
00608
00614 template <class NavigatorType, class Category>
00615 class CReverseTermStack:
00616 public CTermStack<NavigatorType, Category> {
00617 public:
00618 typedef NavigatorType navigator;
00619 typedef CTermStack<NavigatorType, Category> base;
00620
00622 CReverseTermStack(): base() { }
00623
00625 CReverseTermStack(navigator navi): base(navi) { }
00626
00629 template <class Dummy>
00630 CReverseTermStack(navigator navi, const Dummy&): base(navi) { }
00631
00632 void init() { base::initLast(); }
00633 void initLast() { base::init(); }
00634 void increment() { base::decrement(); }
00635 void decrement() { base::increment(); }
00636 };
00637
00638 template <class NavigatorType, class BlockProperty, class Category, class
00639 BaseType = internal_tag>
00640 class CDegStackCore;
00641
00643 template <class NavigatorType, class Category, class BaseType>
00644 class CDegStackCore<NavigatorType, invalid_tag, Category, BaseType>:
00645 public CTermStack<NavigatorType, Category, BaseType> {
00646
00647 public:
00648 typedef CTermStack<NavigatorType, Category, BaseType> base;
00649 typedef NavigatorType navigator;
00650 typedef typename cached_deg<navigator>::manager_type manager_type;
00651
00652 CDegStackCore(): base(), getDeg(typename manager_type::mgrcore_ptr()) {}
00653
00654 CDegStackCore(navigator navi, const manager_type& mgr):
00655 base(navi), getDeg(mgr) {}
00656
00657
00658 void gotoEnd() {
00659 assert(!base::empty());
00660 while(!base::isConstant()) {
00661 base::incrementElse();
00662 }
00663 }
00664
00665 cached_deg<navigator> getDeg;
00666 };
00667
00669 template <class NavigatorType, class Category, class BaseType>
00670 class CDegStackCore<NavigatorType, valid_tag, Category, BaseType> :
00671 public CTermStack<NavigatorType, Category, BaseType> {
00672
00673 public:
00674 typedef CTermStack<NavigatorType, Category, BaseType> base;
00675 typedef NavigatorType navigator;
00676 typedef typename base::idx_type idx_type;
00677 typedef typename base::size_type size_type;
00678 typedef typename cached_block_deg<navigator>::manager_type manager_type;
00679
00680 CDegStackCore(): base(), block(typename manager_type::mgrcore_ptr()) {}
00681 CDegStackCore(navigator navi, const manager_type& mgr):
00682 base(navi), block(mgr) {}
00683
00684 size_type getDeg(navigator navi) const { return block(navi); }
00685
00686 bool atBegin() const {
00687 return base::empty() || (base::index() < block.min());
00688 }
00689
00690 bool atEnd() const { return atEnd(base::top()); }
00691 bool atEnd(navigator navi) const {
00692 return navi.isConstant() || (*navi >= block.max());
00693 }
00694
00695 bool validEnd() const{ return validEnd(base::top()); }
00696 bool validEnd(navigator navi) const {
00697
00698 while(!atEnd(navi))
00699 navi.incrementElse();
00700
00701 return (navi.isConstant()? navi.terminalValue(): *navi >= block.max());
00702 }
00703
00704 void next() {
00705
00706 bool invalid = true;
00707 while (!atBegin() && invalid) {
00708 assert(!base::isConstant());
00709 base::incrementElse();
00710 if (invalid = base::isInvalid())
00711 base::decrementNode();
00712 }
00713 }
00714 void previous() {
00715
00716 if( base::handleElse.empty() || (*base::handleElse.top() < block.min()) ) {
00717 while(!atBegin())
00718 base::decrementNode();
00719 return;
00720 }
00721 navigator navi = base::handleElse.top();
00722 assert(base::top().isValid());
00723
00724 while(!atBegin() && (base::index() >= *navi) ) {
00725 base::decrementNode();
00726 }
00727
00728 if (base::empty() || (base::index() < *navi)) {
00729 base::handleElse.pop();
00730 base::push(navi);
00731 }
00732 base::incrementThen();
00733 }
00734
00735 void gotoEnd() {
00736 assert(!base::empty());
00737 while( (!base::isConstant()) && (base::index() < block.max()) ) {
00738 base::incrementElse();
00739 }
00740 }
00741
00742 protected:
00743 cached_block_deg<navigator> block;
00744 };
00745
00746 template <class NavigatorType, class BlockProperty, class DescendingProperty,
00747 class BaseType = internal_tag>
00748 class CDegStackBase;
00749
00750 template <class NavigatorType, class BlockProperty, class BaseType>
00751 class CDegStackBase<NavigatorType, valid_tag, BlockProperty, BaseType>:
00752 public CDegStackCore<NavigatorType, BlockProperty,
00753 std::forward_iterator_tag, BaseType> {
00754
00755 public:
00756 typedef CDegStackCore<NavigatorType, BlockProperty,
00757 std::forward_iterator_tag, BaseType> base;
00758
00759 typedef typename base::size_type size_type;
00760 typedef typename base::deg_type deg_type;
00761 typedef std::greater<size_type> size_comparer;
00762 typedef typename base::manager_type manager_type;
00763
00764 CDegStackBase(): base() {}
00765 CDegStackBase(NavigatorType navi, const manager_type& mgr): base(navi, mgr) {}
00766
00767 integral_constant<bool, false> takeLast;
00768
00769 void proximate() { base::next(); }
00770
00771 void incrementBranch() { base::incrementThen(); }
00772
00773 bool maxOnThen(deg_type deg) const {
00774 return (base::getDeg(base::top().thenBranch()) + 1 == deg);
00775 }
00776
00777 };
00778
00779
00780 template <class NavigatorType, class BlockProperty, class BaseType>
00781 class CDegStackBase<NavigatorType, invalid_tag, BlockProperty, BaseType>:
00782 public CDegStackCore<NavigatorType, BlockProperty,
00783 std::bidirectional_iterator_tag, BaseType> {
00784
00785 public:
00786 typedef CDegStackCore<NavigatorType, BlockProperty,
00787 std::bidirectional_iterator_tag, BaseType> base;
00788 typedef typename base::size_type size_type;
00789 typedef typename base::deg_type deg_type;
00790 typedef std::greater_equal<size_type> size_comparer;
00791 typedef typename base::manager_type manager_type;
00792
00793 CDegStackBase(): base() {}
00794 CDegStackBase(NavigatorType navi, const manager_type& mgr): base(navi, mgr) {}
00795
00796 integral_constant<bool, true> takeLast;
00797
00798 void proximate() { base::previous(); }
00799
00800 void incrementBranch() { base::incrementValidElse(); }
00801
00802 bool maxOnThen(deg_type deg) const {
00803 return !(base::getDeg(base::top().elseBranch()) == deg);
00804 }
00805 };
00806
00807
00808 template <class NavigatorType, class DescendingProperty,
00809 class BlockProperty = invalid_tag, class BaseType = internal_tag>
00810 class CDegTermStack:
00811 public CDegStackBase<NavigatorType, DescendingProperty, BlockProperty, BaseType> {
00812
00813 public:
00814 typedef CDegStackBase<NavigatorType, DescendingProperty, BlockProperty, BaseType> base;
00815 typedef CDegTermStack<NavigatorType, DescendingProperty, BlockProperty, BaseType> self;
00816
00817 typedef typename base::navigator navigator;
00818 typedef typename navigator::size_type size_type;
00819 typedef typename navigator::deg_type deg_type;
00820 typedef typename base::manager_type manager_type;
00821
00822 CDegTermStack(): base(), m_start() {}
00823 CDegTermStack(navigator navi, const manager_type& mgr):
00824 base(navi, mgr), m_start(navi) {}
00825
00826 void init() {
00827 followDeg();
00828 base::terminate();
00829 }
00830 void followDeg() {
00831 assert(!base::empty());
00832
00833 deg_type deg = base::getDeg(base::top());
00834
00835 while (deg > 0) {
00836
00837 if ( base::maxOnThen(deg) ) {
00838 --deg;
00839 base::incrementThen();
00840 }
00841 else
00842 base::incrementElse();
00843
00844 }
00845 }
00846
00847 void increment() {
00848 assert(!base::empty());
00849 if (base::markedOne()) {
00850 base::clearOne();
00851 return;
00852 }
00853
00854
00855 size_type upperbound = base::size();
00856 degTerm();
00857
00858 if(base::empty()) {
00859 restart();
00860 findTerm(upperbound);
00861 }
00862 if(!base::empty())
00863 base::terminate();
00864 }
00865
00866
00867 void degTerm() {
00868 size_type size = base::size() + 1;
00869
00870 assert(!base::isConstant());
00871 bool doloop;
00872 do {
00873 assert(!base::empty());
00874 base::proximate();
00875
00876 if (base::atBegin())
00877 return;
00878
00879 while (!base::atEnd() && (base::size() < size) ) {
00880 base::incrementBranch();
00881 }
00882 base::gotoEnd();
00883
00884 if (doloop = (base::isInvalid() || (base::size() != size)) )
00885 base::decrementNode();
00886
00887 } while (!base::empty() && doloop);
00888
00889 }
00890
00891
00892 void decrement() {}
00893
00894 void findTerm(size_type upperbound) {
00895 assert(!base::empty());
00896
00897 typename base::purestack_type max_elt, current(base::top());
00898 base::decrementNode();
00899
00900 typename base::size_comparer comp;
00901
00902 while (!current.empty() &&
00903 (base::takeLast() || (max_elt.size() != upperbound)) ) {
00904
00905 while (!base::atEnd(current.top()) && (current.size() < upperbound) )
00906 current.incrementThen();
00907
00908 if (base::validEnd(current.top())) {
00909 if (comp(current.size(), max_elt.size()))
00910 max_elt = current;
00911 current.decrementNode();
00912 }
00913 current.next();
00914 }
00915 base::append(max_elt);
00916
00917 if(max_elt.empty())
00918 base::invalidate();
00919 }
00920
00921 void restart() { base::restart(m_start); }
00922
00923 private:
00924 navigator m_start;
00925 };
00926
00927
00928
00930 template <class NavigatorType, class DescendingProperty, class BaseType = internal_tag>
00931 class CBlockTermStack:
00932 public CDegTermStack<NavigatorType, DescendingProperty, valid_tag, BaseType> {
00933
00934 public:
00935 typedef CDegTermStack<NavigatorType, DescendingProperty, valid_tag, BaseType> base;
00936 typedef CBlockTermStack<NavigatorType, DescendingProperty, BaseType> self;
00937
00938 typedef typename base::navigator navigator;
00939 typedef typename navigator::size_type size_type;
00940 typedef typename navigator::idx_type idx_type;
00941 typedef typename base::manager_type manager_type;
00942
00944 CBlockTermStack(navigator navi, const manager_type& mgr):
00945 base(navi, mgr) { }
00946
00948 CBlockTermStack(): base() {}
00949
00950
00951 void init() {
00952 assert(!base::empty());
00953 followDeg();
00954 base::terminate();
00955 }
00956
00957 void increment() {
00958 assert(!base::empty());
00959
00960 if (base::markedOne()) {
00961 base::clearOne();
00962 return;
00963 }
00964
00965 navigator current = base::top();
00966 while (*current < base::block.min())
00967 --base::block;
00968
00969 incrementBlock();
00970 while ( (base::size() > 1 ) && base::isInvalid() ) {
00971 --base::block;
00972 base::decrementNode();
00973 incrementBlock();
00974 }
00975
00976 followDeg();
00977
00978 assert(!base::empty());
00979 base::terminate();
00980 }
00981
00982 void followBlockDeg() { base::followDeg(); }
00983
00984 void followDeg() {
00985 assert(base::top().isValid());
00986
00987 if (!base::isConstant() )
00988 followBlockDeg();
00989
00990 while (!base::isConstant() ) {
00991 ++base::block;
00992 followBlockDeg();
00993 }
00994 }
00995
00996 void incrementBlock() {
00997
00998 assert(!base::empty());
00999 size_type size = base::size() + 1;
01000
01001 if (base::index() < base::block.min()) {
01002 base::invalidate();
01003 return;
01004 }
01005
01006 base::degTerm();
01007
01008 if (base::size() == size) return;
01009
01010 if (base::empty())
01011 base::restart();
01012 else {
01013 assert(base::index() < base::block.min());
01014 base::incrementThen();
01015 }
01016
01017 while (!base::isConstant() && (base::index() < base::block.min()))
01018 base::incrementElse();
01019
01020 assert(size > base::size());
01021
01022 base::findTerm(size - base::size());
01023 base::gotoEnd();
01024 }
01025 };
01026
01027 END_NAMESPACE_PBORI
01028
01029 #endif