Skip to content
Snippets Groups Projects
Commit f9100b0b authored by Jan Trávníček's avatar Jan Trávníček
Browse files

add visitor helper class

parent 5cc47c19
No related branches found
No related tags found
No related merge requests found
/*
* UnboundedRegExpElement.h
*
* Created on: Nov 23, 2013
* Author: Jan Travnicek
*/
#ifndef VISITOR_HPP_
#define VISITOR_HPP_
#include <variant>
namespace std {
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 ... > {
};
// -----------------------------------------------------------------
template < class ReturnType, class Visitor, class ... Params >
class VisitorContextAux {
typename std::aligned_storage < SizeOf < ReturnType >::size, AlignOf < ReturnType >::align >::type result;
std::tuple < Params ... > params;
public:
VisitorContextAux ( Params && ... params ) : params ( std::forward < Params > ( params ) ... ) {
}
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 > ( params ) ) ... ) );
}
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 > ( params ) ) ... ) );
}
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 );
// reinterpret_cast < ReturnType * > ( & result )->~ReturnType ( ); // not needed to delete; data gets moved from on previous line
return res;
}
template < class ReturnType2 = ReturnType >
void getResult ( typename std::enable_if < std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) {
}
};
} /* namespace std */
#endif /* VISITOR_HPP_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment