/*========================================================================= Program: Visualization Toolkit Module: vtkDispatcher.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ //////////////////////////////////////////////////////////////////////////////// // 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-Wesley Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef vtkDispatcher_Private_h #define vtkDispatcher_Private_h #include "vtkConfigure.h" #ifndef VTK_LEGACY_REMOVE #ifndef __VTK_WRAP__ #include #include #include namespace vtkDispatcherPrivate { //////////////////////////////////////////////////////////////////////////////// // Dispatch helper for reference functors //////////////////////////////////////////////////////////////////////////////// template class FunctorRefDispatcherHelper { Fun& fun_; public: typedef RT ResultType; FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper& rhs) : fun_(rhs.fun_) { } FunctorRefDispatcherHelper(Fun& f) : fun_(f) { } ResultType operator()(BaseLhs& lhs) { return fun_(CastLhs::Cast(lhs)); } private: FunctorRefDispatcherHelper& operator=(const FunctorRefDispatcherHelper& b); }; //////////////////////////////////////////////////////////////////////////////// // Dispatch helper //////////////////////////////////////////////////////////////////////////////// template class FunctorDispatcherHelper { Fun fun_; public: typedef RT ResultType; FunctorDispatcherHelper(const FunctorDispatcherHelper& rhs) : fun_(rhs.fun_) { } FunctorDispatcherHelper(Fun fun) : fun_(fun) { } ResultType operator()(BaseLhs& lhs) { return fun_(CastLhs::Cast(lhs)); } }; //////////////////////////////////////////////////////////////////////////////// // Parent class for all FunctorImpl, helps hide functor template args //////////////////////////////////////////////////////////////////////////////// template class FunctorImpl { public: typedef R ResultType; typedef P1 Parm1; virtual ~FunctorImpl() {} virtual R operator()(P1&) = 0; virtual FunctorImpl* DoClone() const = 0; template static U* Clone(U* pObj) { if (!pObj) return nullptr; U* pClone = static_cast(pObj->DoClone()); assert(typeid(*pClone) == typeid(*pObj)); return pClone; } protected: FunctorImpl() {} FunctorImpl(const FunctorImpl&) {} private: FunctorImpl& operator=(const FunctorImpl&) = delete; }; //////////////////////////////////////////////////////////////////////////////// // Impl functor that calls a user functor //////////////////////////////////////////////////////////////////////////////// template class FunctorHandler : public ParentFunctor::Impl { typedef typename ParentFunctor::Impl Base; public: typedef typename Base::ResultType ResultType; typedef typename Base::Parm1 Parm1; FunctorHandler(Fun& fun) : f_(fun) { } ~FunctorHandler() override {} ResultType operator()(Parm1& p1) override { return f_(p1); } FunctorHandler* DoClone() const override { return new FunctorHandler(*this); } private: Fun f_; FunctorHandler(const FunctorHandler& b) : ParentFunctor::Impl(b) , f_(b.f_) { } FunctorHandler& operator=(const FunctorHandler& b) = delete; }; //////////////////////////////////////////////////////////////////////////////// // Functor wrapper class //////////////////////////////////////////////////////////////////////////////// template class Functor { public: typedef FunctorImpl Impl; typedef R ResultType; Functor() : spImpl_() { } Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) { } template Functor(Fun fun) : spImpl_(new FunctorHandler(fun)) { } Functor& operator=(const Functor& rhs) { Functor copy(rhs); spImpl_.swap(copy.spImpl_); return *this; } ResultType operator()(Parm1& p1) { return (*spImpl_)(p1); } private: std::unique_ptr spImpl_; }; } namespace vtkDoubleDispatcherPrivate { //////////////////////////////////////////////////////////////////////////////// // Dispatch helper //////////////////////////////////////////////////////////////////////////////// template class FunctorRefDispatcherHelper { Fun& fun_; public: typedef RT ResultType; FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper& rhs) : fun_(rhs.fun_) { } FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) { } ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) { return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); } private: FunctorRefDispatcherHelper& operator=(const FunctorRefDispatcherHelper& b); }; template class FunctorDoubleDispatcherHelper { Fun fun_; public: typedef RT ResultType; FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper& rhs) : fun_(rhs.fun_) { } FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) { } ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) { return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); } }; //////////////////////////////////////////////////////////////////////////////// // Parent class for all FunctorImpl, helps hide functor template args //////////////////////////////////////////////////////////////////////////////// template class FunctorImpl { public: typedef R ResultType; typedef P1 Parm1; typedef P2 Parm2; virtual ~FunctorImpl() {} virtual R operator()(P1&, P2&) = 0; virtual FunctorImpl* DoClone() const = 0; template static U* Clone(U* pObj) { if (!pObj) return nullptr; U* pClone = static_cast(pObj->DoClone()); assert(typeid(*pClone) == typeid(*pObj)); return pClone; } protected: FunctorImpl() {} FunctorImpl(const FunctorImpl&) {} private: FunctorImpl& operator=(const FunctorImpl&) = delete; }; //////////////////////////////////////////////////////////////////////////////// // Impl functor that calls a user functor //////////////////////////////////////////////////////////////////////////////// template class FunctorHandler : public ParentFunctor::Impl { typedef typename ParentFunctor::Impl Base; public: typedef typename Base::ResultType ResultType; typedef typename Base::Parm1 Parm1; typedef typename Base::Parm2 Parm2; FunctorHandler(const Fun& fun) : f_(fun) { } ~FunctorHandler() override {} ResultType operator()(Parm1& p1, Parm2& p2) override { return f_(p1, p2); } FunctorHandler* DoClone() const override { return new FunctorHandler(*this); } private: Fun f_; FunctorHandler(const FunctorHandler& b) : ParentFunctor::Impl(b) , f_(b.f_) { } FunctorHandler& operator=(const FunctorHandler& b) = delete; }; //////////////////////////////////////////////////////////////////////////////// // Functor wrapper class //////////////////////////////////////////////////////////////////////////////// template class Functor { public: typedef FunctorImpl Impl; typedef R ResultType; Functor() : spImpl_() { } Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) { } template Functor(const Fun& fun) : spImpl_(new FunctorHandler(fun)) { } Functor& operator=(const Functor& rhs) { Functor copy(rhs); spImpl_.swap(copy.spImpl_); return *this; } ResultType operator()(Parm1& p1, Parm2& p2) { return (*spImpl_)(p1, p2); } private: std::unique_ptr spImpl_; }; } namespace vtkDispatcherCommon { template struct DynamicCaster { static To& Cast(From& obj) { return dynamic_cast(obj); } static To* Cast(From* obj) { return dynamic_cast(obj); } }; template struct vtkCaster { static To& Cast(From& obj) { return *(To::SafeDownCast(&obj)); } static To* Cast(From* obj) { return To::SafeDownCast(obj); } }; class TypeInfo { public: // Constructors TypeInfo(); // needed for containers TypeInfo(const std::type_info&); // non-explicit // Access for the wrapped std::type_info const std::type_info& Get() const; // Compatibility functions bool before(const TypeInfo& rhs) const; const char* name() const; private: const std::type_info* pInfo_; }; // Implementation inline TypeInfo::TypeInfo() { class Nil { }; pInfo_ = &typeid(Nil); assert(pInfo_); } inline TypeInfo::TypeInfo(const std::type_info& ti) : pInfo_(&ti) { assert(pInfo_); } inline bool TypeInfo::before(const TypeInfo& rhs) const { assert(pInfo_); // type_info::before return type is int in some VC libraries return pInfo_->before(*rhs.pInfo_) != 0; } inline const std::type_info& TypeInfo::Get() const { assert(pInfo_); return *pInfo_; } inline const char* TypeInfo::name() const { assert(pInfo_); return pInfo_->name(); } // Comparison operators inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs) // type_info::operator== return type is int in some VC libraries { return (lhs.Get() == rhs.Get()) != 0; } inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs) { return lhs.before(rhs); } inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs) { return !(lhs == rhs); } inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs) { return rhs < lhs; } inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs) { return !(lhs > rhs); } inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs) { return !(lhs < rhs); } } #endif // wrapping #endif // legacy remove #endif // vtkDispatcherPrivate_h // VTK-HeaderTest-Exclude: vtkDispatcher_Private.h