83 lines
2.1 KiB
C++
83 lines
2.1 KiB
C++
/******************************************************************************/
|
|
/* 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
|