/******************************************************************************/ /* ALGORITHMS - INLINE CODE ***************************************************/ /******************************************************************************/ #ifndef _H_EBCL_INLINE_ALGORITHMS #define _H_EBCL_INLINE_ALGORITHMS #include 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