33 #include <boost/mpl/assert.hpp>
34 #include <boost/mpl/list.hpp>
35 #include <boost/mpl/front.hpp>
36 #include <boost/mpl/pop_front.hpp>
38 #include <feel/feelcore/feel.hpp>
42 namespace mpl=boost::mpl;
96 typedef R return_type;
111 virtual return_type
visit( T* ) = 0;
116 return visit( &__t );
128 public Visitor<typename mpl::front<TList>::type, R>,
129 public mpl::if_<mpl::greater<mpl::size<TList>,mpl::long_<1l> >,
130 mpl::identity<VisitorList<mpl::pop_front<TList>,R> >,
131 mpl::identity<mpl::identity<VisitorBase> > >::type::type
134 typedef typename mpl::if_<mpl::equal_to<mpl::size<TList>,mpl::int_<2> >,
136 mpl::identity<C> >::type::type the_type;
174 class Visitor< mpl::list<Head, Tail>, R >
176 public Visitor<Head, R>,
177 public Visitor<Tail, R>
180 typedef R return_type;
182 using Visitor<Tail, R>::visit;
189 class Visitor< mpl::list<Head>, R>
191 public Visitor<Head, R>
194 typedef R return_type;
225 virtual R visit( Head* )
236 class VisitorBaseImpl< mpl::list<Head>, R >
238 public Visitor<Head, R>
241 virtual R visit( Head* )
255 struct VisitableCatchAllDefault
257 static R onUnknownVisitor( Visited&, VisitorBase& )
262 static R onUnknownVisitor( Visited*, VisitorBase* )
275 template <
class,
class>
class CatchAll = VisitableCatchAllDefault
281 typedef R return_type;
283 virtual ~VisitableBase() {}
286 virtual return_type accept( VisitorBase& ) = 0;
289 virtual return_type accept( VisitorBase* ) = 0;
301 acceptImpl( T* visited, VisitorBase* guest )
304 if ( Visitor<T>* p =
dynamic_cast< Visitor<T>*
>( guest ) )
306 return p->visit( visited );
309 return CatchAll<R, T>::onUnknownVisitor( visited, guest );
319 #define FEELPP_DEFINE_VISITABLE() \
320 virtual return_type accept( VisitorBase& guest ) \
322 return this->acceptImpl( this, &guest ); \
324 virtual return_type accept( VisitorBase* guest ) \
326 return this->acceptImpl( this, guest ); \
343 typedef R return_type;
346 template <
class Visited>
347 return_type genericVisit( Visited* host )
350 return subObj.visit( host );
353 template <
class Visited>
354 return_type genericVisit( Visited& host )
357 return subObj.visit( host );
367 #define FEELPP__DEFINE_CYCLIC_VISITABLE(SomeVisitor) \
368 virtual SomeVisitor::return_type Accept(SomeVisitor& guest) \
370 return guest.genericVisit(*this); \
372 virtual SomeVisitor::return_type Accept(SomeVisitor* guest) \
374 return guest->genericVisit(*this); \