Rani Sharoni's port
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@33 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
b233e001b3
commit
301d96c6a1
26 changed files with 7909 additions and 694 deletions
328
MSVC/1300/Visitor.h
Normal file
328
MSVC/1300/Visitor.h
Normal file
|
@ -0,0 +1,328 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The Loki Library
|
||||
// Copyright (c) 2001 by Andrei Alexandrescu
|
||||
// This code accompanies the book:
|
||||
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
||||
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||||
// Permission to use, copy, modify, distribute and sell this software for any
|
||||
// purpose is hereby granted without fee, provided that the above copyright
|
||||
// notice appear in all copies and that both that copyright notice and this
|
||||
// permission notice appear in supporting documentation.
|
||||
// The author or Addison-Welsey Longman make no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Last update: May 19, 2002
|
||||
|
||||
#ifndef VISITOR_INC_
|
||||
#define VISITOR_INC_
|
||||
|
||||
#include "Typelist.h"
|
||||
#include "HierarchyGenerators.h"
|
||||
|
||||
namespace Loki
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template BaseVisitor
|
||||
// The base class of any Acyclic Visitor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class BaseVisitor
|
||||
{
|
||||
public:
|
||||
virtual ~BaseVisitor() {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template Visitor
|
||||
// Forward decleration
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T, typename R = void>
|
||||
class Visitor;
|
||||
|
||||
namespace Private
|
||||
{
|
||||
// for some reason VC7 needs the base definition altough not in use
|
||||
template <typename TListTag>
|
||||
struct VisitorHelper1
|
||||
{
|
||||
template <typename T, typename R>
|
||||
struct In
|
||||
{
|
||||
typedef typename T::ERROR_THIS_INSTANCE_SELECTED Result;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename TListTag>
|
||||
struct VisitorHelper2
|
||||
{
|
||||
template <typename T, typename R>
|
||||
struct In
|
||||
{
|
||||
typedef typename T::ERROR_THIS_INSTANCE_SELECTED Result;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VisitorHelper1<TL::Typelist_tag>
|
||||
{
|
||||
template <class TList, typename R>
|
||||
struct In
|
||||
{
|
||||
typedef Visitor<typename TList::Head, R> Result;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VisitorHelper2<TL::Typelist_tag>
|
||||
{
|
||||
template <class TList, typename R>
|
||||
struct In
|
||||
{
|
||||
private:
|
||||
template<typename Tail>
|
||||
struct In1
|
||||
{
|
||||
typedef Visitor<typename TList::Tail, R> Result;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct In1<NullType>
|
||||
{
|
||||
struct Result {};
|
||||
};
|
||||
|
||||
public:
|
||||
typedef typename In1<typename TList::Tail>::Result Result;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct VisitorHelper1<TL::NoneList_tag>
|
||||
{
|
||||
template <class T, typename R>
|
||||
struct In
|
||||
{
|
||||
struct Result
|
||||
{
|
||||
typedef R ReturnType;
|
||||
virtual ReturnType Visit(T&) = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VisitorHelper2<TL::NoneList_tag>
|
||||
{
|
||||
template <class T, typename R>
|
||||
struct In { struct Result {}; };
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template Visitor
|
||||
// The building block of Acyclic Visitor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T, typename R>
|
||||
class Visitor
|
||||
: public Private::VisitorHelper1
|
||||
<
|
||||
typename TL::is_Typelist<T>::type_tag
|
||||
>
|
||||
::template In<T, R>::Result
|
||||
|
||||
, public Private::VisitorHelper2
|
||||
<
|
||||
typename TL::is_Typelist<T>::type_tag
|
||||
>
|
||||
::template In<T, R>::Result
|
||||
{
|
||||
public:
|
||||
typedef R ReturnType;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template BaseVisitorImpl
|
||||
// Implements non-strict visitation (you can implement only part of the Visit
|
||||
// functions)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <class TList, typename R = void>
|
||||
class BaseVisitorImpl;
|
||||
|
||||
namespace Private
|
||||
{
|
||||
// for some reason VC7 needs the base definition altough not in use
|
||||
template<typename TListTag>
|
||||
struct BaseVisitorImplHelper
|
||||
{
|
||||
template <typename T, typename R>
|
||||
struct In
|
||||
{
|
||||
typedef typename T::ERROR_THIS_INSTANCE_SELECTED Result;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BaseVisitorImplHelper<TL::Typelist_tag>
|
||||
{
|
||||
template <typename TList, typename R>
|
||||
struct In
|
||||
{
|
||||
typedef BaseVisitorImpl<TList, R> Result;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BaseVisitorImplHelper<TL::NullType_tag>
|
||||
{
|
||||
template <typename TList, typename R>
|
||||
struct In
|
||||
{
|
||||
struct Result {};
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
template <class TList, typename R>
|
||||
class BaseVisitorImpl
|
||||
: public Visitor<typename TList::Head, R>
|
||||
|
||||
, public Private::BaseVisitorImplHelper
|
||||
<
|
||||
typename TL::is_Typelist<typename TList::Tail>::type_tag
|
||||
>
|
||||
::template In<typename TList::Tail, R>::Result
|
||||
{
|
||||
ASSERT_TYPELIST(TList);
|
||||
|
||||
public:
|
||||
// using BaseVisitorImpl<Tail, R>::Visit;
|
||||
|
||||
virtual R Visit(typename TList::Head&)
|
||||
{ return R(); }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template NonStrictVisitor
|
||||
// Implements non-strict visitation (you can implement only part of the Visit
|
||||
// functions)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T, class Base>
|
||||
struct NonStrictVisitorUnit : public Base
|
||||
{
|
||||
typedef typename Base::ReturnType ReturnType;
|
||||
ReturnType Visit(T&)
|
||||
{
|
||||
return ReturnType();
|
||||
}
|
||||
};
|
||||
|
||||
template <class TList, typename R = void>
|
||||
class NonStrictVisitor
|
||||
: public GenLinearHierarchy<
|
||||
TList,
|
||||
NonStrictVisitorUnit,
|
||||
Visitor<TList, R> >
|
||||
{
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template BaseVisitable
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename R, typename Visited>
|
||||
struct DefaultCatchAll
|
||||
{
|
||||
static R OnUnknownVisitor(Visited&, BaseVisitor&)
|
||||
{ return R(); }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template BaseVisitable
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template
|
||||
<
|
||||
typename R = void,
|
||||
template <typename, class> class CatchAll = DefaultCatchAll
|
||||
>
|
||||
class BaseVisitable
|
||||
{
|
||||
public:
|
||||
typedef R ReturnType;
|
||||
virtual ~BaseVisitable() {}
|
||||
virtual ReturnType Accept(BaseVisitor&) = 0;
|
||||
|
||||
protected: // give access only to the hierarchy
|
||||
template <class T>
|
||||
static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
|
||||
{
|
||||
// Apply the Acyclic Visitor
|
||||
if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(&guest))
|
||||
{
|
||||
return p->Visit(visited);
|
||||
}
|
||||
return CatchAll<R, T>::OnUnknownVisitor(visited, guest);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// macro DEFINE_VISITABLE
|
||||
// Put it in every class that you want to make visitable (in addition to
|
||||
// deriving it from BaseVisitable<R>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define DEFINE_VISITABLE() \
|
||||
virtual ReturnType Accept(BaseVisitor& guest) \
|
||||
{ return AcceptImpl(*this, guest); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class template CyclicVisitor
|
||||
// Put it in every class that you want to make visitable (in addition to
|
||||
// deriving it from BaseVisitable<R>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename R, class TList>
|
||||
class CyclicVisitor : public Visitor<TList, R>
|
||||
{
|
||||
public:
|
||||
typedef R ReturnType;
|
||||
// using Visitor<TList, R>::Visit;
|
||||
|
||||
virtual ~CyclicVisitor() {}
|
||||
|
||||
template <class Visited>
|
||||
ReturnType GenericVisit(Visited& host)
|
||||
{
|
||||
Visitor<Visited, ReturnType>& subObj = *this;
|
||||
return subObj.Visit(host);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// macro DEFINE_CYCLIC_VISITABLE
|
||||
// Put it in every class that you want to make visitable by a cyclic visitor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define DEFINE_CYCLIC_VISITABLE(SomeVisitor) \
|
||||
virtual SomeVisitor::ReturnType Accept(SomeVisitor& guest) \
|
||||
{ return guest.GenericVisit(*this); }
|
||||
} // namespace Loki
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Change log:
|
||||
// March 20: add default argument DefaultCatchAll to BaseVisitable
|
||||
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // VISITOR_INC_
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue