From 2ffd6b016f449086f8d8d6edb367b177879baacf Mon Sep 17 00:00:00 2001 From: aandrei Date: Wed, 21 Nov 2001 07:28:56 +0000 Subject: [PATCH] First blush git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@6 7ec92016-0320-0410-acc4-a06ded1c099a --- AbstractFactory.h | 159 ++++++ AssocVector.h | 324 +++++++++++ EmptyType.h | 32 ++ Factory.h | 137 +++++ Functor.h | 1121 ++++++++++++++++++++++++++++++++++++++ HierarchyGenerators.h | 233 ++++++++ Mappings.h | 31 ++ MultiMethods.h | 320 +++++++++++ NullType.h | 32 ++ Singleton.cpp | 42 ++ Singleton.h | 421 +++++++++++++++ SmallObj.cpp | 408 ++++++++++++++ SmallObj.h | 176 ++++++ SmartPtr.h | 1183 +++++++++++++++++++++++++++++++++++++++++ Threads.h | 195 +++++++ Tuple.h | 22 + TypeInfo.h | 101 ++++ TypeManip.h | 165 ++++++ TypeTraits.h | 230 ++++++++ Typelist.h | 734 +++++++++++++++++++++++++ Visitor.h | 211 ++++++++ main.cpp | 301 +++++++++++ readme.txt | 17 + static_check.h | 50 ++ 24 files changed, 6645 insertions(+) create mode 100644 AbstractFactory.h create mode 100644 AssocVector.h create mode 100644 EmptyType.h create mode 100644 Factory.h create mode 100644 Functor.h create mode 100644 HierarchyGenerators.h create mode 100644 Mappings.h create mode 100644 MultiMethods.h create mode 100644 NullType.h create mode 100644 Singleton.cpp create mode 100644 Singleton.h create mode 100644 SmallObj.cpp create mode 100644 SmallObj.h create mode 100644 SmartPtr.h create mode 100644 Threads.h create mode 100644 Tuple.h create mode 100644 TypeInfo.h create mode 100644 TypeManip.h create mode 100644 TypeTraits.h create mode 100644 Typelist.h create mode 100644 Visitor.h create mode 100644 main.cpp create mode 100644 readme.txt create mode 100644 static_check.h diff --git a/AbstractFactory.h b/AbstractFactory.h new file mode 100644 index 0000000..d015e43 --- /dev/null +++ b/AbstractFactory.h @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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: February 19, 2001 + +#ifndef ABSTRACTFACTORY_INC_ +#define ABSTRACTFACTORY_INC_ + +#include "Typelist.h" +#include "TypeManip.h" +#include "HierarchyGenerators.h" + +#include + +namespace Loki +{ + +//////////////////////////////////////////////////////////////////////////////// +// class template AbstractFactoryUnit +// The building block of an Abstract Factory +//////////////////////////////////////////////////////////////////////////////// + + template + class AbstractFactoryUnit + { + public: + virtual T* DoCreate(Type2Type) = 0; + virtual ~AbstractFactoryUnit() {} + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template AbstractFactory +// Defines an Abstract Factory interface starting from a typelist +//////////////////////////////////////////////////////////////////////////////// + + template + < + class TList, + template class Unit = AbstractFactoryUnit + > + class AbstractFactory : public GenScatterHierarchy + { + public: + typedef TList ProductList; + + template T* Create() + { + Unit& unit = *this; + return unit.DoCreate(Type2Type()); + } + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template OpNewFactoryUnit +// Creates an object by invoking the new operator +//////////////////////////////////////////////////////////////////////////////// + + template + class OpNewFactoryUnit : public Base + { + typedef typename Base::ProductList BaseProductList; + + protected: + typedef typename BaseProductList::Tail ProductList; + + public: + typedef BaseProductList::Head AbstractProduct; + ConcreteProduct* DoCreate(Type2Type) + { + return new ConcreteProduct; + } + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template PrototypeFactoryUnit +// Creates an object by cloning a prototype +// There is a difference between the implementation herein and the one described +// in the book: GetPrototype and SetPrototype use the helper friend +// functions DoGetPrototype and DoSetPrototype. The friend functions avoid +// name hiding issues. Plus, GetPrototype takes a reference to pointer +// instead of returning the pointer by value. +//////////////////////////////////////////////////////////////////////////////// + + template + class PrototypeFactoryUnit : public Base + { + typedef typename Base::ProductList BaseProductList; + + protected: + typedef typename BaseProductList::Tail ProductList; + + public: + typedef typename BaseProductList::Head AbstractProduct; + + PrototypeFactoryUnit(AbstractProduct* p = 0) + : pPrototype_(p) + {} + + friend void DoGetPrototype(const PrototypeFactoryUnit& me, + AbstractProduct*& pPrototype) + { pPrototype = me.pPrototype_; } + + friend void DoSetPrototype(PrototypeFactoryUnit& me, + AbstractProduct* pObj) + { me.pPrototype_ = pObj; } + + template + void GetPrototype(AbstractProduct*& p) + { return DoGetPrototype(*this, p); } + + template + void SetPrototype(U* pObj) + { DoSetPrototype(*this, pObj); } + + AbstractProduct* DoCreate(Type2Type) + { + assert(pPrototype_); + return pPrototype_->Clone(); + } + + private: + AbstractProduct* pPrototype_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template ConcreteFactory +// Implements an AbstractFactory interface +//////////////////////////////////////////////////////////////////////////////// + + template + < + class AbstractFact, + template class Creator = OpNewFactoryUnit, + class TList = typename AbstractFact::ProductList + > + class ConcreteFactory + : public GenLinearHierarchy< + typename TL::Reverse::Result, Creator, AbstractFact> + { + public: + typedef typename AbstractFact::ProductList ProductList; + typedef TList ConcreteProductList; + }; + +} // namespace Loki + +#endif // ABSTRACTFACTORY_INC_ \ No newline at end of file diff --git a/AssocVector.h b/AssocVector.h new file mode 100644 index 0000000..0dcc245 --- /dev/null +++ b/AssocVector.h @@ -0,0 +1,324 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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: February 19, 2001 + +#ifndef ASSOCVECTOR_INC_ +#define ASSOCVECTOR_INC_ + +#include +#include +#include +#include +#include + +namespace Loki +{ +//////////////////////////////////////////////////////////////////////////////// +// class template AssocVectorCompare +// Used by AssocVector +//////////////////////////////////////////////////////////////////////////////// + + namespace Private + { + template + class AssocVectorCompare : public C + { + typedef std::pair + Data; + typedef typename C::first_argument_type first_argument_type; + + public: + AssocVectorCompare() + {} + + AssocVectorCompare(const C& src) : C(src) + {} + + bool operator()(const first_argument_type& lhs, + const first_argument_type& rhs) const + { return C::operator()(lhs, rhs); } + + bool operator()(const Data& lhs, const Data& rhs) const + { return operator()(lhs.first, rhs.first); } + + bool operator()(const Data& lhs, + const first_argument_type& rhs) const + { return operator()(lhs.first, rhs); } + + bool operator()(const first_argument_type& lhs, + const Data& rhs) const + { return operator()(lhs, rhs.first); } + }; + } + +//////////////////////////////////////////////////////////////////////////////// +// class template AssocVector +// An associative vector built as a syntactic drop-in replacement for std::map +// BEWARE: AssocVector doesn't respect all map's guarantees, the most important +// being: +// * iterators are invalidated by insert and erase operations +// * the complexity of insert/erase is O(N) not O(log N) +// * value_type is std::pair not std::pair +// * iterators are random +//////////////////////////////////////////////////////////////////////////////// + + template + < + class K, + class V, + class C = std::less, + class A = std::allocator< std::pair > + > + class AssocVector + : private std::vector< std::pair, A > + , private Private::AssocVectorCompare + { + typedef std::vector, A> Base; + typedef Private::AssocVectorCompare MyCompare; + + public: + typedef K key_type; + typedef V mapped_type; + typedef typename Base::value_type value_type; + + typedef C key_compare; + typedef A allocator_type; + typedef typename A::reference reference; + typedef typename A::const_reference const_reference; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::size_type size_type; + typedef typename Base::difference_type difference_type; + typedef typename A::pointer pointer; + typedef typename A::const_pointer const_pointer; + typedef typename Base::reverse_iterator reverse_iterator; + typedef typename Base::const_reverse_iterator const_reverse_iterator; + + class value_compare + : public std::binary_function + , private key_compare + { + friend class AssocVector; + + protected: + value_compare(key_compare pred) : key_compare(pred) + {} + + public: + bool operator()(const value_type& lhs, const value_type& rhs) const + { return key_compare::operator()(lhs.first, rhs.first); } + }; + + // 23.3.1.1 construct/copy/destroy + + explicit AssocVector(const key_compare& comp = key_compare(), + const A& alloc = A()) + : Base(alloc), MyCompare(comp) + {} + + template + AssocVector(InputIterator first, InputIterator last, + const key_compare& comp = key_compare(), + const A& alloc = A()) + : Base(first, last, alloc), MyCompare(comp) + { + MyCompare& me = *this; + std::sort(begin(), end(), me); + } + + AssocVector& operator=(const AssocVector& rhs) + { AssocVector(*this).swap(*this); } + + // iterators: + // The following are here because MWCW gets 'using' wrong + iterator begin() { return Base::begin(); } + const_iterator begin() const { return Base::begin(); } + iterator end() { return Base::end(); } + const_iterator end() const { return Base::end(); } + reverse_iterator rbegin() { return Base::rbegin(); } + const_reverse_iterator rbegin() const { return Base::rbegin(); } + reverse_iterator rend() { return Base::rend(); } + const_reverse_iterator rend() const { return Base::rend(); } + + // capacity: + bool empty() const { return Base::empty(); } + size_type size() const { return Base::size(); } + size_type max_size() { return Base::max_size(); } + + // 23.3.1.2 element access: + mapped_type& operator[](const key_type& key) + { return insert(value_type(key, mapped_type())).first->second; } + + // modifiers: + std::pair insert(const value_type& val) + { + bool found(true); + iterator i(lower_bound(val.first)); + + if (i == end() || operator()(val.first, i->first)) + { + i = Base::insert(i, val); + found = false; + } + return std::make_pair(i, !found); + } + + iterator insert(iterator pos, const value_type& val) + { + if (pos != end() && operator()(*pos, val) && + (pos == end() - 1 || + !operator()(val, pos[1]) && + operator()(pos[1], val))) + { + return Base::insert(pos, val); + } + return insert(val).first; + } + + template + iterator insert(InputIterator first, InputIterator last) + { for (; first != last; ++first) insert(*first); } + + void erase(iterator pos) + { Base::erase(pos); } + + size_type erase(const key_type& k) + { + iterator i(find(k)); + if (i == end()) return 0; + erase(i); + return 1; + } + + void erase(iterator first, iterator last) + { Base::erase(first, last); } + + void swap(AssocVector& other) + { + using namespace std; + Base::swap(other); + MyCompare& me = *this; + MyCompare& rhs = other; + swap(me, rhs); + } + + void clear() + { Base::clear(); } + + // observers: + key_compare key_comp() const + { return *this; } + + value_compare value_comp() const + { + const key_compare& comp = *this; + return value_compare(comp); + } + + // 23.3.1.3 map operations: + iterator find(const key_type& k) + { + iterator i(lower_bound(k)); + if (i != end() && operator()(k, i->first)) + { + i = end(); + } + return i; + } + + const_iterator find(const key_type& k) const + { + const_iterator i(lower_bound(k)); + if (i != end() && operator()(k, i->first)) + { + i = end(); + } + return i; + } + + size_type count(const key_type& k) const + { return find(k) != end(); } + + iterator lower_bound(const key_type& k) + { + MyCompare& me = *this; + return std::lower_bound(begin(), end(), k, me); + } + + const_iterator lower_bound(const key_type& k) const + { + const MyCompare& me = *this; + return std::lower_bound(begin(), end(), k, me); + } + + iterator upper_bound(const key_type& k) + { + MyCompare& me = *this; + return std::upper_bound(begin(), end(), k, me); + } + + const_iterator upper_bound(const key_type& k) const + { + const MyCompare& me = *this; + return std::upper_bound(begin(), end(), k, me); + } + + std::pair equal_range(const key_type& k) + { + MyCompare& me = *this; + return std::equal_range(begin(), end(), k, me); + } + + std::pair equal_range( + const key_type& k) const + { + const MyCompare& me = *this; + return std::equal_range(begin(), end(), k, me)); + } + + friend bool operator==(const AssocVector& lhs, const AssocVector& rhs) + { + const Base& me = lhs; + return me == rhs; + } + + friend bool operator<(const AssocVector& lhs, const AssocVector& rhs) + { + const Base& me = lhs; + return me < rhs; + } + + friend bool operator!=(const AssocVector& lhs, const AssocVector& rhs) + { return !(lhs == rhs); } + + friend bool operator>(const AssocVector& lhs, const AssocVector& rhs) + { return rhs < lhs; } + + friend bool operator>=(const AssocVector& lhs, const AssocVector& rhs) + { return !(lhs < rhs); } + + friend bool operator<=(const AssocVector& lhs, const AssocVector& rhs) + { return !(rhs < lhs); } + }; + + // specialized algorithms: + template + void swap(AssocVector& lhs, AssocVector& rhs) + { lhs.swap(rhs); } + +} // namespace Loki + +#endif // ASSOCVECTOR_INC_ \ No newline at end of file diff --git a/EmptyType.h b/EmptyType.h new file mode 100644 index 0000000..9cd3414 --- /dev/null +++ b/EmptyType.h @@ -0,0 +1,32 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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: February 19, 2001 + +#ifndef EMPTYTYPE_INC_ +#define EMPTYTYPE_INC_ + +namespace Loki +{ +//////////////////////////////////////////////////////////////////////////////// +// class EmptyType +// Used as a class type that doesn't hold anything +// Useful as a strawman class +//////////////////////////////////////////////////////////////////////////////// + + class EmptyType {}; +} + +#endif // EMPTYTYPE_INC_ \ No newline at end of file diff --git a/Factory.h b/Factory.h new file mode 100644 index 0000000..a668eaa --- /dev/null +++ b/Factory.h @@ -0,0 +1,137 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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: February 19, 2001 + +#ifndef FACTORY_INC_ +#define FACTORY_INC_ + +#include "TypeInfo.h" +#include "AssocVector.h" +#include + +namespace Loki +{ + +//////////////////////////////////////////////////////////////////////////////// +// class template DefaultFactoryError +// Manages the "Unknown Type" error in an object factory +//////////////////////////////////////////////////////////////////////////////// + + template + struct DefaultFactoryError + { + struct Exception : public std::exception + { + const char* what() const { return "Unknown Type"; } + }; + + static AbstractProduct* OnUnknownType(IdentifierType) + { + throw Exception(); + } + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template Factory +// Implements a generic object factory +//////////////////////////////////////////////////////////////////////////////// + + template + < + class AbstractProduct, + typename IdentifierType, + typename ProductCreator = AbstractProduct* (*)(), + template + class FactoryErrorPolicy = DefaultFactoryError + > + class Factory + : public FactoryErrorPolicy + { + public: + bool Register(const IdentifierType& id, ProductCreator creator) + { + return associations_.insert( + IdToProductMap::value_type(id, creator)).second; + } + + bool Unregister(const IdentifierType& id) + { + return associations_.erase(id) == 1; + } + + AbstractProduct* CreateObject(const IdentifierType& id) + { + typename IdToProductMap::const_iterator i = associations_.find(id); + if (i != associations_.end()) + { + return (i->second)(); + } + return OnUnknownType(id); + } + + private: + typedef AssocVector IdToProductMap; + IdToProductMap associations_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template CloneFactory +// Implements a generic cloning factory +//////////////////////////////////////////////////////////////////////////////// + + template + < + class AbstractProduct, + class ProductCreator = + AbstractProduct* (*)(const AbstractProduct*), + template + class FactoryErrorPolicy = DefaultFactoryError + > + class CloneFactory + : public FactoryErrorPolicy + { + public: + bool Register(const TypeInfo& ti, ProductCreator creator) + { + return associations_.insert( + IdToProductMap::value_type(ti, creator)).second; + } + + bool Unregister(const TypeInfo& id) + { + return associations_.erase(id) == 1; + } + + AbstractProduct* CreateObject(const AbstractProduct* model) + { + if (model == 0) return 0; + + typename IdToProductMap::const_iterator i = + associations_.find(typeid(*model)); + if (i != associations_.end()) + { + return (i->second)(model); + } + return OnUnknownType(typeid(*model)); + } + + private: + typedef AssocVector IdToProductMap; + IdToProductMap associations_; + }; +} // namespace Loki + +#endif // FACTORY_INC_ \ No newline at end of file diff --git a/Functor.h b/Functor.h new file mode 100644 index 0000000..01dc3e4 --- /dev/null +++ b/Functor.h @@ -0,0 +1,1121 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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: February 19, 2001 + +#ifndef FUNCTOR_INC_ +#define FUNCTOR_INC_ + +#include "Typelist.h" +#include "EmptyType.h" +#include "SmallObj.h" +#include "TypeTraits.h" +#include + +namespace Loki +{ +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl (internal) +//////////////////////////////////////////////////////////////////////////////// + + namespace Private + { + template class ThreadingModel> + struct FunctorImplBase : public SmallObject + { + typedef R ResultType; + + typedef EmptyType Parm1; + typedef EmptyType Parm2; + typedef EmptyType Parm3; + typedef EmptyType Parm4; + typedef EmptyType Parm5; + typedef EmptyType Parm6; + typedef EmptyType Parm7; + typedef EmptyType Parm8; + typedef EmptyType Parm9; + typedef EmptyType Parm10; + typedef EmptyType Parm11; + typedef EmptyType Parm12; + typedef EmptyType Parm13; + typedef EmptyType Parm14; + typedef EmptyType Parm15; + + virtual FunctorImplBase* DoClone() const = 0; + template + static U* Clone(U* pObj) + { + if (!pObj) return 0; + U* pClone = static_cast(pObj->DoClone()); + assert(typeid(*pClone) == typeid(*pObj)); + return pClone; + } + }; + } + +//////////////////////////////////////////////////////////////////////////////// +// macro DEFINE_CLONE_FUNCTORIMPL +// Implements the DoClone function for a functor implementation +//////////////////////////////////////////////////////////////////////////////// + +#define DEFINE_CLONE_FUNCTORIMPL(Cls) \ + virtual Cls* DoClone() const { return new Cls(*this); } + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// The base class for a hierarchy of functors. The FunctorImpl class is not used +// directly; rather, the Functor class manages and forwards to a pointer to +// FunctorImpl +// You may want to derive your own functors from FunctorImpl. +// Specializations of FunctorImpl for up to 15 parameters follow +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel = DEFAULT_THREADING> + class FunctorImpl; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 0 (zero) parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + virtual R operator()() = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 1 parameter +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + virtual R operator()(Parm1) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 2 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + virtual R operator()(Parm1, Parm2) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 3 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + virtual R operator()(Parm1, Parm2, Parm3) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 4 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 5 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 6 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 7 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 8 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 9 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 10 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 11 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 12 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 13 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 14 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + typedef typename TypeTraits::ParameterType Parm14; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 15 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + typedef typename TypeTraits::ParameterType Parm14; + typedef typename TypeTraits::ParameterType Parm15; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14, + Parm15) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorHandler +// Wraps functors and pointers to functions +//////////////////////////////////////////////////////////////////////////////// + + template + class FunctorHandler + : public ParentFunctor::Impl + { + typedef typename ParentFunctor::Impl Base; + + public: + using typename Base::ResultType; + using typename Base::Parm1; + using typename Base::Parm2; + using typename Base::Parm3; + using typename Base::Parm4; + using typename Base::Parm5; + using typename Base::Parm6; + using typename Base::Parm7; + using typename Base::Parm8; + using typename Base::Parm9; + using typename Base::Parm10; + using typename Base::Parm11; + using typename Base::Parm12; + using typename Base::Parm13; + using typename Base::Parm14; + using typename Base::Parm15; + + FunctorHandler(const Fun& fun) : f_(fun) {} + + DEFINE_CLONE_FUNCTORIMPL(FunctorHandler) + + // operator() implementations for up to 15 arguments + + ResultType operator()() + { return f_(); } + + ResultType operator()(Parm1 p1) + { return f_(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return f_(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return f_(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return f_(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return f_(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return f_(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return f_(p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14, p15); + } + + private: + Fun f_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorHandler +// Wraps pointers to member functions +//////////////////////////////////////////////////////////////////////////////// + + template + class MemFunHandler : public ParentFunctor::Impl + { + typedef typename ParentFunctor::Impl Base; + + public: + using typename Base::ResultType; + using typename Base::Parm1; + using typename Base::Parm2; + using typename Base::Parm3; + using typename Base::Parm4; + using typename Base::Parm5; + using typename Base::Parm6; + using typename Base::Parm7; + using typename Base::Parm8; + using typename Base::Parm9; + using typename Base::Parm10; + using typename Base::Parm11; + using typename Base::Parm12; + using typename Base::Parm13; + using typename Base::Parm14; + using typename Base::Parm15; + + MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) + : pObj_(pObj), pMemFn_(pMemFn) + {} + + DEFINE_CLONE_FUNCTORIMPL(MemFunHandler) + + ResultType operator()() + { return ((*pObj_).*pMemFn_)(); } + + ResultType operator()(Parm1 p1) + { return ((*pObj_).*pMemFn_)(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return ((*pObj_).*pMemFn_)(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return ((*pObj_).*pMemFn_)(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13, p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13, p14, p15); + } + + private: + PointerToObj pObj_; + PointerToMemFn pMemFn_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template Functor +// A generalized functor implementation with value semantics +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel = DEFAULT_THREADING> + class Functor + { + public: + // Handy type definitions for the body type + typedef FunctorImpl Impl; + typedef R ResultType; + typedef TList ParmList; + typedef typename Impl::Parm1 Parm1; + typedef typename Impl::Parm2 Parm2; + typedef typename Impl::Parm3 Parm3; + typedef typename Impl::Parm4 Parm4; + typedef typename Impl::Parm5 Parm5; + typedef typename Impl::Parm6 Parm6; + typedef typename Impl::Parm7 Parm7; + typedef typename Impl::Parm8 Parm8; + typedef typename Impl::Parm9 Parm9; + typedef typename Impl::Parm10 Parm10; + typedef typename Impl::Parm11 Parm11; + typedef typename Impl::Parm12 Parm12; + typedef typename Impl::Parm13 Parm13; + typedef typename Impl::Parm14 Parm14; + typedef typename Impl::Parm15 Parm15; + + // Member functions + + Functor() : spImpl_(0) + {} + + Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) + {} + + Functor(std::auto_ptr spImpl) : spImpl_(spImpl) + {} + + template + Functor(Fun fun) + : spImpl_(new FunctorHandler(fun)) + {} + + template + Functor(const PtrObj& p, MemFn memFn) + : spImpl_(new MemFunHandler(p, memFn)) + {} + + Functor& operator=(const Functor& rhs) + { + Functor copy(rhs); + // swap auto_ptrs by hand + Impl* p = spImpl_.release(); + spImpl_.reset(copy.spImpl_.release()); + copy.spImpl_.reset(p); + return *this; + } + + ResultType operator()() + { return (*spImpl_)(); } + + ResultType operator()(Parm1 p1) + { return (*spImpl_)(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return (*spImpl_)(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return (*spImpl_)(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return (*spImpl_)(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return (*spImpl_)(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return (*spImpl_)(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { + return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, + p12); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { + return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, + p12, p13); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, + p12, p13, p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, + p12, p13, p14, p15); + } + + private: + std::auto_ptr spImpl_; + }; + + namespace Private + { + template struct BinderFirstTraits; + + template class ThreadingModel> + struct BinderFirstTraits< Functor > + { + typedef TL::Erase::Result>::Result + ParmList; + typedef Functor BoundFunctorType; + typedef typename BoundFunctorType::Impl Impl; + }; + } + +//////////////////////////////////////////////////////////////////////////////// +// class template BinderFirst +// Binds the first parameter of a Functor object to a specific value +//////////////////////////////////////////////////////////////////////////////// + + template + class BinderFirst + : public Private::BinderFirstTraits::Impl + { + typedef typename Private::BinderFirstTraits::Impl Base; + typedef typename OriginalFunctor::ResultType ResultType; + + typedef typename OriginalFunctor::Parm1 BoundType; + + typedef typename OriginalFunctor::Parm2 Parm1; + typedef typename OriginalFunctor::Parm3 Parm2; + typedef typename OriginalFunctor::Parm4 Parm3; + typedef typename OriginalFunctor::Parm5 Parm4; + typedef typename OriginalFunctor::Parm6 Parm5; + typedef typename OriginalFunctor::Parm7 Parm6; + typedef typename OriginalFunctor::Parm8 Parm7; + typedef typename OriginalFunctor::Parm9 Parm8; + typedef typename OriginalFunctor::Parm10 Parm9; + typedef typename OriginalFunctor::Parm11 Parm10; + typedef typename OriginalFunctor::Parm12 Parm11; + typedef typename OriginalFunctor::Parm13 Parm12; + typedef typename OriginalFunctor::Parm14 Parm13; + typedef typename OriginalFunctor::Parm15 Parm14; + typedef EmptyType Parm15; + + public: + BinderFirst(const OriginalFunctor& fun, BoundType bound) + : f_(fun), b_(bound) + {} + + DEFINE_CLONE_FUNCTORIMPL(BinderFirst) + + // operator() implementations for up to 15 arguments + + ResultType operator()() + { return f_(b_); } + + ResultType operator()(Parm1 p1) + { return f_(b_, p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return f_(b_, p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return f_(b_, p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return f_(b_, p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return f_(b_, p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return f_(b_, p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14); + } + + private: + OriginalFunctor f_; + BoundType b_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// function template BindFirst +// Binds the first parameter of a Functor object to a specific value +//////////////////////////////////////////////////////////////////////////////// + + template + typename Private::BinderFirstTraits::BoundFunctorType + BindFirst( + const Fctor& fun, + typename Fctor::Parm1 bound) + { + typedef typename Private::BinderFirstTraits::BoundFunctorType + Outgoing; + + return Outgoing(std::auto_ptr( + new BinderFirst(fun, bound))); + } + +//////////////////////////////////////////////////////////////////////////////// +// class template Chainer +// Chains two functor calls one after another +//////////////////////////////////////////////////////////////////////////////// + + template + class Chainer : public Fun2::Impl + { + typedef Fun2 Base; + + public: + using typename Base::ResultType; + using typename Base::Parm1; + using typename Base::Parm2; + using typename Base::Parm3; + using typename Base::Parm4; + using typename Base::Parm5; + using typename Base::Parm6; + using typename Base::Parm7; + using typename Base::Parm8; + using typename Base::Parm9; + using typename Base::Parm10; + using typename Base::Parm11; + using typename Base::Parm12; + using typename Base::Parm13; + using typename Base::Parm14; + using typename Base::Parm15; + + Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {} + + DEFINE_CLONE_FUNCTORIMPL(Chainer) + + // operator() implementations for up to 15 arguments + + ResultType operator()() + { return f1_(), f2_(); } + + ResultType operator()(Parm1 p1) + { return f1_(p1), f2_(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return f1_(p1, p2), f2_(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return f1_(p1, p2, p3), f2_(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { + return f1_(p1, p2, p3, p4, p5, p6, p7), + f2_(p1, p2, p3, p4, p5, p6, p7); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8), + f2_(p1, p2, p3, p4, p5, p6, p7, p8); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14, p15), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14, p15); + } + + private: + Fun1 f1_; + Fun2 f2_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// function template Chain +// Chains two functor calls one after another +//////////////////////////////////////////////////////////////////////////////// + + + template + Fun2 Chain( + const Fun1& fun1, + const Fun2& fun2) + { + return Fun2(std::auto_ptr( + new Chainer(fun1, fun2))); + } + +} // namespace Loki + +#endif // FUNCTOR_INC_ \ No newline at end of file diff --git a/HierarchyGenerators.h b/HierarchyGenerators.h new file mode 100644 index 0000000..2d06723 --- /dev/null +++ b/HierarchyGenerators.h @@ -0,0 +1,233 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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: February 19, 2001 + +#ifndef HIERARCHYGENERATORS_INC_ +#define HIERARCHYGENERATORS_INC_ + +#include "Typelist.h" +#include "TypeTraits.h" +#include "EmptyType.h" + +namespace Loki +{ +//////////////////////////////////////////////////////////////////////////////// +// class template GenScatterHierarchy +// Generates a scattered hierarchy starting from a typelist and a template +// Invocation (TList is a typelist, Model is a template of one arg): +// GenScatterHierarchy +// The generated class inherits all classes generated by instantiating the +// template 'Model' with the types contained in TList +//////////////////////////////////////////////////////////////////////////////// + + template class Unit> + class GenScatterHierarchy; + + template class Unit> + class GenScatterHierarchy, Unit> + : public GenScatterHierarchy + , public GenScatterHierarchy + { + public: + typedef Typelist TList; + typedef GenScatterHierarchy LeftBase; + typedef GenScatterHierarchy RightBase; + + template struct Rebind + { typedef Unit Result; }; + }; + + template class Unit> + class GenScatterHierarchy : public Unit + { + typedef Unit LeftBase; + + template struct Rebind + { typedef Unit Result; }; + }; + + template