definition reordering and comments
This commit is contained in:
parent
97c63e0472
commit
5427d659d7
2 changed files with 111 additions and 98 deletions
|
|
@ -100,6 +100,37 @@ namespace diff{
|
|||
LUMIERA_ERROR_DECLARE(DIFF_CONFLICT); ///< Collision in diff application: contents of target not as expected.
|
||||
|
||||
|
||||
template<class I, typename E>
|
||||
using HandlerFun = void (I::*) (E);
|
||||
|
||||
|
||||
/** @internal type rebinding helper */
|
||||
template<class I>
|
||||
struct InterpreterScheme ///< base case is to expect typedef I::Val
|
||||
{
|
||||
using Interpreter = I;
|
||||
using Val = typename I::Val;
|
||||
using Handler = HandlerFun<I,Val>;
|
||||
};
|
||||
|
||||
template<template<typename> class IP, typename E>
|
||||
struct InterpreterScheme<IP<E>> ///< alternatively, the interpreter value type can be templated
|
||||
{
|
||||
using Val = E;
|
||||
using Interpreter = IP<E>;
|
||||
using Handler = HandlerFun<Interpreter,Val>;
|
||||
};
|
||||
|
||||
template<class I, typename E>
|
||||
struct InterpreterScheme<HandlerFun<I,E>>
|
||||
{
|
||||
using Val = E;
|
||||
using Interpreter = I;
|
||||
using Handler = HandlerFun<I,E>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Definition frame for a language to describe differences in data structures.
|
||||
* We use a \em linearised representation as a sequence of DiffStep messages
|
||||
|
|
@ -146,33 +177,6 @@ namespace diff{
|
|||
};
|
||||
};
|
||||
|
||||
template<class I, typename E>
|
||||
using HandlerFun = void (I::*) (E);
|
||||
|
||||
|
||||
template<class I>
|
||||
struct InterpreterScheme
|
||||
{
|
||||
using Interpreter = I;
|
||||
using Val = typename I::Val;
|
||||
using Handler = HandlerFun<I,Val>;
|
||||
};
|
||||
|
||||
template<template<typename> class IP, typename E>
|
||||
struct InterpreterScheme<IP<E>>
|
||||
{
|
||||
using Val = E;
|
||||
using Interpreter = IP<E>;
|
||||
using Handler = HandlerFun<Interpreter,Val>;
|
||||
};
|
||||
|
||||
template<class I, typename E>
|
||||
struct InterpreterScheme<HandlerFun<I,E>>
|
||||
{
|
||||
using Val = E;
|
||||
using Interpreter = I;
|
||||
using Handler = HandlerFun<I,E>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -215,9 +219,10 @@ namespace diff{
|
|||
}
|
||||
|
||||
/** shortcut to define tokens of the diff language.
|
||||
* Use it to define namespace level function objects, which,
|
||||
* Use it to define namespace or class level function objects, which,
|
||||
* when supplied with an argument value of type \c E, will generate
|
||||
* a specific language token wrapping a copy of this element.
|
||||
* @see ListDiffLanguage usage example
|
||||
* @note need a typedef \c Interpreter at usage site
|
||||
* to refer to the actual language interpreter interface;
|
||||
* the template parameters of the Language and the element
|
||||
|
|
|
|||
|
|
@ -76,76 +76,8 @@ namespace diff{
|
|||
|
||||
using DiffStep = typename ListDiffLanguage<Val>::DiffStep;
|
||||
|
||||
/**
|
||||
* @internal state frame for diff detection and generation.
|
||||
* A diff generation process is built on top of an "old" reference point
|
||||
* and a "new" state of the underlying sequence. Within this reference frame,
|
||||
* an demand-driven evaluation of the differences is handed out to the client
|
||||
* as an iterator. While consuming this evaluation process, both the old and
|
||||
* the new version of the sequence will be traversed once. In case of re-orderings,
|
||||
* a nested forward lookup similar to insertion sort will look for matches in the
|
||||
* old sequence, rendering the whole evaluation quadratic in worst-case.
|
||||
*/
|
||||
class DiffFrame
|
||||
{
|
||||
Idx old_;
|
||||
Idx* new_;
|
||||
size_t oldHead_=0,
|
||||
newHead_=0;
|
||||
|
||||
static ListDiffLanguage<Val> token;
|
||||
|
||||
DiffStep currentStep_{token.skip(Val())};
|
||||
|
||||
bool hasOld() const { return oldHead_ < old_.size(); }
|
||||
bool hasNew() const { return newHead_ < new_->size(); }
|
||||
|
||||
public:
|
||||
DiffFrame(Idx& current, Idx&& refPoint)
|
||||
: old_(refPoint)
|
||||
, new_(¤t)
|
||||
{ }
|
||||
|
||||
|
||||
/* === Iteration control API for IterStateWrapper== */
|
||||
|
||||
friend bool
|
||||
checkPoint (DiffFrame const& frame)
|
||||
{
|
||||
return frame.hasNew() || frame.hasOld();
|
||||
}
|
||||
|
||||
friend DiffStep&
|
||||
yield (DiffFrame const& frame)
|
||||
{
|
||||
REQUIRE (checkPoint (frame));
|
||||
return unConst(frame).currentStep_;
|
||||
}
|
||||
|
||||
friend void
|
||||
iterNext (DiffFrame & frame)
|
||||
{
|
||||
frame.establishInvariant();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
establishInvariant()
|
||||
{
|
||||
if (canPick())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
canPick()
|
||||
{
|
||||
return false;//TODO
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
/** @internal state frame for diff detection and generation. */
|
||||
class DiffFrame;
|
||||
|
||||
|
||||
|
||||
|
|
@ -194,10 +126,86 @@ namespace diff{
|
|||
return Diff(DiffFrame(refIdx_, move(mark)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A diff generation process is built on top of an "old" reference point
|
||||
* and a "new" state of the underlying sequence. Within this reference frame,
|
||||
* an demand-driven evaluation of the differences is handed out to the client
|
||||
* as an iterator. While consuming this evaluation process, both the old and
|
||||
* the new version of the sequence will be traversed once. In case of re-orderings,
|
||||
* a nested forward lookup similar to insertion sort will look for matches in the
|
||||
* old sequence, rendering the whole evaluation quadratic in worst-case.
|
||||
*/
|
||||
template<class SEQ>
|
||||
class DiffDetector<SEQ>::DiffFrame
|
||||
{
|
||||
Idx old_;
|
||||
Idx* new_;
|
||||
size_t oldHead_=0,
|
||||
newHead_=0;
|
||||
|
||||
static ListDiffLanguage<Val> token;
|
||||
|
||||
DiffStep currentStep_{token.skip (Val())};
|
||||
|
||||
bool hasOld() const { return oldHead_ < old_.size(); }
|
||||
bool hasNew() const { return newHead_ < new_->size(); }
|
||||
|
||||
public:
|
||||
DiffFrame(Idx& current, Idx&& refPoint)
|
||||
: old_(refPoint)
|
||||
, new_(¤t)
|
||||
{ }
|
||||
|
||||
|
||||
/* === Iteration control API for IterStateWrapper== */
|
||||
|
||||
friend bool
|
||||
checkPoint (DiffFrame const& frame)
|
||||
{
|
||||
return frame.hasNew() || frame.hasOld();
|
||||
}
|
||||
|
||||
friend DiffStep&
|
||||
yield (DiffFrame const& frame)
|
||||
{
|
||||
REQUIRE (checkPoint (frame));
|
||||
return unConst(frame).currentStep_;
|
||||
}
|
||||
|
||||
friend void
|
||||
iterNext (DiffFrame & frame)
|
||||
{
|
||||
frame.establishInvariant();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
establishInvariant()
|
||||
{
|
||||
if (canPick())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
canPick()
|
||||
{
|
||||
return false;//TODO
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/** allocate static storage for the diff language token builder functions */
|
||||
template<class SEQ>
|
||||
ListDiffLanguage<typename DiffDetector<SEQ>::Val> DiffDetector<SEQ>::DiffFrame::token;
|
||||
|
||||
|
||||
//#########################
|
||||
namespace test{
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue