corelib/include/ebcl/inline/Algorithms.hh

84 lines
2.1 KiB
C++
Raw Normal View History

2017-11-08 09:07:04 +01:00
/******************************************************************************/
/* 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