Library: remove redundant checks from IterAdapter implementation

Explicitly assuming that those functions are called solely from IterAdapter
and that they are implemented in a typical standard style, we're able to elide
two redundant calls to the checkPoint() function. Since checkPoint typically performs
some non-trivial checks, this has the potential of a significant performance improvement

- we check (and throw ITER_EXHAUST) anyway from operator++, so we know that pos is valid
- the iterate() function ensures checkPoint is invoked right after iterNext,
  and thus the typical standard implementation of iterNext need not do the same
This commit is contained in:
Fischlurch 2017-10-01 03:25:33 +02:00
parent a08fba5880
commit 5dfd135595
5 changed files with 11 additions and 10 deletions

View file

@ -312,10 +312,9 @@ namespace diff{
/** Implementation of Iteration-logic: pull next element. */ /** Implementation of Iteration-logic: pull next element. */
friend void friend void
iterNext (const Record* src, ElmIter& pos) iterNext (const Record*, ElmIter& pos)
{ {
++pos; ++pos;
checkPoint (src,pos);
} }
/** Implementation of Iteration-logic: detect iteration end. /** Implementation of Iteration-logic: detect iteration end.

View file

@ -238,8 +238,7 @@ namespace lib {
void void
iterate() iterate()
{ {
if (check()) iterNext (source_,pos_); // extension point: free function iterNext(...)
iterNext (source_,pos_); // extension point: free function iterNext(...)
check(); check();
} // checkPoint() might mark end condition } // checkPoint() might mark end condition
// for comparison with IterAdapter{} // for comparison with IterAdapter{}

View file

@ -96,7 +96,7 @@ namespace lib {
virtual Pos firstResult () =0; virtual Pos firstResult () =0;
/** iteration step: switch on to the next element. /** iteration step: switch on to the next element.
* The pos pointer may be set to NULL to report * The pos pointer should be set to NULL to report
* iteration end * iteration end
*/ */
virtual void nextResult(Pos& pos) =0; virtual void nextResult(Pos& pos) =0;

View file

@ -311,10 +311,9 @@ namespace lib {
/** Implementation of Iteration-logic: pull next element. */ /** Implementation of Iteration-logic: pull next element. */
friend void friend void
iterNext (const PathArray* src, const Literal*& pos) iterNext (const PathArray*, const Literal*& pos)
{ {
++pos; ++pos;
checkPoint (src,pos);
} }
/** Implementation of Iteration-logic: detect iteration end. */ /** Implementation of Iteration-logic: detect iteration end. */

View file

@ -135,13 +135,17 @@ namespace test{
protected: /* ==== API for the IterAdapter ==== */ protected: /* ==== API for the IterAdapter ==== */
/** Implementation of Iteration-logic: pull next element. */ /** Implementation of Iteration-logic: pull next element.
* @remarks typically the implementation is simplistic,
* since the way this extension point is called from IterAdapter
* ensures that _`pos` is still valid_ and that the `checkPoint()` function
* is invoked immediately afterwards, allowing to adjust `pos` if necessary
*/
template<class ITER> template<class ITER>
friend void friend void
iterNext (const TestContainer* src, ITER& pos) iterNext (const TestContainer*, ITER& pos)
{ {
++pos; ++pos;
checkPoint (src,pos);
} }
/** Implementation of Iteration-logic: detect iteration end. /** Implementation of Iteration-logic: detect iteration end.