Algorithms - Visitor implementation
This commit is contained in:
parent
46fa84d967
commit
0bc11d32d7
2 changed files with 178 additions and 0 deletions
include/ebcl/inline
83
include/ebcl/inline/Algorithms.hh
Normal file
83
include/ebcl/inline/Algorithms.hh
Normal file
|
@ -0,0 +1,83 @@
|
|||
/******************************************************************************/
|
||||
/* ALGORITHMS - INLINE CODE ***************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef _H_EBCL_INLINE_ALGORITHMS
|
||||
#define _H_EBCL_INLINE_ALGORITHMS
|
||||
#include <ebcl/Algorithms.hh>
|
||||
namespace ebcl {
|
||||
|
||||
|
||||
/*= VISITOR ==================================================================*/
|
||||
|
||||
// Specialization of the visitor helper for references
|
||||
template< typename R >
|
||||
struct T_VisitorHelper_< R , true >
|
||||
{
|
||||
using T_Base = typename std::remove_reference< R >::type;
|
||||
using T_Opt = T_Base*;
|
||||
using T_StackRef = T_Base*;
|
||||
|
||||
static T_StackRef mkext( R value ) noexcept { return &value; }
|
||||
static R deref( T_StackRef ref ) noexcept { return *ref; }
|
||||
};
|
||||
|
||||
// Specialization of the visitor helper for values
|
||||
template< typename R >
|
||||
struct T_VisitorHelper_< R , false >
|
||||
{
|
||||
using T_Base = typename std::remove_const< R >::type;
|
||||
using T_Opt = T_Optional< T_Base >;
|
||||
using T_StackRef = T_Base;
|
||||
|
||||
static T_StackRef mkext( R value ) noexcept { return value; }
|
||||
static R deref( T_StackRef ref ) noexcept { return ref; }
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T , typename R >
|
||||
inline T_Visitor< T , R >::T_Visitor(
|
||||
F_NodeBrowser browser ) noexcept
|
||||
: nodeBrowser_( std::move( browser ) )
|
||||
{ }
|
||||
|
||||
template< typename T , typename R >
|
||||
inline void T_Visitor< T , R >::visit(
|
||||
R root ,
|
||||
F_NodeAction action )
|
||||
{
|
||||
stack_.addNew( root , 0 );
|
||||
|
||||
while ( !stack_.empty( ) ) {
|
||||
auto& n( stack_.last( ) );
|
||||
switch ( n.state ) {
|
||||
case BEFORE:
|
||||
n.state = action( Helper_::deref( n.node ) , false )
|
||||
? CHILDREN : AFTER;
|
||||
break;
|
||||
|
||||
case CHILDREN: {
|
||||
const T_OptNode child{
|
||||
nodeBrowser_( Helper_::deref( n.node ) , n.child ++ ) };
|
||||
if ( child ) {
|
||||
stack_.addNew( *child , 0 );
|
||||
} else {
|
||||
n.state = AFTER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AFTER:
|
||||
action( Helper_::deref( n.node ) , true );
|
||||
stack_.removeLast( );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
#endif // _H_EBCL_INLINE_ALGORITHMS
|
Loading…
Add table
Add a link
Reference in a new issue