diff --git a/alib2common/src/core/visitor.hpp b/alib2common/src/core/visitor.hpp index 1fd3034450734e1ddf3a93e498eff6fdeabec217..c6110ac1aeb46abb80256987633e0249a59172b7 100644 --- a/alib2common/src/core/visitor.hpp +++ b/alib2common/src/core/visitor.hpp @@ -13,49 +13,64 @@ namespace core { -template < class ... Visitables > -class VisitorContextBaseBuilder; - -template < class Visitable > -class VisitorContextBaseBuilder < Visitable > { -public: - virtual void visit ( const Visitable & ) = 0; -}; - -template < class Visitable, class ... Visitables > -class VisitorContextBaseBuilder < Visitable, Visitables ... > : public VisitorContextBaseBuilder < Visitables ... > { -public: - using VisitorContextBaseBuilder < Visitables ... >::visit; - - virtual void visit ( const Visitable & ) = 0; -}; - -template < class ... Visitables > -class VisitorContextBase : public VisitorContextBaseBuilder < Visitables ... > { -}; - -// ----------------------------------------------------------------- - +/** + * \brief + * Class implementing an actual visitor interface to the visitor. + * + * The interface is represented by the return type, the visitor class implementing the callbacks, and additional params of the call. + * + */ template < class ReturnType, class Visitor, class ... Params > class VisitorContextAux { + /** + * \brief + * A place for the result. + */ typename std::aligned_storage < ext::SizeOf < ReturnType >::size, ext::AlignOf < ReturnType >::align >::type result; + /** + * \brief + * A place for the params. + */ ext::tuple < Params ... > m_params; public: + /** + * \brief + * Constructor for initialisation of the visitor context, i.e. additional call parameters. + */ VisitorContextAux ( Params && ... params ) : m_params ( std::forward < Params > ( params ) ... ) { } + /** + * \brief + * Call method to the visitors visit method. The actuall class of visited object is already evaluated here. + * + * This call method is enabled if the return type is not void. + */ template < class Inherit, size_t ... Indexes, class ReturnType2 = ReturnType > void call ( const Inherit & inherit, std::index_sequence < Indexes ... >, typename std::enable_if < !std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) { - new ( & result )ReturnType ( Visitor::visit ( inherit, std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); + new ( & result ) ReturnType ( Visitor::visit ( inherit, std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); } + + /** + * \brief + * Call method to the visitors visit method. The actuall class of visited object is already evaluated here. + * + * This call method is enabled if the return type is void. + */ template < class Inherit, size_t ... Indexes, class ReturnType2 = ReturnType > void call ( const Inherit & inherit, std::index_sequence < Indexes ... >, typename std::enable_if < std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) { ReturnType ( Visitor::visit ( inherit, std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); } + /** + * \brief + * Visit result getter. + * + * Enabled if the return type is not void. + */ template < class ReturnType2 = ReturnType > ReturnType getResult ( typename std::enable_if < !std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) { ReturnType res = reinterpret_cast < ReturnType && > ( result ); @@ -64,6 +79,12 @@ public: return res; } + /** + * \brief + * Visit result getter. + * + * Enabled if the return type not void. + */ template < class ReturnType2 = ReturnType > void getResult ( typename std::enable_if < std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) { }