├── .gitignore ├── AbstractFactory.h ├── AssocVector.h ├── Borland ├── AbstractFactory.h ├── AssocVector.h ├── EmptyType.h ├── Factory.h ├── Functor.h ├── HierarchyGenerators.h ├── LokiTypeInfo.h ├── MultiMethods.h ├── NullType.h ├── Singleton.cpp ├── Singleton.h ├── SmallObj.cpp ├── SmallObj.h ├── SmartPtr.h ├── Threads.h ├── Tuple.h ├── TypeManip.h ├── TypeTraits.h ├── Typelist.h ├── Visitor.h ├── readme.txt └── static_check.h ├── DataGenerators.h ├── EmptyType.h ├── Factory.h ├── Functor.h ├── HierarchyGenerators.h ├── LokiTypeInfo.h ├── MSVC ├── 1200 │ ├── AbstractFactory.h │ ├── AssocVector.h │ ├── DataGenerators.h │ ├── EmptyType.h │ ├── Factory.h │ ├── Functor.h │ ├── FunctorOld.h │ ├── HierarchyGenerators.h │ ├── LokiTypeInfo.h │ ├── MSVC6Helpers.h │ ├── MultiMethods.h │ ├── NullType.h │ ├── Readme.txt │ ├── Singleton.cpp │ ├── Singleton.h │ ├── SmallObj.cpp │ ├── SmallObj.h │ ├── SmartPtr.h │ ├── Threads.h │ ├── Tuple.h │ ├── TypeManip.h │ ├── TypeTraits.h │ ├── Typelist.h │ ├── Visitor.h │ ├── VisitorOld.h │ └── static_check.h └── 1300 │ ├── AbstractFactory.h │ ├── AssocVector.h │ ├── DataGenerators.h │ ├── EmptyType.h │ ├── Factory.h │ ├── Functor.h │ ├── HierarchyGenerators.h │ ├── LokiTypeInfo.h │ ├── MinMax.h │ ├── MultiMethods.h │ ├── NullType.h │ ├── Singleton.cpp │ ├── Singleton.h │ ├── SmallObj.cpp │ ├── SmallObj.h │ ├── SmartPtr.h │ ├── Threads.h │ ├── TypeManip.h │ ├── TypeTraits.h │ ├── Typelist.h │ ├── VC_Alignment.h │ ├── Variant.h │ ├── Visitor.h │ ├── portby.txt │ ├── readme.txt │ └── static_check.h ├── MultiMethods.h ├── NullType.h ├── README.md ├── Reference ├── AbstractFactory.h ├── AssocVector.h ├── DataGenerators.h ├── EmptyType.h ├── Factory.h ├── Functor.h ├── HierarchyGenerators.h ├── LokiTypeInfo.h ├── MultiMethods.h ├── NullType.h ├── Singleton.cpp ├── Singleton.h ├── SmallObj.cpp ├── SmallObj.h ├── SmartPtr.h ├── Threads.h ├── Tuple.h ├── TypeManip.h ├── TypeTraits.h ├── Typelist.h ├── Visitor.h ├── readme.txt └── static_check.h ├── Singleton.cpp ├── Singleton.h ├── SmallObj.cpp ├── SmallObj.h ├── SmartPtr.h ├── Threads.h ├── Tuple.h ├── TypeManip.h ├── TypeTraits.h ├── Typelist.h ├── Visitor.h ├── readme.txt ├── static_check.h └── tools ├── HeaderGen ├── HeaderGen.cpp ├── HeaderGen.sln ├── HeaderGen.vcproj ├── Headers.lst ├── readme.txt └── vendors.lst └── RegressionTest ├── AbstractFactoryTest.h ├── AssocVectorTest.h ├── DataGeneratorsTest.h ├── FactoryTest.h ├── FunctorTest.h ├── MSVCUnitTest.sln ├── MSVCUnitTest.vcproj ├── SingletonTest.h ├── SmallObjectTest.h ├── SmartPtrTest.h ├── Test.cpp ├── TypeManipTest.h ├── TypeTraitsTest.h ├── TypelistTest.h └── UnitTest.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | 9 | # Compiled Static libraries 10 | *.lai 11 | *.la 12 | *.a 13 | -------------------------------------------------------------------------------- /AbstractFactory.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////// 2 | // Generated header: AbstractFactory.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | /////////////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/AbstractFactory.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/AbstractFactory.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/AbstractFactory.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/AbstractFactory.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/AbstractFactory.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/AbstractFactory.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/AbstractFactory.h" 23 | # else 24 | # include "Reference/AbstractFactory.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /AssocVector.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////// 2 | // Generated header: AssocVector.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | /////////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/AssocVector.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/AssocVector.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/AssocVector.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/AssocVector.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/AssocVector.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/AssocVector.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/AssocVector.h" 23 | # else 24 | # include "Reference/AssocVector.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /Borland/AbstractFactory.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/AbstractFactory.h -------------------------------------------------------------------------------- /Borland/AssocVector.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/AssocVector.h -------------------------------------------------------------------------------- /Borland/EmptyType.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/EmptyType.h -------------------------------------------------------------------------------- /Borland/Factory.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/Factory.h -------------------------------------------------------------------------------- /Borland/Functor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/Functor.h -------------------------------------------------------------------------------- /Borland/HierarchyGenerators.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/HierarchyGenerators.h -------------------------------------------------------------------------------- /Borland/LokiTypeInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/LokiTypeInfo.h -------------------------------------------------------------------------------- /Borland/NullType.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/NullType.h -------------------------------------------------------------------------------- /Borland/Singleton.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/Singleton.cpp -------------------------------------------------------------------------------- /Borland/Singleton.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/Singleton.h -------------------------------------------------------------------------------- /Borland/SmallObj.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/SmallObj.cpp -------------------------------------------------------------------------------- /Borland/SmallObj.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/SmallObj.h -------------------------------------------------------------------------------- /Borland/SmartPtr.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/SmartPtr.h -------------------------------------------------------------------------------- /Borland/Threads.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/Threads.h -------------------------------------------------------------------------------- /Borland/Tuple.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: August 9, 2002 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // This file is intentionally left empty 20 | // Due to compiler limitations, its contents has been moved to 21 | // HierarchyGenerators.h 22 | //////////////////////////////////////////////////////////////////////////////// 23 | 24 | -------------------------------------------------------------------------------- /Borland/TypeManip.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/TypeManip.h -------------------------------------------------------------------------------- /Borland/TypeTraits.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/TypeTraits.h -------------------------------------------------------------------------------- /Borland/Typelist.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/Typelist.h -------------------------------------------------------------------------------- /Borland/Visitor.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: August 9, 2002 17 | 18 | #ifndef VISITOR_INC_ 19 | #define VISITOR_INC_ 20 | 21 | #include "Typelist.h" 22 | 23 | namespace Loki 24 | { 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // class template BaseVisitor 28 | // The base class of any Acyclic Visitor 29 | //////////////////////////////////////////////////////////////////////////////// 30 | 31 | class BaseVisitor 32 | { 33 | public: 34 | virtual ~BaseVisitor() {} 35 | }; 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // class template Visitor 39 | // The building block of Acyclic Visitor 40 | //////////////////////////////////////////////////////////////////////////////// 41 | 42 | template 43 | class Visitor 44 | { 45 | public: 46 | typedef R ReturnType; 47 | virtual ReturnType Visit(T&) = 0; 48 | }; 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // class template Visitor (specialization) 52 | // This specialization is not present in the book. It makes it easier to define 53 | // Visitors for multiple types in a shot by using a typelist. Example: 54 | // 55 | // class SomeVisitor : 56 | // public BaseVisitor // required 57 | // public Visitor, 58 | // public Visitor 59 | // { 60 | // public: 61 | // void Visit(RasterBitmap&); // visit a RasterBitmap 62 | // void Visit(Paragraph &); // visit a Paragraph 63 | // }; 64 | //////////////////////////////////////////////////////////////////////////////// 65 | 66 | template 67 | class Visitor, R> 68 | : public Visitor, public Visitor 69 | { 70 | public: 71 | typedef R ReturnType; 72 | // using Visitor::Visit; 73 | // using Visitor::Visit; 74 | }; 75 | 76 | template 77 | class Visitor, R> : public Visitor 78 | { 79 | public: 80 | typedef R ReturnType; 81 | using Visitor::Visit; 82 | }; 83 | 84 | //////////////////////////////////////////////////////////////////////////////// 85 | // class template BaseVisitorImpl 86 | // Implements non-strict visitation (you can implement only part of the Visit 87 | // functions) 88 | //////////////////////////////////////////////////////////////////////////////// 89 | 90 | template class BaseVisitorImpl; 91 | 92 | template 93 | class BaseVisitorImpl, R> 94 | : public Visitor 95 | , public BaseVisitorImpl 96 | { 97 | public: 98 | // using BaseVisitorImpl::Visit; 99 | 100 | virtual R Visit(Head&) 101 | { return R(); } 102 | }; 103 | 104 | template 105 | class BaseVisitorImpl, R> 106 | : public Visitor 107 | { 108 | public: 109 | virtual R Visit(Head&) 110 | { return R(); } 111 | }; 112 | 113 | //////////////////////////////////////////////////////////////////////////////// 114 | // class template BaseVisitable 115 | //////////////////////////////////////////////////////////////////////////////// 116 | 117 | template 118 | struct DefaultCatchAll 119 | { 120 | static R OnUnknownVisitor(Visited&, BaseVisitor&) 121 | { return R(); } 122 | }; 123 | 124 | //////////////////////////////////////////////////////////////////////////////// 125 | // class template BaseVisitable 126 | //////////////////////////////////////////////////////////////////////////////// 127 | 128 | template 129 | < 130 | typename R = void, 131 | template class CatchAll = DefaultCatchAll 132 | > 133 | class BaseVisitable 134 | { 135 | public: 136 | typedef R ReturnType; 137 | virtual ~BaseVisitable() {} 138 | virtual ReturnType Accept(BaseVisitor&) = 0; 139 | 140 | protected: // give access only to the hierarchy 141 | template 142 | static ReturnType AcceptImpl(T& visited, BaseVisitor& guest) 143 | { 144 | // Apply the Acyclic Visitor 145 | if (Visitor* p = dynamic_cast*>(&guest)) 146 | { 147 | return p->Visit(visited); 148 | } 149 | return CatchAll::OnUnknownVisitor(visited, guest); 150 | } 151 | }; 152 | 153 | //////////////////////////////////////////////////////////////////////////////// 154 | // macro DEFINE_VISITABLE 155 | // Put it in every class that you want to make visitable (in addition to 156 | // deriving it from BaseVisitable 157 | //////////////////////////////////////////////////////////////////////////////// 158 | 159 | //### BCB port - added Loki:: prefix 160 | #define DEFINE_VISITABLE() \ 161 | virtual ReturnType Accept(Loki::BaseVisitor& guest) \ 162 | { return AcceptImpl(*this, guest); } 163 | 164 | //////////////////////////////////////////////////////////////////////////////// 165 | // class template CyclicVisitor 166 | // Put it in every class that you want to make visitable (in addition to 167 | // deriving it from BaseVisitable 168 | //////////////////////////////////////////////////////////////////////////////// 169 | 170 | template 171 | class CyclicVisitor : public Visitor 172 | { 173 | public: 174 | typedef R ReturnType; 175 | // using Visitor::Visit; 176 | 177 | template 178 | ReturnType GenericVisit(Visited& host) 179 | { 180 | Visitor& subObj = *this; 181 | return subObj.Visit(host); 182 | } 183 | }; 184 | 185 | //////////////////////////////////////////////////////////////////////////////// 186 | // macro DEFINE_CYCLIC_VISITABLE 187 | // Put it in every class that you want to make visitable by a cyclic visitor 188 | //////////////////////////////////////////////////////////////////////////////// 189 | 190 | #define DEFINE_CYCLIC_VISITABLE(SomeVisitor) \ 191 | virtual SomeVisitor::ReturnType Accept(SomeVisitor& guest) \ 192 | { return guest.GenericVisit(*this); } 193 | 194 | } // namespace Loki 195 | 196 | //////////////////////////////////////////////////////////////////////////////// 197 | // Change log: 198 | // March 20: add default argument DefaultCatchAll to BaseVisitable 199 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 200 | //////////////////////////////////////////////////////////////////////////////// 201 | 202 | #endif // VISITOR_INC_ 203 | 204 | -------------------------------------------------------------------------------- /Borland/readme.txt: -------------------------------------------------------------------------------- 1 | Last update: August 9, 2002 2 | 3 | Directions: 4 | 5 | To use Loki, simply extract the files from the archive, give your compiler access to their path, and include them appropriately in your code via #include. 6 | 7 | If you use the small object allocator directly or indirectly (through the Functor class) you must add SmallObj.cpp to your project/makefile. 8 | 9 | If you use Singletons with longevity you must add Singleton.cpp to your project/makefile. 10 | 11 | Compatibility: 12 | 13 | Loki has been tested with Metrowerks CodeWarrior Pro 6 under Windows. CodeWarrior has a problem with the Conversion template (see TypeManip.h) and, though it compiles it, it doesn't provide correct results. Consequently, the DerivedToFront algorithm in Typelist.h does not function. This affects the static dispatcher in Multimethods.h. As a fix, you must order the types (putting the most derived ones in the front) when providing the typelist argument to StaticDispatcher. 14 | 15 | Also, Loki has been ported to g++ 2.95.3 by Nick Thurn. 16 | 17 | 18 | This is a ported version of Loki to Borland C++ Builder 6.0. However, it uses standard C++, so it should work on the other compilers, as well. 19 | 20 | More info: 21 | 22 | http://moderncppdesign.com 23 | -------------------------------------------------------------------------------- /Borland/static_check.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/Borland/static_check.h -------------------------------------------------------------------------------- /DataGenerators.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////// 2 | // Generated header: DataGenerators.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | ////////////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/DataGenerators.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/DataGenerators.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/DataGenerators.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/DataGenerators.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/DataGenerators.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/DataGenerators.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/DataGenerators.h" 23 | # else 24 | # include "Reference/DataGenerators.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /EmptyType.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////// 2 | // Generated header: EmptyType.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | ///////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/EmptyType.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/EmptyType.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/EmptyType.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/EmptyType.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/EmptyType.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/EmptyType.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/EmptyType.h" 23 | # else 24 | # include "Reference/EmptyType.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /Factory.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////// 2 | // Generated header: Factory.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | /////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/Factory.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/Factory.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/Factory.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/Factory.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/Factory.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/Factory.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/Factory.h" 23 | # else 24 | # include "Reference/Factory.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /Functor.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////// 2 | // Generated header: Functor.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | /////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/Functor.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/Functor.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/Functor.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/Functor.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/Functor.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/Functor.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/Functor.h" 23 | # else 24 | # include "Reference/Functor.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /HierarchyGenerators.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////// 2 | // Generated header: HierarchyGenerators.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | /////////////////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/HierarchyGenerators.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/HierarchyGenerators.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/HierarchyGenerators.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/HierarchyGenerators.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/HierarchyGenerators.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/HierarchyGenerators.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/HierarchyGenerators.h" 23 | # else 24 | # include "Reference/HierarchyGenerators.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /LokiTypeInfo.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////// 2 | // Generated header: TypeInfo.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | //////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/LokiTypeInfo.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/LokiTypeInfo.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/LokiTypeInfo.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/LokiTypeInfo.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/LokiTypeInfo.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/LokiTypeInfo.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/LokiTypeInfo.h" 23 | # else 24 | # include "Reference/LokiTypeInfo.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /MSVC/1200/AbstractFactory.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: Feb 20, 2003 17 | // replaced pointer-dummy parameters with Type2Type-parameters. 18 | // See readme.txt (notes: C) if you don't know why the dummy parameters are needed 19 | // 20 | // replaced all template template parameters with 'normal' parameters 21 | // For each Factory-Unit there is now a wrapper-class (non template class) 22 | // containing a nested template class called In which 23 | // provides a typedef (type) to the real unit-class. 24 | // Use one of the wrapper-classes to instantiate a factory. 25 | // 26 | // Covariant return types had to go, too. 27 | 28 | #ifndef ABSTRACTFACTORY_INC_ 29 | #define ABSTRACTFACTORY_INC_ 30 | 31 | #include "Typelist.h" 32 | #include "TypeManip.h" 33 | #include "HierarchyGenerators.h" 34 | #include "MSVC6Helpers.h" 35 | 36 | #include 37 | 38 | #define ETAS_HELPER(Type) (::Loki::Type2Type()) 39 | 40 | namespace Loki 41 | { 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // class template AbstractFactoryUnit 45 | // The building block of an Abstract Factory 46 | //////////////////////////////////////////////////////////////////////////////// 47 | 48 | template 49 | class AbstractFactoryUnit 50 | { 51 | public: 52 | virtual T* DoCreate(Type2Type) = 0; 53 | virtual ~AbstractFactoryUnit() {} 54 | }; 55 | 56 | // Wrapper for AbstractFactoryUnit. 57 | struct AbstractFactoryUnitWrapper 58 | { 59 | template 60 | struct In 61 | { 62 | typedef AbstractFactoryUnit type; 63 | }; 64 | }; 65 | //////////////////////////////////////////////////////////////////////////////// 66 | // class template AbstractFactory 67 | // Defines an Abstract Factory interface starting from a typelist 68 | //////////////////////////////////////////////////////////////////////////////// 69 | // VC 6.0 changes: 70 | // Because the VC 6.0 does not support explicit template argument specification (14.8.1) 71 | // the member-function Create takes a dummy argument of type Type2Type whose sole 72 | // responsibility is to help the compiler in deducing the type of T. 73 | // Using this port the call: 74 | // ConcProduct* p = aFactory.Create(); 75 | // therefore becomes: 76 | // ConcProduct* p = aFactory.Create(Type2Type()); 77 | 78 | template 79 | < 80 | class TList, 81 | class Unit = AbstractFactoryUnitWrapper 82 | > 83 | class AbstractFactory : public GenScatterHierarchy 84 | { 85 | public: 86 | typedef TList ProductList; 87 | 88 | template T* Create(Type2Type) 89 | { 90 | ApplyInnerType::type& unit = *this; 91 | return unit.DoCreate(Type2Type()); 92 | } 93 | }; 94 | 95 | //////////////////////////////////////////////////////////////////////////////// 96 | // class template OpNewFactoryUnit 97 | // Creates an object by invoking the new operator 98 | //////////////////////////////////////////////////////////////////////////////// 99 | 100 | template 101 | class OpNewFactoryUnit : public Base 102 | { 103 | typedef typename Base::ProductList BaseProductList; 104 | 105 | protected: 106 | typedef typename BaseProductList::Tail ProductList; 107 | 108 | public: 109 | typedef typename BaseProductList::Head AbstractProduct; 110 | // VC does not support covariant return types 111 | AbstractProduct* DoCreate(Type2Type) 112 | { 113 | return new ConcreteProduct; 114 | } 115 | }; 116 | 117 | // Wrapper for OpNewFactoryUnit 118 | struct OpNewFactoryUnitWrapper 119 | { 120 | template 121 | struct In 122 | { 123 | typedef OpNewFactoryUnit type; 124 | }; 125 | }; 126 | 127 | //////////////////////////////////////////////////////////////////////////////// 128 | // class template PrototypeFactoryUnit 129 | // Creates an object by cloning a prototype 130 | // There is a difference between the implementation herein and the one described 131 | // in the book: GetPrototype and SetPrototype use the helper friend 132 | // functions DoGetPrototype and DoSetPrototype. The friend functions avoid 133 | // name hiding issues. Plus, GetPrototype takes a reference to pointer 134 | // instead of returning the pointer by value. 135 | //////////////////////////////////////////////////////////////////////////////// 136 | 137 | template 138 | class PrototypeFactoryUnit : public Base 139 | { 140 | typedef typename Base::ProductList BaseProductList; 141 | 142 | protected: 143 | typedef typename BaseProductList::Tail ProductList; 144 | 145 | public: 146 | typedef typename BaseProductList::Head AbstractProduct; 147 | 148 | PrototypeFactoryUnit(AbstractProduct* p = 0) 149 | : pPrototype_(p) 150 | {} 151 | 152 | friend void DoGetPrototype(const PrototypeFactoryUnit& me, 153 | AbstractProduct*& pPrototype) 154 | { pPrototype = me.pPrototype_; } 155 | 156 | friend void DoSetPrototype(PrototypeFactoryUnit& me, 157 | AbstractProduct* pObj) 158 | { me.pPrototype_ = pObj; } 159 | 160 | template 161 | void GetPrototype(U*& p) 162 | { return DoGetPrototype(*this, p); } 163 | 164 | template 165 | void SetPrototype(U* pObj) 166 | { DoSetPrototype(*this, pObj); } 167 | 168 | AbstractProduct* DoCreate(Type2Type) 169 | { 170 | assert(pPrototype_); 171 | // vc does not support covariant return types thus 172 | // Clone *always* returns a base-pointer. 173 | // if DoCreate is called from a ConcreteFactory-object we 174 | // need to down-cast. 175 | // Is the static_cast always safe? 176 | return static_cast(pPrototype_->Clone()); 177 | } 178 | 179 | private: 180 | AbstractProduct* pPrototype_; 181 | }; 182 | 183 | // Wrapper for PrototypeFactoryUnit 184 | struct PrototypeFactoryUnitWrapper 185 | { 186 | template 187 | struct In 188 | { 189 | typedef PrototypeFactoryUnit type; 190 | }; 191 | }; 192 | //////////////////////////////////////////////////////////////////////////////// 193 | // class template ConcreteFactory 194 | // Implements an AbstractFactory interface 195 | //////////////////////////////////////////////////////////////////////////////// 196 | 197 | template 198 | < 199 | class AbstractFact, 200 | class Creator = OpNewFactoryUnit, 201 | class TList = /*VC 6.0 does not like typename here*/ AbstractFact::ProductList 202 | > 203 | class ConcreteFactory 204 | : public GenLinearHierarchy< 205 | typename TL::Reverse::Result, Creator, AbstractFact> 206 | { 207 | public: 208 | typedef typename AbstractFact::ProductList ProductList; 209 | typedef TList ConcreteProductList; 210 | }; 211 | 212 | } // namespace Loki 213 | 214 | //////////////////////////////////////////////////////////////////////////////// 215 | // Change log: 216 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 217 | // Oct 24, 2002: ported by Benjamin Kaufmann to MSVC 6.0 218 | // Feb 20, 2003: replaced pointer-dummy parameters with Type2Type-parameters. B.K. 219 | // September 25, 2004: Fixed bug in PrototypeFactoryUnit::GetPrototype, thanks 220 | // to a bug report submitted by funcall. 221 | //////////////////////////////////////////////////////////////////////////////// 222 | 223 | #endif // ABSTRACTFACTORY_INC_ 224 | -------------------------------------------------------------------------------- /MSVC/1200/DataGenerators.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Data Generator by Shannon Barber 4 | // This code DOES NOT accompany the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // 8 | // Code covered by the MIT License 9 | // The author makes no representations about the suitability of this software 10 | // for any purpose. It is provided "as is" without express or implied warranty. 11 | //////////////////////////////////////////////////////////////////////////////// 12 | 13 | // Last update: Mar 04, 2003 14 | // MSVC 6.0 version 15 | 16 | #ifndef DATAGENERATORS_H 17 | #define DATAGENERATORS_H 18 | #include "Typelist.h" 19 | #include "MSVC6Helpers.h" 20 | namespace Loki 21 | { 22 | namespace TL 23 | { 24 | template 25 | struct nameof_type 26 | { 27 | const char* operator()() 28 | { 29 | return typeid(T).name(); 30 | } 31 | }; 32 | template 33 | struct sizeof_type 34 | { 35 | size_t operator()() 36 | { 37 | return sizeof(T); 38 | } 39 | }; 40 | 41 | // wrappers to workaround the need for template template parameters 42 | struct nameof_type_wrapper 43 | { 44 | template 45 | struct In 46 | { 47 | typedef nameof_type type; 48 | }; 49 | }; 50 | 51 | struct sizeof_type_wrapper 52 | { 53 | template 54 | struct In 55 | { 56 | typedef sizeof_type type; 57 | }; 58 | 59 | }; 60 | template 61 | struct IterateTypes; 62 | namespace Private 63 | { 64 | // Specialization for a general typelist 65 | template 66 | struct IterateTypesImpl 67 | { 68 | template 69 | struct In 70 | { 71 | typedef typename TList::Head T1; 72 | typedef typename TList::Tail T2; 73 | 74 | typedef IterateTypes head_t; 75 | head_t head; 76 | typedef IterateTypes tail_t; 77 | tail_t tail; 78 | 79 | template 80 | void operator()(II ii) 81 | { 82 | head.operator()(ii); 83 | tail.operator()(ii); 84 | } 85 | protected: 86 | ~In() {} 87 | }; 88 | }; 89 | 90 | // Specialization for a single type 91 | template <> 92 | struct IterateTypesImpl 93 | { 94 | template 95 | struct In 96 | { 97 | template 98 | void operator()(II ii) 99 | { 100 | typedef typename Loki::ApplyInnerType::type gFunc; 101 | gFunc genfunc; 102 | *ii = genfunc(); 103 | ++ii; //Is this even needed? 104 | } 105 | protected: 106 | ~In() {} 107 | }; 108 | }; 109 | 110 | // Specialization for NullType 111 | template <> 112 | struct IterateTypesImpl 113 | { 114 | template 115 | struct In 116 | { 117 | template 118 | void operator()(II ii) 119 | {} 120 | protected: 121 | ~In() {} 122 | }; 123 | }; 124 | } // end ns Private 125 | 126 | template 127 | struct IterateTypes : public 128 | Private::IterateTypesImpl 129 | < 130 | TL::Private::IsTypelist::type_id 131 | >::template In 132 | {}; 133 | 134 | template 135 | void iterate_types(II ii) 136 | { 137 | Loki::TL::IterateTypes it; 138 | it(ii); 139 | } 140 | }//ns TL 141 | }//ns Loki 142 | 143 | #endif //DATAGENERATORS_H 144 | //////////////////////////////////////////////////////////////////////////////// 145 | // Change log: 146 | // 9/20/02 Named changed from GenData to IterateTypes 147 | // 10/8/02 insertion iterators are passed-by-value, not by-reference (oops) 148 | // 03/04/03 ported by Benjamin Kaufmann to MSVC 6.0 149 | // 03/06/03 added protected destructors to private implementation classes B.K. 150 | //////////////////////////////////////////////////////////////////////////////// 151 | -------------------------------------------------------------------------------- /MSVC/1200/EmptyType.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef EMPTYTYPE_INC_ 19 | #define EMPTYTYPE_INC_ 20 | 21 | namespace Loki 22 | { 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // class EmptyType 25 | // Used as a class type that doesn't hold anything 26 | // Useful as a strawman class 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | class EmptyType {}; 30 | } 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | // Change log: 34 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 35 | //////////////////////////////////////////////////////////////////////////////// 36 | 37 | #endif // EMPTYTYPE_INC_ 38 | -------------------------------------------------------------------------------- /MSVC/1200/Factory.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // Last update: Feb 22, 2003 17 | // 18 | // 19 | // The default error policy is no longer a template-class 20 | 21 | #ifndef FACTORY_INC_ 22 | #define FACTORY_INC_ 23 | 24 | #include "LokiTypeInfo.h" 25 | #include "AssocVector.h" 26 | #include 27 | 28 | namespace Loki 29 | { 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | // class template DefaultFactoryError 33 | // Manages the "Unknown Type" error in an object factory 34 | //////////////////////////////////////////////////////////////////////////////// 35 | 36 | struct DefaultFactoryError 37 | { 38 | struct Exception : public std::exception 39 | { 40 | const char* what() const throw() { return "Unknown Type"; } 41 | }; 42 | 43 | template 44 | static AbstractProduct* OnUnknownType(IdentifierType s,Type2Type) 45 | { 46 | throw Exception(); 47 | return (AbstractProduct*) 0; 48 | } 49 | }; 50 | 51 | //////////////////////////////////////////////////////////////////////////////// 52 | // class template Factory 53 | // Implements a generic object factory 54 | //////////////////////////////////////////////////////////////////////////////// 55 | 56 | template 57 | < 58 | class AbstractProduct, 59 | typename IdentifierType, 60 | typename ProductCreator = AbstractProduct* (*)(), 61 | class FactoryErrorPolicy = DefaultFactoryError 62 | > 63 | class Factory 64 | : public FactoryErrorPolicy 65 | { 66 | public: 67 | bool Register(const IdentifierType& id, ProductCreator creator) 68 | { 69 | return associations_.insert( 70 | IdToProductMap::value_type(id, creator)).second; 71 | } 72 | 73 | bool Unregister(const IdentifierType& id) 74 | { 75 | return associations_.erase(id) == 1; 76 | } 77 | 78 | AbstractProduct* CreateObject(const IdentifierType& id) 79 | { 80 | typename IdToProductMap::iterator i = associations_.find(id); 81 | if (i != associations_.end()) 82 | { 83 | return (i->second)(); 84 | } 85 | return OnUnknownType(id, Type2Type()); 86 | } 87 | 88 | private: 89 | typedef AssocVector IdToProductMap; 90 | IdToProductMap associations_; 91 | }; 92 | 93 | //////////////////////////////////////////////////////////////////////////////// 94 | // class template CloneFactory 95 | // Implements a generic cloning factory 96 | //////////////////////////////////////////////////////////////////////////////// 97 | 98 | template 99 | < 100 | class AbstractProduct, 101 | class ProductCreator = 102 | AbstractProduct* (*)(const AbstractProduct*), 103 | 104 | class FactoryErrorPolicy = DefaultFactoryError 105 | > 106 | class CloneFactory 107 | : public FactoryErrorPolicy 108 | { 109 | public: 110 | bool Register(const TypeInfo& ti, ProductCreator creator) 111 | { 112 | return associations_.insert( 113 | IdToProductMap::value_type(ti, creator)).second; 114 | } 115 | 116 | bool Unregister(const TypeInfo& id) 117 | { 118 | return associations_.erase(id) == 1; 119 | } 120 | 121 | AbstractProduct* CreateObject(const AbstractProduct* model) 122 | { 123 | if (model == 0) return 0; 124 | 125 | typename IdToProductMap::iterator i = 126 | associations_.find(typeid(*model)); 127 | if (i != associations_.end()) 128 | { 129 | return (i->second)(model); 130 | } 131 | return OnUnknownType(TypeInfo(typeid(*model)),Type2Type()); 132 | } 133 | 134 | private: 135 | typedef AssocVector IdToProductMap; 136 | IdToProductMap associations_; 137 | }; 138 | } // namespace Loki 139 | 140 | //////////////////////////////////////////////////////////////////////////////// 141 | // Change log: 142 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 143 | // May 08, 2002: replaced const_iterator with iterator so that self-modifying 144 | // ProductCreators are supported. Also, added a throw() spec to what(). 145 | // Credit due to Jason Fischl. 146 | // Oct 24, 2002: ported to MSVC 6 by Benjamin Kaufmann. 147 | // Note: The default error policy is no longer a template-class. 148 | // Feb 22, 2003: Added missing parameter to OnUnknownType B.K. 149 | //////////////////////////////////////////////////////////////////////////////// 150 | 151 | #endif // FACTORY_INC_ 152 | -------------------------------------------------------------------------------- /MSVC/1200/LokiTypeInfo.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef LOKITYPEINFO_INC_ 19 | #define LOKITYPEINFO_INC_ 20 | 21 | #include 22 | #include 23 | #include "Typelist.h" 24 | 25 | namespace Loki 26 | { 27 | //////////////////////////////////////////////////////////////////////////////// 28 | // class TypeInfo 29 | // Purpose: offer a first-class, comparable wrapper over std::type_info 30 | //////////////////////////////////////////////////////////////////////////////// 31 | 32 | class TypeInfo 33 | { 34 | public: 35 | // Constructors 36 | TypeInfo(); // needed for containers 37 | TypeInfo(const std::type_info&); // non-explicit 38 | 39 | // Access for the wrapped std::type_info 40 | const std::type_info& Get() const; 41 | // Compatibility functions 42 | bool before(const TypeInfo& rhs) const; 43 | const char* name() const; 44 | 45 | private: 46 | const std::type_info* pInfo_; 47 | }; 48 | 49 | // Implementation 50 | 51 | inline TypeInfo::TypeInfo() 52 | { 53 | class Nil {}; 54 | pInfo_ = &typeid(Nil); 55 | assert(pInfo_); 56 | } 57 | 58 | inline TypeInfo::TypeInfo(const std::type_info& ti) 59 | : pInfo_(&ti) 60 | { assert(pInfo_); } 61 | 62 | inline bool TypeInfo::before(const TypeInfo& rhs) const 63 | { 64 | assert(pInfo_); 65 | return pInfo_->before(*rhs.pInfo_) != 0; 66 | } 67 | 68 | inline const std::type_info& TypeInfo::Get() const 69 | { 70 | assert(pInfo_); 71 | return *pInfo_; 72 | } 73 | 74 | inline const char* TypeInfo::name() const 75 | { 76 | assert(pInfo_); 77 | return pInfo_->name(); 78 | } 79 | 80 | // Comparison operators 81 | 82 | inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs) 83 | { return (lhs.Get() == rhs.Get()) != 0; } 84 | 85 | inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs) 86 | { return lhs.before(rhs); } 87 | 88 | inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs) 89 | { return !(lhs == rhs); } 90 | 91 | inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs) 92 | { return rhs < lhs; } 93 | 94 | inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs) 95 | { return !(lhs > rhs); } 96 | 97 | inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs) 98 | { return !(lhs < rhs); } 99 | } 100 | 101 | //////////////////////////////////////////////////////////////////////////////// 102 | // Change log: 103 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 104 | //////////////////////////////////////////////////////////////////////////////// 105 | 106 | #endif // LOKITYPEINFO_INC_ 107 | -------------------------------------------------------------------------------- /MSVC/1200/MSVC6Helpers.h: -------------------------------------------------------------------------------- 1 | // Last update: Mar 06, 2003 2 | // Added VoidWrap 3 | // Added qualification ::Loki::Private:: to types from the Private-Namespace 4 | // Thanks to Adi Shavit 5 | 6 | #ifndef MSVC6HELPERS__H 7 | #define MSVC6HELPERS__H 8 | #if !defined (_MSC_VER) || _MSC_VER >= 1300 9 | #error "please use this header only with MSVC 6.0" 10 | #endif 11 | #include "TypeManip.h" 12 | namespace Loki 13 | { 14 | namespace Private 15 | { 16 | template 17 | struct VC_InaccessibleBase : public T 18 | {}; 19 | 20 | // workaround for the "Error C2516. : is not a legal base class" 21 | // Use VC_Base_Workaround's LeftBase instead of the 22 | // alleged illegal base class. 23 | template 24 | struct VC_Base_Workaround : public T, public U 25 | { 26 | typedef T LeftBase; 27 | }; 28 | 29 | // MSVC 6.0 does not allow the return of 30 | // expressions of type "cv void" in a functions with a return 31 | // type of cv void (6.6.3). 32 | // Functor.h uses this Type as a workaround. 33 | struct VoidAsType {}; 34 | 35 | // workaround for error C2182: '__formal' illegal use of type 'void' 36 | // when trying to use void as default value of a template parameter. 37 | // Instead of template class bla {}; 38 | // simply write template class bla {}; 39 | // and the VC 6.0 will be happy. 40 | struct VoidWrap 41 | { 42 | typedef void type; 43 | }; 44 | // workarounds for template template parameters 45 | //////////////////////////////////////////////////////////////////////////////// 46 | // class template AlwaysFalse 47 | // Invocation: AlwaysFalse::value 48 | // value will always by 0 (false) 49 | //////////////////////////////////////////////////////////////////////////////// 50 | template< typename T > 51 | struct AlwaysFalse 52 | { 53 | enum { value = false }; 54 | }; 55 | 56 | //////////////////////////////////////////////////////////////////////////////// 57 | // class template ApplyImpl1 58 | // Invocation: ApplyImpl1::template Result 59 | // T must be a nontemplate type with a nested class template named In. 60 | // The class template is a helper for the Apply1-Template 61 | //////////////////////////////////////////////////////////////////////////////// 62 | template 63 | struct ApplyImpl1 64 | { 65 | template 66 | struct VC_WORKAROUND : public TypeWithNestedTemplate {}; 67 | 68 | struct VC_WORKAROUND 69 | { template struct In; }; 70 | 71 | template< typename T1 > struct Result : public 72 | VC_WORKAROUND< ::Loki::Private::AlwaysFalse::value >::template In 73 | { 74 | typedef VC_WORKAROUND< ::Loki::Private::AlwaysFalse::value >::template In Base; 75 | 76 | }; 77 | }; 78 | //////////////////////////////////////////////////////////////////////////////// 79 | // class template ApplyImpl2 80 | // Invocation: ApplyImpl2::template Result 81 | // T must be a nontemplate type with a nested class template named In. 82 | // The class template is a helper for the Apply2-Template 83 | //////////////////////////////////////////////////////////////////////////////// 84 | template 85 | struct ApplyImpl2 86 | { 87 | template 88 | struct VC_WORKAROUND : public TypeWithNestedTemplate {}; 89 | 90 | struct VC_WORKAROUND 91 | {template struct In; }; 92 | 93 | template< typename T1, typename T2 > struct Result : public 94 | VC_WORKAROUND< ::Loki::Private::AlwaysFalse::value >::template In 95 | { 96 | }; 97 | }; 98 | 99 | } // end of namespace Private 100 | 101 | 102 | //////////////////////////////////////////////////////////////////////////////// 103 | // class template Apply1 104 | // Invocation: Apply1 105 | // Applies the type U to the inner template In of type T 106 | // The class template Apply1 helps to emulate template template parameters 107 | // i first saw this technique in boost's mpl library. 108 | //////////////////////////////////////////////////////////////////////////////// 109 | template 110 | struct Apply1 : ::Loki::Private::ApplyImpl1::template Result 111 | { 112 | typedef typename ::Loki::Private::ApplyImpl1::template Result::Base Base; 113 | }; 114 | //////////////////////////////////////////////////////////////////////////////// 115 | // class template Apply2 116 | // Invocation: Apply2 117 | // Applies the types U and V to the inner template In of type T 118 | // The class template Apply2 helps to emulate template template parameters 119 | // i first saw this technique in boost's mpl library. 120 | //////////////////////////////////////////////////////////////////////////////// 121 | template 122 | struct Apply2 : ::Loki::Private::ApplyImpl2::template Result 123 | { 124 | 125 | }; 126 | 127 | //////////////////////////////////////////////////////////////////////////////// 128 | // class template ApplyInnerType 129 | // Invocation: ApplyInnerType::type 130 | // Applies the type U to the the inner template 'In' of type Wrapper and typedefs 131 | // the resulting type to 'type' 132 | // The class template ApplyInnerType helps to emulate template template parameters 133 | // i first saw this technique in boost's mpl library. 134 | //////////////////////////////////////////////////////////////////////////////// 135 | template 136 | struct ApplyInnerType 137 | { 138 | template struct Wrapper_VC : Wrapper {}; 139 | 140 | template<> struct Wrapper_VC 141 | { template struct In; }; 142 | typedef typename 143 | Wrapper_VC< ::Loki::Private::AlwaysFalse::value>::template In::type type; 144 | }; 145 | //////////////////////////////////////////////////////////////////////////////// 146 | // class template ApplyInnerType2 147 | // Invocation: ApplyInnerType2::type 148 | // Applies the types U and V to the the inner template 'In' of type Wrapper and typedefs 149 | // the resulting type to 'type' 150 | // The class template ApplyInnerType helps to emulate template template parameters 151 | // i first saw this technique in boost's mpl library. 152 | //////////////////////////////////////////////////////////////////////////////// 153 | template 154 | struct ApplyInnerType2 155 | { 156 | template struct Wrapper_VC : Wrapper {}; 157 | 158 | template<> struct Wrapper_VC 159 | { template struct In; }; 160 | typedef typename 161 | Wrapper_VC< ::Loki::Private::AlwaysFalse::value>::template In::type type; 162 | }; 163 | 164 | template 165 | struct ApplyInnerType4 166 | { 167 | template struct Wrapper_VC : Wrapper {}; 168 | 169 | template<> struct Wrapper_VC 170 | { template struct In; }; 171 | typedef typename 172 | Wrapper_VC< ::Loki::Private::AlwaysFalse::value>::template In::type type; 173 | }; 174 | 175 | 176 | } 177 | #endif -------------------------------------------------------------------------------- /MSVC/1200/NullType.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef NULLTYPE_INC_ 19 | #define NULLTYPE_INC_ 20 | 21 | namespace Loki 22 | { 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // class NullType 25 | // Used as a placeholder for "no type here" 26 | // Useful as an end marker in typelists 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | class NullType {}; 30 | } 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | // Change log: 34 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 35 | //////////////////////////////////////////////////////////////////////////////// 36 | 37 | #endif // NULLTYPE_INC_ 38 | -------------------------------------------------------------------------------- /MSVC/1200/Readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/MSVC/1200/Readme.txt -------------------------------------------------------------------------------- /MSVC/1200/Singleton.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: Oct 06, 2002 17 | 18 | #include "Singleton.h" 19 | 20 | using namespace Loki::Private; 21 | 22 | Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0; 23 | unsigned int Loki::Private::elements = 0; 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // function AtExitFn 28 | // Ensures proper destruction of objects with longevity 29 | //////////////////////////////////////////////////////////////////////////////// 30 | 31 | void Loki::Private::AtExitFn() 32 | { 33 | assert(elements > 0 && pTrackerArray != 0); 34 | // Pick the element at the top of the stack 35 | LifetimeTracker* pTop = pTrackerArray[elements - 1]; 36 | // Remove that object off the stack 37 | // Don't check errors - realloc with less memory 38 | // can't fail 39 | pTrackerArray = static_cast(VC_BROKEN_STD::realloc( 40 | pTrackerArray, sizeof(*pTrackerArray) * --elements)); 41 | // Destroy the element 42 | delete pTop; 43 | } 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | // Change log: 47 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 48 | // Oct 06 2002: ported by Benjamin Kaufmann to VC 6.0 49 | //////////////////////////////////////////////////////////////////////////////// 50 | -------------------------------------------------------------------------------- /MSVC/1200/SmallObj.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: Jan 12, 2003 17 | // changed SmallObject's op new from 18 | // static void* operator new(VC_BROKEN_STD::size_t size); 19 | // to 20 | // static void* operator new(VC_BROKEN_STD::size_t size, 21 | // VC_BROKEN_STD::size_t dummy = 0); 22 | // and removed the ugly #pragma warning(disable:4291)" 23 | // Thanks to M.Yamada for the hint 24 | 25 | #ifndef SMALLOBJ_INC_ 26 | #define SMALLOBJ_INC_ 27 | 28 | #include "Threads.h" 29 | #include "Singleton.h" 30 | #include "MSVC6Helpers.h" // for apply-template 31 | #include 32 | #include 33 | 34 | #ifndef DEFAULT_CHUNK_SIZE 35 | #define DEFAULT_CHUNK_SIZE 4096 36 | #endif 37 | 38 | #ifndef MAX_SMALL_OBJECT_SIZE 39 | #define MAX_SMALL_OBJECT_SIZE 64 40 | #endif 41 | 42 | namespace Loki 43 | { 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // class FixedAllocator 46 | // Offers services for allocating fixed-sized objects 47 | //////////////////////////////////////////////////////////////////////////////// 48 | 49 | class FixedAllocator 50 | { 51 | public: // VC7 access control BUG 52 | class Chunk 53 | { 54 | friend FixedAllocator; 55 | 56 | void Init(VC_BROKEN_STD::size_t blockSize, unsigned char blocks); 57 | void* Allocate(VC_BROKEN_STD::size_t blockSize); 58 | void Deallocate(void* p, VC_BROKEN_STD::size_t blockSize); 59 | void Reset(VC_BROKEN_STD::size_t blockSize, unsigned char blocks); 60 | void Release(); 61 | unsigned char* pData_; 62 | unsigned char 63 | firstAvailableBlock_, 64 | blocksAvailable_; 65 | }; 66 | 67 | private: 68 | // Internal functions 69 | void DoDeallocate(void* p); 70 | Chunk* VicinityFind(void* p); 71 | 72 | // Data 73 | VC_BROKEN_STD::size_t blockSize_; 74 | unsigned char numBlocks_; 75 | typedef std::vector Chunks; 76 | Chunks chunks_; 77 | Chunk* allocChunk_; 78 | Chunk* deallocChunk_; 79 | // For ensuring proper copy semantics 80 | mutable const FixedAllocator* prev_; 81 | mutable const FixedAllocator* next_; 82 | 83 | public: 84 | // Create a FixedAllocator able to manage blocks of 'blockSize' size 85 | explicit FixedAllocator(VC_BROKEN_STD::size_t blockSize = 0); 86 | FixedAllocator(const FixedAllocator&); 87 | FixedAllocator& operator=(const FixedAllocator&); 88 | ~FixedAllocator(); 89 | 90 | void Swap(FixedAllocator& rhs); 91 | 92 | // Allocate a memory block 93 | void* Allocate(); 94 | // Deallocate a memory block previously allocated with Allocate() 95 | // (if that's not the case, the behavior is undefined) 96 | void Deallocate(void* p); 97 | // Returns the block size with which the FixedAllocator was initialized 98 | VC_BROKEN_STD::size_t BlockSize() const 99 | { return blockSize_; } 100 | // Comparison operator for sorting 101 | bool operator<(VC_BROKEN_STD::size_t rhs) const 102 | { return BlockSize() < rhs; } 103 | }; 104 | 105 | //////////////////////////////////////////////////////////////////////////////// 106 | // class SmallObjAllocator 107 | // Offers services for allocating small-sized objects 108 | //////////////////////////////////////////////////////////////////////////////// 109 | 110 | class SmallObjAllocator 111 | { 112 | public: 113 | SmallObjAllocator( 114 | VC_BROKEN_STD::size_t chunkSize, 115 | VC_BROKEN_STD::size_t maxObjectSize); 116 | 117 | void* Allocate(VC_BROKEN_STD::size_t numBytes); 118 | void Deallocate(void* p, VC_BROKEN_STD::size_t size); 119 | 120 | private: 121 | SmallObjAllocator(const SmallObjAllocator&); 122 | SmallObjAllocator& operator=(const SmallObjAllocator&); 123 | 124 | typedef std::vector Pool; 125 | Pool pool_; 126 | FixedAllocator* pLastAlloc_; 127 | FixedAllocator* pLastDealloc_; 128 | VC_BROKEN_STD::size_t chunkSize_; 129 | VC_BROKEN_STD::size_t maxObjectSize_; 130 | }; 131 | 132 | //////////////////////////////////////////////////////////////////////////////// 133 | // class SmallObject 134 | // Base class for polymorphic small objects, offers fast 135 | // allocations/deallocations 136 | //////////////////////////////////////////////////////////////////////////////// 137 | 138 | template 139 | < 140 | class ThreadingModel = DEFAULT_THREADING, 141 | VC_BROKEN_STD::size_t chunkSize = DEFAULT_CHUNK_SIZE, 142 | VC_BROKEN_STD::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE 143 | > 144 | class SmallObject : public 145 | Apply1 > 146 | { 147 | typedef typename Apply1 > MyThreadingModel; 149 | 150 | struct MySmallObjAllocator : public SmallObjAllocator 151 | { 152 | MySmallObjAllocator() 153 | : SmallObjAllocator(chunkSize, maxSmallObjectSize) 154 | {} 155 | }; 156 | // The typedef below would make things much simpler, 157 | // but MWCW won't like it 158 | // typedef SingletonHolder MyAllocator; 160 | 161 | public: 162 | static void* operator new(VC_BROKEN_STD::size_t size, VC_BROKEN_STD::size_t dummy = 0) 163 | { 164 | #if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) 165 | typename MyThreadingModel::Lock lock; 166 | (void)lock; // get rid of warning 167 | 168 | return SingletonHolder::Instance().Allocate(size); 170 | #else 171 | return ::operator new(size); 172 | #endif 173 | } 174 | static void operator delete(void* p, VC_BROKEN_STD::size_t size) 175 | { 176 | #if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) 177 | typename MyThreadingModel::Lock lock; 178 | (void)lock; // get rid of warning 179 | 180 | SingletonHolder::Instance().Deallocate(p, size); 182 | #else 183 | ::operator delete(p, size); 184 | #endif 185 | } 186 | virtual ~SmallObject() {} 187 | }; 188 | } // namespace Loki 189 | 190 | //////////////////////////////////////////////////////////////////////////////// 191 | // Change log: 192 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 193 | // Oct 11, 2002: ported by Benjamin Kaufmann to MSVC 6.0 194 | //////////////////////////////////////////////////////////////////////////////// 195 | 196 | #endif // SMALLOBJ_INC_ 197 | -------------------------------------------------------------------------------- /MSVC/1200/SmartPtr.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dutor/loki/a992dfe3e200c1f04edd2088a809e203def8af52/MSVC/1200/SmartPtr.h -------------------------------------------------------------------------------- /MSVC/1200/Threads.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADS_H_ 2 | #define THREADS_H_ 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // macro DEFAULT_THREADING 5 | // Selects the default threading model for certain components of Loki 6 | // If you don't define it, it defaults to single-threaded 7 | // All classes in Loki have configurable threading model; DEFAULT_THREADING 8 | // affects only default template arguments 9 | //////////////////////////////////////////////////////////////////////////////// 10 | 11 | // Last update: Mar 26, 2003 12 | // note: In this VC 6 port all template policies become non-templates with 13 | // either member-template functions or a nested template struct named In 14 | 15 | // Changed wrong ctor/dtor names in ObjectLevelLockable. 16 | // Thanks to Adi Shavit for pointing that out 17 | 18 | #ifndef DEFAULT_THREADING 19 | #define DEFAULT_THREADING /**/ ::Loki::SingleThreaded 20 | #endif 21 | 22 | namespace Loki 23 | { 24 | //////////////////////////////////////////////////////////////////////////////// 25 | // class template SingleThreaded 26 | // Implementation of the ThreadingModel policy used by various classes 27 | // Implements a single-threaded model; no synchronization 28 | //////////////////////////////////////////////////////////////////////////////// 29 | class SingleThreaded 30 | { 31 | public: 32 | template 33 | struct In 34 | { 35 | struct Lock 36 | { 37 | Lock() {} 38 | explicit Lock(const SingleThreaded&) {} 39 | }; 40 | 41 | typedef Host VolatileType; 42 | 43 | typedef int IntType; 44 | 45 | static IntType AtomicAdd(volatile IntType& lval, IntType val) 46 | { return lval += val; } 47 | 48 | static IntType AtomicSubtract(volatile IntType& lval, IntType val) 49 | { return lval -= val; } 50 | 51 | static IntType AtomicMultiply(volatile IntType& lval, IntType val) 52 | { return lval *= val; } 53 | 54 | static IntType AtomicDivide(volatile IntType& lval, IntType val) 55 | { return lval /= val; } 56 | 57 | static IntType AtomicIncrement(volatile IntType& lval) 58 | { return ++lval; } 59 | 60 | static IntType AtomicDecrement(volatile IntType& lval) 61 | { return --lval; } 62 | 63 | // The following function uses the undefined variable val. 64 | // Moreover I couldn't find the function in the orginial loki-lib. 65 | // I therefore commented the function out 66 | /* 67 | static IntType AtomicDivide(volatile IntType& lval) 68 | { return lval /= val; } 69 | */ 70 | static void AtomicAssign(volatile IntType & lval, IntType val) 71 | { lval = val; } 72 | 73 | static void AtomicAssign(IntType & lval, volatile IntType & val) 74 | { lval = val; } 75 | }; 76 | }; 77 | 78 | #ifdef _WINDOWS_ 79 | 80 | //////////////////////////////////////////////////////////////////////////////// 81 | // class template ObjectLevelLockable 82 | // Implementation of the ThreadingModel policy used by various classes 83 | // Implements a object-level locking scheme 84 | //////////////////////////////////////////////////////////////////////////////// 85 | 86 | 87 | struct ObjectLevelLockable 88 | { 89 | template 90 | struct In 91 | { 92 | private: 93 | CRITICAL_SECTION mtx_; 94 | 95 | public: 96 | In() 97 | { 98 | ::InitializeCriticalSection(&mtx_); 99 | } 100 | 101 | ~In() 102 | { 103 | ::DeleteCriticalSection(&mtx_); 104 | } 105 | 106 | class Lock; 107 | friend class Lock; 108 | 109 | class Lock 110 | { 111 | ObjectLevelLockable::In& host_; 112 | 113 | Lock(const Lock&); 114 | Lock& operator=(const Lock&); 115 | //Lock(); // buggy design 116 | public: 117 | 118 | explicit Lock(ObjectLevelLockable::In& host) : host_(host) 119 | { 120 | ::EnterCriticalSection(&host_.mtx_); 121 | } 122 | ~Lock() 123 | { 124 | ::LeaveCriticalSection(&host_.mtx_); 125 | } 126 | }; 127 | 128 | typedef volatile Host VolatileType; 129 | 130 | typedef LONG IntType; 131 | 132 | static IntType AtomicIncrement(volatile IntType& lval) 133 | { return InterlockedIncrement(&const_cast(lval)); } 134 | 135 | static IntType AtomicDecrement(volatile IntType& lval) 136 | { return InterlockedDecrement(&const_cast(lval)); } 137 | 138 | static void AtomicAssign(volatile IntType& lval, IntType val) 139 | { InterlockedExchange(&const_cast(lval), val); } 140 | 141 | static void AtomicAssign(IntType& lval, volatile IntType& val) 142 | { InterlockedExchange(&lval, val); } 143 | }; 144 | }; 145 | 146 | struct ClassLevelLockable 147 | { 148 | template 149 | struct In 150 | { 151 | public: 152 | struct Initializer; 153 | friend struct Initializer; 154 | struct Initializer 155 | { 156 | 157 | CRITICAL_SECTION mtx_; 158 | 159 | Initializer() 160 | { 161 | ::InitializeCriticalSection(&mtx_); 162 | } 163 | ~Initializer() 164 | { 165 | ::DeleteCriticalSection(&mtx_); 166 | } 167 | }; 168 | 169 | static Initializer initializer_; 170 | 171 | public: 172 | class Lock; 173 | friend class Lock; 174 | 175 | class Lock 176 | { 177 | Lock(const Lock&); 178 | Lock& operator=(const Lock&); 179 | public: 180 | Lock() 181 | { 182 | ::EnterCriticalSection(&initializer_.mtx_); 183 | } 184 | explicit Lock(ClassLevelLockable&) 185 | { 186 | ::EnterCriticalSection(&initializer_.mtx_); 187 | } 188 | ~Lock() 189 | { 190 | ::LeaveCriticalSection(&initializer_.mtx_); 191 | } 192 | }; 193 | 194 | typedef volatile Host VolatileType; 195 | 196 | typedef LONG IntType; 197 | 198 | static IntType AtomicIncrement(volatile IntType& lval) 199 | { return InterlockedIncrement(&const_cast(lval)); } 200 | 201 | static IntType AtomicDecrement(volatile IntType& lval) 202 | { return InterlockedDecrement(&const_cast(lval)); } 203 | 204 | static void AtomicAssign(volatile IntType& lval, IntType val) 205 | { InterlockedExchange(&const_cast(lval), val); } 206 | 207 | static void AtomicAssign(IntType& lval, volatile IntType& val) 208 | { InterlockedExchange(&lval, val); } 209 | }; 210 | }; 211 | 212 | template 213 | typename Loki::ClassLevelLockable::template In::Initializer 214 | Loki::ClassLevelLockable::template In::initializer_; 215 | 216 | #endif 217 | } 218 | 219 | //////////////////////////////////////////////////////////////////////////////// 220 | // Change log: 221 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 222 | // Oct 06, 2002: ported by Benjamin Kaufmann to MSVC 6.0 223 | // Feb 20, 2003: corrected constructor parameter in ObjectLevelLockable::Lock 224 | // Mar 26, 2003: added Loki-Namespace-Qualification to definition of 225 | // ClassLevelLockable's static member. 226 | //////////////////////////////////////////////////////////////////////////////// 227 | 228 | #endif 229 | -------------------------------------------------------------------------------- /MSVC/1200/Tuple.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // This file is intentionally left empty 20 | // Due to compiler limitations, its contents has been moved to 21 | // HierarchyGenerators.h 22 | //////////////////////////////////////////////////////////////////////////////// 23 | -------------------------------------------------------------------------------- /MSVC/1200/static_check.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef STATIC_CHECK_INC_ 19 | #define STATIC_CHECK_INC_ 20 | 21 | namespace Loki 22 | { 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // Helper structure for the STATIC_CHECK macro 25 | //////////////////////////////////////////////////////////////////////////////// 26 | 27 | template struct CompileTimeError; 28 | template<> struct CompileTimeError {}; 29 | 30 | namespace Private 31 | { 32 | template struct static_assert_test{}; 33 | template struct SizeError; 34 | 35 | template <> struct SizeError{}; 36 | } 37 | } 38 | 39 | #define STATIC_SIZE_ASSERT(Type, ExpSize) \ 40 | typedef ::Loki::Private::static_assert_test)> static_assert_typedef_ 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // macro STATIC_CHECK 45 | // Invocation: STATIC_CHECK(expr, id) 46 | // where: 47 | // expr is a compile-time integral or pointer expression 48 | // id is a C++ identifier that does not need to be defined 49 | // If expr is zero, id will appear in a compile-time error message. 50 | //////////////////////////////////////////////////////////////////////////////// 51 | 52 | #define STATIC_CHECK(expr, msg) \ 53 | { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } 54 | 55 | 56 | //////////////////////////////////////////////////////////////////////////////// 57 | // Change log: 58 | // March 20, 2001: add extra parens to STATIC_CHECK - it looked like a fun 59 | // definition 60 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 61 | //////////////////////////////////////////////////////////////////////////////// 62 | 63 | #endif // STATIC_CHECK_INC_ 64 | -------------------------------------------------------------------------------- /MSVC/1300/AbstractFactory.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: May 19, 2002 17 | 18 | #ifndef ABSTRACTFACTORY_INC_ 19 | #define ABSTRACTFACTORY_INC_ 20 | 21 | #include "Typelist.h" 22 | #include "TypeManip.h" 23 | #include "HierarchyGenerators.h" 24 | 25 | #include 26 | 27 | namespace Loki 28 | { 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // class template AbstractFactoryUnit 32 | // The building block of an Abstract Factory 33 | //////////////////////////////////////////////////////////////////////////////// 34 | 35 | template 36 | class AbstractFactoryUnit 37 | { 38 | public: 39 | virtual T* DoCreate(Type2Type) = 0; 40 | virtual ~AbstractFactoryUnit() {} 41 | }; 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // class template AbstractFactory 45 | // Defines an Abstract Factory interface starting from a typelist 46 | //////////////////////////////////////////////////////////////////////////////// 47 | 48 | template 49 | < 50 | class TList, 51 | template class Unit = AbstractFactoryUnit 52 | > 53 | class AbstractFactory : public GenScatterHierarchy 54 | { 55 | public: 56 | typedef TList ProductList; 57 | 58 | template T* Create() 59 | { 60 | Unit& unit = *this; 61 | return unit.DoCreate(Type2Type()); 62 | } 63 | }; 64 | 65 | //////////////////////////////////////////////////////////////////////////////// 66 | // class template OpNewFactoryUnit 67 | // Creates an object by invoking the new operator 68 | //////////////////////////////////////////////////////////////////////////////// 69 | 70 | template 71 | class OpNewFactoryUnit : public Base 72 | { 73 | typedef typename Base::ProductList BaseProductList; 74 | 75 | protected: 76 | typedef typename BaseProductList::Tail ProductList; 77 | 78 | public: 79 | typedef typename BaseProductList::Head AbstractProduct; 80 | ConcreteProduct* DoCreate(Type2Type) 81 | { 82 | return new ConcreteProduct; 83 | } 84 | }; 85 | 86 | //////////////////////////////////////////////////////////////////////////////// 87 | // class template PrototypeFactoryUnit 88 | // Creates an object by cloning a prototype 89 | // There is a difference between the implementation herein and the one described 90 | // in the book: GetPrototype and SetPrototype use the helper friend 91 | // functions DoGetPrototype and DoSetPrototype. The friend functions avoid 92 | // name hiding issues. Plus, GetPrototype takes a reference to pointer 93 | // instead of returning the pointer by value. 94 | //////////////////////////////////////////////////////////////////////////////// 95 | 96 | template 97 | class PrototypeFactoryUnit : public Base 98 | { 99 | typedef typename Base::ProductList BaseProductList; 100 | 101 | protected: 102 | typedef typename BaseProductList::Tail ProductList; 103 | 104 | public: 105 | typedef typename BaseProductList::Head AbstractProduct; 106 | 107 | PrototypeFactoryUnit(AbstractProduct* p = 0) 108 | : pPrototype_(p) 109 | {} 110 | 111 | friend void DoGetPrototype(const PrototypeFactoryUnit& me, 112 | AbstractProduct*& pPrototype) 113 | { pPrototype = me.pPrototype_; } 114 | 115 | friend void DoSetPrototype(PrototypeFactoryUnit& me, 116 | AbstractProduct* pObj) 117 | { me.pPrototype_ = pObj; } 118 | 119 | template 120 | void GetPrototype(U*& p) 121 | { return DoGetPrototype(*this, p); } 122 | 123 | template 124 | void SetPrototype(U* pObj) 125 | { DoSetPrototype(*this, pObj); } 126 | 127 | AbstractProduct* DoCreate(Type2Type) 128 | { 129 | assert(pPrototype_); 130 | return pPrototype_->Clone(); 131 | } 132 | 133 | private: 134 | AbstractProduct* pPrototype_; 135 | }; 136 | 137 | //////////////////////////////////////////////////////////////////////////////// 138 | // class template ConcreteFactory 139 | // Implements an AbstractFactory interface 140 | //////////////////////////////////////////////////////////////////////////////// 141 | 142 | template 143 | < 144 | class AbstractFact, 145 | template class Creator = OpNewFactoryUnit, 146 | class TList = typename AbstractFact::ProductList 147 | > 148 | class ConcreteFactory 149 | : public GenLinearHierarchy< 150 | typename TL::Reverse::Result, Creator, AbstractFact> 151 | { 152 | public: 153 | typedef typename AbstractFact::ProductList ProductList; 154 | typedef TList ConcreteProductList; 155 | }; 156 | 157 | } // namespace Loki 158 | 159 | //////////////////////////////////////////////////////////////////////////////// 160 | // Change log: 161 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 162 | // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) 163 | // September 25, 2004: Fixed bug in PrototypeFactoryUnit::GetPrototype, thanks 164 | // to a bug report submitted by funcall. 165 | //////////////////////////////////////////////////////////////////////////////// 166 | 167 | #endif // ABSTRACTFACTORY_INC_ 168 | -------------------------------------------------------------------------------- /MSVC/1300/DataGenerators.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Data Generator by Mr. Shannon Barber 4 | // This code DOES NOT accompany the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // 8 | // Code covered by the MIT License 9 | // 10 | // The author makes no representations about the suitability of this software 11 | // for any purpose. It is provided "as is" without express or implied warranty. 12 | //////////////////////////////////////////////////////////////////////////////// 13 | 14 | // Last update: Oct 10, 2002 15 | 16 | #pragma once 17 | #include "Typelist.h" 18 | 19 | //MSVC7 version 20 | namespace Loki 21 | { 22 | //////////////////////////////////////////////////////////////////////////////// 23 | // class template IterateTypes 24 | //////////////////////////////////////////////////////////////////////////////// 25 | namespace TL 26 | { 27 | template 28 | struct nameof_type 29 | { 30 | const char* operator()() 31 | { 32 | return typeid(T).name(); 33 | } 34 | }; 35 | template 36 | struct sizeof_type 37 | { 38 | size_t operator()() 39 | { 40 | return sizeof(T); 41 | } 42 | }; 43 | template class UnitFunc> 44 | struct IterateTypes; 45 | 46 | namespace Private 47 | { 48 | // for some reason VC7 needs the base definition altough not in use 49 | template 50 | struct IterateTypesHelper1 51 | { 52 | template class GenFunc> 53 | struct In 54 | { 55 | typedef typename T::ERROR_THIS_INSTANCE_SELECTED Result; 56 | }; 57 | }; 58 | 59 | template 60 | struct IterateTypesHelper2 61 | { 62 | template class GenFunc> 63 | struct In 64 | { 65 | typedef typename T::ERROR_THIS_INSTANCE_SELECTED Result; 66 | }; 67 | }; 68 | 69 | 70 | template <> 71 | struct IterateTypesHelper1 72 | { 73 | template class GenFunc> 74 | struct In 75 | { 76 | typedef IterateTypes Result; 77 | }; 78 | }; 79 | 80 | template <> 81 | struct IterateTypesHelper2 82 | { 83 | template class GenFunc> 84 | struct In 85 | { 86 | typedef IterateTypes Result; 87 | }; 88 | }; 89 | 90 | 91 | template <> 92 | struct IterateTypesHelper1 93 | { 94 | template class GenFunc> 95 | struct In 96 | { 97 | struct Result 98 | { 99 | typedef GenFunc genfunc_t; 100 | template 101 | void operator()(II ii) 102 | { 103 | genfunc_t gen; 104 | //warning C4267: 'argument' : conversion from 'size_t' to 'const std::_Vbase', possible loss of data 105 | #pragma warning(push) 106 | #pragma warning(disable: 4267) 107 | //TODOSGB 108 | *ii = gen(); 109 | #pragma warning(pop) 110 | ++ii; 111 | } 112 | template 113 | void operator()(II ii, P1 p1) 114 | { 115 | genfunc_t gen; 116 | *ii = gen(p1); 117 | ++ii; 118 | } 119 | }; 120 | }; 121 | }; 122 | 123 | template <> 124 | struct IterateTypesHelper2 125 | { 126 | template class GenFunc> 127 | struct In 128 | { 129 | struct Result 130 | { 131 | template void operator()(II) {} 132 | template void operator()(II, P1) {} 133 | }; 134 | }; 135 | }; 136 | 137 | 138 | template <> 139 | struct IterateTypesHelper1 140 | { 141 | template class GenFunc> 142 | struct In 143 | { 144 | struct Result 145 | { 146 | template void operator()(II) {} 147 | template void operator()(II, P1) {} 148 | }; 149 | }; 150 | }; 151 | 152 | template <> 153 | struct IterateTypesHelper2 154 | { 155 | template class GenFunc> 156 | struct In 157 | { 158 | struct Result 159 | { 160 | template void operator()(II) {} 161 | template void operator()(II, P1) {} 162 | }; 163 | }; 164 | }; 165 | 166 | } // namespace Private 167 | 168 | 169 | 170 | //////////////////////////////////////////////////////////////////////////////// 171 | // class template IterateTypes 172 | // Iteratates a Typelist, and invokes the ctor of GenFunc 173 | // for each type in the list, passing a functor along the way. 174 | // The functor is designed to be an insertion iterator which GenFunc 175 | // can use to output information about the types in the list. 176 | //////////////////////////////////////////////////////////////////////////////// 177 | 178 | 179 | template class GenFunc> 180 | struct IterateTypes 181 | { 182 | public: 183 | 184 | typedef typename Private::IterateTypesHelper1 185 | < 186 | typename TL::is_Typelist::type_tag 187 | > 188 | ::template In::Result head_t; 189 | 190 | typedef typename Private::IterateTypesHelper2 191 | < 192 | typename TL::is_Typelist::type_tag 193 | > 194 | ::template In::Result tail_t; 195 | head_t head; 196 | tail_t tail; 197 | 198 | template 199 | void operator()(II ii) 200 | { 201 | this->head.operator()(ii); 202 | this->tail.operator()(ii); 203 | } 204 | template 205 | void operator()(II ii, P1 p1) 206 | { 207 | this->head.operator()(ii, p1); 208 | this->tail.operator()(ii, p1); 209 | } 210 | }; 211 | 212 | //UnitFunc is really a template-template parameter, but MSVC7 213 | // chokes on the correct defintion. Oddly enough, it works correctly 214 | // with the 'undecorated' template parameter declaraion! 215 | //template class UnitFunc 216 | template 217 | void iterate_types(II ii) 218 | { 219 | Loki::TL::IterateTypes it; 220 | it(ii); 221 | } 222 | }//ns TL 223 | }//ns Loki 224 | 225 | //////////////////////////////////////////////////////////////////////////////// 226 | // Change log: 227 | // Aug 17, 2002: Ported to MSVC7 by Rani Sharoni 228 | // Aug 18, 2002: Removed ctor(II), replaced with operator(II) Shannon Barber 229 | // Oct 10, 2002: Changed II (insertion iterator) from pass-by-reference to pass-by-value 230 | //////////////////////////////////////////////////////////////////////////////// 231 | 232 | -------------------------------------------------------------------------------- /MSVC/1300/EmptyType.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef EMPTYTYPE_INC_ 19 | #define EMPTYTYPE_INC_ 20 | 21 | namespace Loki 22 | { 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // class EmptyType 25 | // Used as a class type that doesn't hold anything 26 | // Useful as a strawman class 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | class EmptyType {}; 30 | } 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | // Change log: 34 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 35 | //////////////////////////////////////////////////////////////////////////////// 36 | 37 | #endif // EMPTYTYPE_INC_ 38 | -------------------------------------------------------------------------------- /MSVC/1300/Factory.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: May 19, 2002 17 | 18 | #ifndef FACTORY_INC_ 19 | #define FACTORY_INC_ 20 | 21 | #include "LokiTypeInfo.h" 22 | #include "AssocVector.h" 23 | #include 24 | 25 | namespace Loki 26 | { 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // class template DefaultFactoryError 30 | // Manages the "Unknown Type" error in an object factory 31 | //////////////////////////////////////////////////////////////////////////////// 32 | 33 | template 34 | struct DefaultFactoryError 35 | { 36 | struct Exception : public std::exception 37 | { 38 | const char* what() const throw() { return "Unknown Type"; } 39 | }; 40 | 41 | static AbstractProduct* OnUnknownType(IdentifierType) 42 | { 43 | throw Exception(); 44 | } 45 | }; 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | // class template Factory 49 | // Implements a generic object factory 50 | //////////////////////////////////////////////////////////////////////////////// 51 | 52 | template 53 | < 54 | class AbstractProduct, 55 | typename IdentifierType, 56 | typename ProductCreator = AbstractProduct* (*)(), 57 | template 58 | class FactoryErrorPolicy = DefaultFactoryError 59 | > 60 | class Factory 61 | : public FactoryErrorPolicy 62 | { 63 | public: 64 | bool Register(const IdentifierType& id, ProductCreator creator) 65 | { 66 | return associations_.insert( 67 | IdToProductMap::value_type(id, creator)).second; 68 | } 69 | 70 | bool Unregister(const IdentifierType& id) 71 | { 72 | return associations_.erase(id) == 1; 73 | } 74 | 75 | AbstractProduct* CreateObject(const IdentifierType& id) 76 | { 77 | typename IdToProductMap::iterator i = associations_.find(id); 78 | if (i != associations_.end()) 79 | { 80 | return (i->second)(); 81 | } 82 | return OnUnknownType(id); 83 | } 84 | 85 | private: 86 | typedef AssocVector IdToProductMap; 87 | IdToProductMap associations_; 88 | }; 89 | 90 | //////////////////////////////////////////////////////////////////////////////// 91 | // class template CloneFactory 92 | // Implements a generic cloning factory 93 | //////////////////////////////////////////////////////////////////////////////// 94 | 95 | template 96 | < 97 | class AbstractProduct, 98 | class ProductCreator = 99 | AbstractProduct* (*)(const AbstractProduct*), 100 | template 101 | class FactoryErrorPolicy = DefaultFactoryError 102 | > 103 | class CloneFactory 104 | : public FactoryErrorPolicy 105 | { 106 | public: 107 | bool Register(const TypeInfo& ti, ProductCreator creator) 108 | { 109 | return associations_.insert( 110 | IdToProductMap::value_type(ti, creator)).second; 111 | } 112 | 113 | bool Unregister(const TypeInfo& id) 114 | { 115 | return associations_.erase(id) == 1; 116 | } 117 | 118 | AbstractProduct* CreateObject(const AbstractProduct* model) 119 | { 120 | if (model == 0) return 0; 121 | 122 | typename IdToProductMap::iterator i = 123 | associations_.find(typeid(*model)); 124 | if (i != associations_.end()) 125 | { 126 | return (i->second)(model); 127 | } 128 | return OnUnknownType(typeid(*model)); 129 | } 130 | 131 | private: 132 | typedef AssocVector IdToProductMap; 133 | IdToProductMap associations_; 134 | }; 135 | } // namespace Loki 136 | 137 | //////////////////////////////////////////////////////////////////////////////// 138 | // Change log: 139 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 140 | // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) 141 | //////////////////////////////////////////////////////////////////////////////// 142 | 143 | #endif // FACTORY_INC_ 144 | -------------------------------------------------------------------------------- /MSVC/1300/LokiTypeInfo.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: May 19, 2002 17 | 18 | #ifndef LOKITYPEINFO_INC_ 19 | #define LOKITYPEINFO_INC_ 20 | 21 | #include 22 | #include 23 | #include "Typelist.h" 24 | 25 | namespace Loki 26 | { 27 | //////////////////////////////////////////////////////////////////////////////// 28 | // class TypeInfo 29 | // Purpose: offer a first-class, comparable wrapper over std::type_info 30 | //////////////////////////////////////////////////////////////////////////////// 31 | 32 | class TypeInfo 33 | { 34 | public: 35 | // Constructors 36 | TypeInfo(); // needed for containers 37 | TypeInfo(const std::type_info&); // non-explicit 38 | 39 | // Access for the wrapped std::type_info 40 | const std::type_info& Get() const; 41 | // Compatibility functions 42 | bool before(const TypeInfo& rhs) const; 43 | const char* name() const; 44 | 45 | private: 46 | const std::type_info* pInfo_; 47 | }; 48 | 49 | // Implementation 50 | 51 | inline TypeInfo::TypeInfo() 52 | { 53 | class Nil {}; 54 | pInfo_ = &typeid(Nil); 55 | assert(pInfo_); 56 | } 57 | 58 | inline TypeInfo::TypeInfo(const std::type_info& ti) 59 | : pInfo_(&ti) 60 | { assert(pInfo_); } 61 | 62 | inline bool TypeInfo::before(const TypeInfo& rhs) const 63 | { 64 | assert(pInfo_); 65 | return pInfo_->before(*rhs.pInfo_) != 0; 66 | } 67 | 68 | inline const std::type_info& TypeInfo::Get() const 69 | { 70 | assert(pInfo_); 71 | return *pInfo_; 72 | } 73 | 74 | inline const char* TypeInfo::name() const 75 | { 76 | assert(pInfo_); 77 | return pInfo_->name(); 78 | } 79 | 80 | // Comparison operators 81 | 82 | inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs) 83 | { return (lhs.Get() == rhs.Get()) != 0; } 84 | 85 | inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs) 86 | { return lhs.before(rhs); } 87 | 88 | inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs) 89 | { return !(lhs == rhs); } 90 | 91 | inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs) 92 | { return rhs < lhs; } 93 | 94 | inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs) 95 | { return !(lhs > rhs); } 96 | 97 | inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs) 98 | { return !(lhs < rhs); } 99 | } 100 | 101 | //////////////////////////////////////////////////////////////////////////////// 102 | // Change log: 103 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 104 | // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) 105 | //////////////////////////////////////////////////////////////////////////////// 106 | 107 | #endif // LOKITYPEINFO_INC_ 108 | -------------------------------------------------------------------------------- /MSVC/1300/MinMax.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: May 19, 2002 17 | 18 | #ifndef MINMAX_INC_ 19 | #define MINMAX_INC_ 20 | 21 | #include "Typelist.h" 22 | #include "TypeTraits.h" 23 | 24 | namespace Private 25 | { 26 | typedef TYPELIST_14( 27 | const bool, 28 | const char, 29 | const signed char, 30 | const unsigned char, 31 | const wchar_t, 32 | const short int, 33 | const unsigned short int, 34 | const int, 35 | const unsigned int, 36 | const long int, 37 | const unsigned long int, 38 | const float, 39 | const double, 40 | const long double) 41 | ArithTypes; 42 | } 43 | 44 | template 45 | class MinMaxTraits 46 | { 47 | typedef typename Loki::Select::exists, 48 | L, R>::Result 49 | T1; 50 | 51 | enum { pos1 = Loki::TL::IndexOf::value }; 52 | enum { pos2 = Loki::TL::IndexOf::value }; 53 | typedef Loki::Select::Result T2; 54 | 55 | enum { rConst = Loki::TypeTraits::isConst >= 56 | Loki::TypeTraits::isConst }; 57 | enum { l2r = rConst && Loki::Conversion< 58 | typename Loki::TypeTraits::NonConstType&, 59 | typename Loki::TypeTraits::NonConstType&>::exists }; 60 | typedef typename Loki::Select::Result T3; 61 | 62 | enum { lConst = Loki::TypeTraits::isConst >= 63 | Loki::TypeTraits::isConst }; 64 | enum { r2l = lConst && Loki::Conversion< 65 | typename Loki::TypeTraits::NonConstType&, 66 | typename Loki::TypeTraits::NonConstType&>::exists }; 67 | public: 68 | typedef typename Loki::Select::Result Result; 69 | }; 70 | 71 | template 72 | typename MinMaxTraits::Result 73 | Min(L& lhs, R& rhs) 74 | { if (lhs < rhs) return lhs; return rhs; } 75 | 76 | template 77 | typename MinMaxTraits::Result 78 | Min(const L& lhs, R& rhs) 79 | { if (lhs < rhs) return lhs; return rhs; } 80 | 81 | template 82 | typename MinMaxTraits::Result 83 | Min(L& lhs, const R& rhs) 84 | { if (lhs < rhs) return lhs; return rhs; } 85 | 86 | template 87 | typename MinMaxTraits::Result 88 | Min(const L& lhs, const R& rhs) 89 | { if (lhs < rhs) return lhs; return rhs; } 90 | 91 | template 92 | typename MinMaxTraits::Result 93 | Max(L& lhs, R& rhs) 94 | { if (lhs > rhs) return lhs; return rhs; } 95 | 96 | template 97 | typename MinMaxTraits::Result 98 | Max(const L& lhs, R& rhs) 99 | { if (lhs > rhs) return lhs; return rhs; } 100 | 101 | template 102 | typename MinMaxTraits::Result 103 | Max(L& lhs, const R& rhs) 104 | { if (lhs > rhs) return lhs; return rhs; } 105 | 106 | template 107 | typename MinMaxTraits::Result 108 | Max(const L& lhs, const R& rhs) 109 | { if (lhs > rhs) return lhs; return rhs; } 110 | 111 | 112 | #endif // MINMAX_INC_ 113 | -------------------------------------------------------------------------------- /MSVC/1300/NullType.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: May 19, 2002 17 | 18 | #ifndef NULLTYPE_INC_ 19 | #define NULLTYPE_INC_ 20 | 21 | namespace Loki 22 | { 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // class NullType 25 | // Used as a placeholder for "no type here" 26 | // Useful as an end marker in typelists 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | class NullType 30 | { 31 | public: 32 | struct Head { private: Head(); }; 33 | struct Tail { private: Tail(); }; 34 | }; 35 | } 36 | 37 | /////////////////////////////////////////////////////////////////////////////// 38 | // Change log: 39 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 40 | // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) 41 | //////////////////////////////////////////////////////////////////////////////// 42 | 43 | #endif // NULLTYPE_INC_ 44 | 45 | -------------------------------------------------------------------------------- /MSVC/1300/Singleton.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #include "Singleton.h" 19 | 20 | using namespace Loki::Private; 21 | 22 | Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0; 23 | unsigned int Loki::Private::elements = 0; 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // function AtExitFn 27 | // Ensures proper destruction of objects with longevity 28 | //////////////////////////////////////////////////////////////////////////////// 29 | 30 | void C_CALLING_CONVENTION_QUALIFIER Loki::Private::AtExitFn() 31 | { 32 | assert(elements > 0 && pTrackerArray != 0); 33 | // Pick the element at the top of the stack 34 | LifetimeTracker* pTop = pTrackerArray[elements - 1]; 35 | // Remove that object off the stack 36 | // Don't check errors - realloc with less memory 37 | // can't fail 38 | pTrackerArray = static_cast(std::realloc( 39 | pTrackerArray, sizeof(*pTrackerArray) * --elements)); 40 | // Destroy the element 41 | delete pTop; 42 | } 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // Change log: 46 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 47 | // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) 48 | //////////////////////////////////////////////////////////////////////////////// 49 | -------------------------------------------------------------------------------- /MSVC/1300/SmallObj.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: May 19, 2002 17 | 18 | #ifndef SMALLOBJ_INC_ 19 | #define SMALLOBJ_INC_ 20 | 21 | #include "Threads.h" 22 | #include "Singleton.h" 23 | #include 24 | #include 25 | 26 | #ifndef DEFAULT_CHUNK_SIZE 27 | #define DEFAULT_CHUNK_SIZE 4096 28 | #endif 29 | 30 | #ifndef MAX_SMALL_OBJECT_SIZE 31 | #define MAX_SMALL_OBJECT_SIZE 64 32 | #endif 33 | 34 | namespace Loki 35 | { 36 | //////////////////////////////////////////////////////////////////////////////// 37 | // class FixedAllocator 38 | // Offers services for allocating fixed-sized objects 39 | //////////////////////////////////////////////////////////////////////////////// 40 | 41 | class FixedAllocator 42 | { 43 | public: // VC7 access control BUG 44 | class Chunk 45 | { 46 | friend FixedAllocator; 47 | 48 | void Init(std::size_t blockSize, unsigned char blocks); 49 | void* Allocate(std::size_t blockSize); 50 | void Deallocate(void* p, std::size_t blockSize); 51 | void Reset(std::size_t blockSize, unsigned char blocks); 52 | void Release(); 53 | unsigned char* pData_; 54 | unsigned char 55 | firstAvailableBlock_, 56 | blocksAvailable_; 57 | }; 58 | 59 | private: 60 | // Internal functions 61 | void DoDeallocate(void* p); 62 | Chunk* VicinityFind(void* p); 63 | 64 | // Data 65 | std::size_t blockSize_; 66 | unsigned char numBlocks_; 67 | typedef std::vector Chunks; 68 | Chunks chunks_; 69 | Chunk* allocChunk_; 70 | Chunk* deallocChunk_; 71 | // For ensuring proper copy semantics 72 | mutable const FixedAllocator* prev_; 73 | mutable const FixedAllocator* next_; 74 | 75 | public: 76 | // Create a FixedAllocator able to manage blocks of 'blockSize' size 77 | explicit FixedAllocator(std::size_t blockSize = 0); 78 | FixedAllocator(const FixedAllocator&); 79 | FixedAllocator& operator=(const FixedAllocator&); 80 | ~FixedAllocator(); 81 | 82 | void Swap(FixedAllocator& rhs); 83 | 84 | // Allocate a memory block 85 | void* Allocate(); 86 | // Deallocate a memory block previously allocated with Allocate() 87 | // (if that's not the case, the behavior is undefined) 88 | void Deallocate(void* p); 89 | // Returns the block size with which the FixedAllocator was initialized 90 | std::size_t BlockSize() const 91 | { return blockSize_; } 92 | // Comparison operator for sorting 93 | bool operator<(std::size_t rhs) const 94 | { return BlockSize() < rhs; } 95 | }; 96 | 97 | //////////////////////////////////////////////////////////////////////////////// 98 | // class SmallObjAllocator 99 | // Offers services for allocating small-sized objects 100 | //////////////////////////////////////////////////////////////////////////////// 101 | 102 | class SmallObjAllocator 103 | { 104 | public: 105 | SmallObjAllocator( 106 | std::size_t chunkSize, 107 | std::size_t maxObjectSize); 108 | 109 | void* Allocate(std::size_t numBytes); 110 | void Deallocate(void* p, std::size_t size); 111 | 112 | private: 113 | SmallObjAllocator(const SmallObjAllocator&); 114 | SmallObjAllocator& operator=(const SmallObjAllocator&); 115 | 116 | typedef std::vector Pool; 117 | Pool pool_; 118 | FixedAllocator* pLastAlloc_; 119 | FixedAllocator* pLastDealloc_; 120 | std::size_t chunkSize_; 121 | std::size_t maxObjectSize_; 122 | }; 123 | 124 | //////////////////////////////////////////////////////////////////////////////// 125 | // class SmallObject 126 | // Base class for polymorphic small objects, offers fast 127 | // allocations/deallocations 128 | //////////////////////////////////////////////////////////////////////////////// 129 | 130 | template 131 | < 132 | template class ThreadingModel = DEFAULT_THREADING, 133 | std::size_t chunkSize = DEFAULT_CHUNK_SIZE, 134 | std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE 135 | > 136 | class SmallObject : public ThreadingModel< 137 | SmallObject > 138 | { 139 | typedef ThreadingModel< SmallObject > MyThreadingModel; 141 | 142 | struct MySmallObjAllocator : public SmallObjAllocator 143 | { 144 | MySmallObjAllocator() 145 | : SmallObjAllocator(chunkSize, maxSmallObjectSize) 146 | {} 147 | }; 148 | // The typedef below would make things much simpler, 149 | // but MWCW won't like it 150 | // typedef SingletonHolder MyAllocator; 152 | 153 | public: 154 | static void* operator new(std::size_t size) 155 | { 156 | #if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) 157 | typename MyThreadingModel::Lock lock; 158 | (void)lock; // get rid of warning 159 | 160 | return SingletonHolder::Instance().Allocate(size); 162 | #else 163 | return ::operator new(size); 164 | #endif 165 | } 166 | static void operator delete(void* p, std::size_t size) 167 | { 168 | #if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) 169 | typename MyThreadingModel::Lock lock; 170 | (void)lock; // get rid of warning 171 | 172 | SingletonHolder::Instance().Deallocate(p, size); 174 | #else 175 | ::operator delete(p, size); 176 | #endif 177 | } 178 | virtual ~SmallObject() {} 179 | }; 180 | } // namespace Loki 181 | 182 | //////////////////////////////////////////////////////////////////////////////// 183 | // Change log: 184 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 185 | // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) 186 | //////////////////////////////////////////////////////////////////////////////// 187 | 188 | #endif // SMALLOBJ_INC_ 189 | -------------------------------------------------------------------------------- /MSVC/1300/Threads.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADS_H_ 2 | #define THREADS_H_ 3 | 4 | //////////////////////////////////////////////////////////////////////////////// 5 | // macro DEFAULT_THREADING 6 | // Selects the default threading model for certain components of Loki 7 | // If you don't define it, it defaults to single-threaded 8 | // All classes in Loki have configurable threading model; DEFAULT_THREADING 9 | // affects only default template arguments 10 | //////////////////////////////////////////////////////////////////////////////// 11 | 12 | // Last update: June 20, 2001 13 | 14 | #ifndef DEFAULT_THREADING 15 | #define DEFAULT_THREADING /**/ ::Loki::SingleThreaded 16 | #endif 17 | 18 | namespace Loki 19 | { 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // class template SingleThreaded 22 | // Implementation of the ThreadingModel policy used by various classes 23 | // Implements a single-threaded model; no synchronization 24 | //////////////////////////////////////////////////////////////////////////////// 25 | 26 | template 27 | class SingleThreaded 28 | { 29 | public: 30 | struct Lock 31 | { 32 | Lock() {} 33 | explicit Lock(const SingleThreaded&) {} 34 | }; 35 | 36 | typedef Host VolatileType; 37 | 38 | typedef int IntType; 39 | 40 | static IntType AtomicAdd(volatile IntType& lval, IntType val) 41 | { return lval += val; } 42 | 43 | static IntType AtomicSubtract(volatile IntType& lval, IntType val) 44 | { return lval -= val; } 45 | 46 | static IntType AtomicMultiply(volatile IntType& lval, IntType val) 47 | { return lval *= val; } 48 | 49 | static IntType AtomicDivide(volatile IntType& lval, IntType val) 50 | { return lval /= val; } 51 | 52 | static IntType AtomicIncrement(volatile IntType& lval) 53 | { return ++lval; } 54 | 55 | static IntType AtomicDecrement(volatile IntType& lval) 56 | { return --lval; } 57 | 58 | static void AtomicAssign(volatile IntType & lval, IntType val) 59 | { lval = val; } 60 | 61 | static void AtomicAssign(IntType & lval, volatile IntType & val) 62 | { lval = val; } 63 | }; 64 | 65 | #ifdef _WINDOWS_ 66 | 67 | //////////////////////////////////////////////////////////////////////////////// 68 | // class template ObjectLevelLockable 69 | // Implementation of the ThreadingModel policy used by various classes 70 | // Implements a object-level locking scheme 71 | //////////////////////////////////////////////////////////////////////////////// 72 | 73 | template 74 | class ObjectLevelLockable 75 | { 76 | mutable CRITICAL_SECTION mtx_; 77 | 78 | public: 79 | ObjectLevelLockable() 80 | { 81 | ::InitializeCriticalSection(&mtx_); 82 | } 83 | 84 | ~ObjectLevelLockable() 85 | { 86 | ::DeleteCriticalSection(&mtx_); 87 | } 88 | 89 | class Lock; 90 | friend class Lock; 91 | 92 | class Lock 93 | { 94 | ObjectLevelLockable const& host_; 95 | 96 | Lock(const Lock&); 97 | Lock& operator=(const Lock&); 98 | public: 99 | 100 | explicit Lock(const ObjectLevelLockable& host) : host_(host) 101 | { 102 | ::EnterCriticalSection(&host_.mtx_); 103 | } 104 | 105 | ~Lock() 106 | { 107 | ::LeaveCriticalSection(&host_.mtx_); 108 | } 109 | }; 110 | 111 | typedef volatile Host VolatileType; 112 | 113 | typedef LONG IntType; 114 | 115 | static IntType AtomicIncrement(volatile IntType& lval) 116 | { return InterlockedIncrement(&const_cast(lval)); } 117 | 118 | static IntType AtomicDecrement(volatile IntType& lval) 119 | { return InterlockedDecrement(&const_cast(lval)); } 120 | 121 | static void AtomicAssign(volatile IntType& lval, IntType val) 122 | { InterlockedExchange(&const_cast(lval), val); } 123 | 124 | static void AtomicAssign(IntType& lval, volatile IntType& val) 125 | { InterlockedExchange(&lval, val); } 126 | }; 127 | 128 | template 129 | class ClassLevelLockable 130 | { 131 | struct Initializer 132 | { 133 | CRITICAL_SECTION mtx_; 134 | 135 | Initializer() 136 | { 137 | ::InitializeCriticalSection(&mtx_); 138 | } 139 | ~Initializer() 140 | { 141 | ::DeleteCriticalSection(&mtx_); 142 | } 143 | }; 144 | 145 | static Initializer initializer_; 146 | 147 | public: 148 | class Lock; 149 | friend class Lock; 150 | 151 | class Lock 152 | { 153 | Lock(const Lock&); 154 | Lock& operator=(const Lock&); 155 | public: 156 | Lock() 157 | { 158 | ::EnterCriticalSection(&initializer_.mtx_); 159 | } 160 | explicit Lock(const ClassLevelLockable&) 161 | { 162 | ::EnterCriticalSection(&initializer_.mtx_); 163 | } 164 | ~Lock() 165 | { 166 | ::LeaveCriticalSection(&initializer_.mtx_); 167 | } 168 | }; 169 | 170 | typedef volatile Host VolatileType; 171 | 172 | typedef LONG IntType; 173 | 174 | static IntType AtomicIncrement(volatile IntType& lval) 175 | { return InterlockedIncrement(&const_cast(lval)); } 176 | 177 | static IntType AtomicDecrement(volatile IntType& lval) 178 | { return InterlockedDecrement(&const_cast(lval)); } 179 | 180 | static void AtomicAssign(volatile IntType& lval, IntType val) 181 | { InterlockedExchange(&const_cast(lval), val); } 182 | 183 | static void AtomicAssign(IntType& lval, volatile IntType& val) 184 | { InterlockedExchange(&lval, val); } 185 | }; 186 | 187 | template 188 | typename ClassLevelLockable::Initializer 189 | ClassLevelLockable::initializer_; 190 | 191 | #endif 192 | } 193 | 194 | //////////////////////////////////////////////////////////////////////////////// 195 | // Change log: 196 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 197 | //////////////////////////////////////////////////////////////////////////////// 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /MSVC/1300/VC_Alignment.h: -------------------------------------------------------------------------------- 1 | // Last update: June 20, 2001 2 | 3 | #ifdef _MSC_VER 4 | # pragma once 5 | #else 6 | # error "Visual C++ specific header !" 7 | #endif 8 | 9 | #ifndef VC_ALIGNMENT_INC_ 10 | #define VC_ALIGNMENT_INC_ 11 | 12 | #include "Typelist.h" 13 | #include "static_check.h" 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // class template MaxAlign 17 | // Computes the maximum alignof for all types in a typelist 18 | // Usage: MaxAlign::result 19 | //////////////////////////////////////////////////////////////////////////////// 20 | 21 | template struct VC_MaxAlign; 22 | 23 | template <> 24 | struct VC_MaxAlign< ::Loki::NullType > 25 | { 26 | enum { result = 0 }; 27 | }; 28 | 29 | template 30 | struct VC_MaxAlign 31 | { 32 | private: 33 | ASSERT_TYPELIST(TList); 34 | 35 | typedef typename TList::Head Head; 36 | typedef typename TList::Tail Tail; 37 | 38 | private: 39 | enum { headResult = __alignof(Head) }; 40 | enum { tailResult = VC_MaxAlign::result }; 41 | 42 | public: 43 | enum { result = headResult > tailResult ? 44 | headResult : tailResult }; 45 | }; 46 | 47 | 48 | //////////////////////////////////////////////////////////////////////////////// 49 | // class VC_AlignedPODBase 50 | // Defines a host of protected types used by VC_AlignedPOD (defined later) 51 | // Could be just part of VC_AlignedPOD itself, but making it separate ought to 52 | // reduce compile times 53 | //////////////////////////////////////////////////////////////////////////////// 54 | class VC_AlignedPODBase 55 | { 56 | protected: 57 | 58 | template 59 | struct AlignedPod 60 | { 61 | STATIC_CHECK(AlignmentSize == 0, BadAlignmentSize_OnlyUpTo128); 62 | }; 63 | 64 | // 65 | // I used the macro because align(#) 66 | // only works with Integer literals 67 | // 68 | #define ALIGNED_POD(_size_) \ 69 | template<> struct AlignedPod<_size_> { \ 70 | __declspec(align(_size_)) struct type { char X[_size_]; }; \ 71 | enum { alignment = __alignof(type) }; }; \ 72 | STATIC_CHECK((_size_ == sizeof(AlignedPod<_size_>::type)), SizeofNotEqualSize); \ 73 | STATIC_CHECK((_size_ == (AlignedPod<_size_>::alignment)), SizeofNotEqualAlignof) 74 | 75 | 76 | ALIGNED_POD(1); 77 | ALIGNED_POD(2); 78 | ALIGNED_POD(4); 79 | ALIGNED_POD(8); 80 | ALIGNED_POD(16); 81 | ALIGNED_POD(32); 82 | ALIGNED_POD(64); 83 | ALIGNED_POD(128); 84 | // can be up to 8192 - is it realistic? 85 | 86 | #undef ALIGNED_POD 87 | 88 | }; 89 | 90 | 91 | //////////////////////////////////////////////////////////////////////////////// 92 | // class template VC_AlignedPOD 93 | // Computes the alignment of all types in a typelist 94 | //////////////////////////////////////////////////////////////////////////////// 95 | 96 | template 97 | class VC_AlignedPOD : VC_AlignedPODBase 98 | { 99 | enum { maxAlign = VC_MaxAlign::result }; 100 | 101 | public: 102 | typedef typename AlignedPod::type Result; 103 | }; 104 | 105 | #endif // VC_ALIGNMENT_INC_ 106 | 107 | -------------------------------------------------------------------------------- /MSVC/1300/portby.txt: -------------------------------------------------------------------------------- 1 | MSVC7 2 | Rani Sharoni -------------------------------------------------------------------------------- /MSVC/1300/readme.txt: -------------------------------------------------------------------------------- 1 | Last update: May 19, 2002 2 | 3 | Directions: 4 | 5 | To use Loki, simply extract the files from the archive, give your compiler access to their path, and include them appropriately in your code via #include. 6 | 7 | If you use the small object allocator directly or indirectly (through the Functor class) you must add SmallObj.cpp to your project/makefile. 8 | 9 | If you use Singletons with longevity you must add Singleton.cpp to your project/makefile. 10 | 11 | Compatibility: 12 | This is ported version of Loki to VC.NET (VC7 - 9466) it is only targeted for this compiler. 13 | To compile your sources with the original Loki you'll have to place it in a separate directory. 14 | 15 | More info: 16 | 17 | http://moderncppdesign.com 18 | http://www.geocities.com/rani_sharoni/LokiPort.html 19 | -------------------------------------------------------------------------------- /MSVC/1300/static_check.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Welsey Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef STATIC_CHECK_INC_ 19 | #define STATIC_CHECK_INC_ 20 | 21 | namespace Loki 22 | { 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // Helper structure for the STATIC_CHECK macro 25 | //////////////////////////////////////////////////////////////////////////////// 26 | 27 | template 28 | struct CompileTimeError; 29 | 30 | template<> 31 | struct CompileTimeError 32 | { 33 | typedef void type; 34 | }; 35 | } 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // macro STATIC_CHECK 39 | // Invocation: STATIC_CHECK(expr, id) 40 | // where: 41 | // expr is a compile-time integral or pointer expression 42 | // id is a C++ identifier that does not need to be defined 43 | // If expr is zero, id will appear in a compile-time error message. 44 | //////////////////////////////////////////////////////////////////////////////// 45 | 46 | #define STATIC_CHECK(expr, msg) \ 47 | typedef char ERROR_##msg[1][(expr)] 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // Change log: 51 | // March 20, 2001: add extra parens to STATIC_CHECK - it looked like a fun 52 | // definition 53 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 54 | // July 09, 2002: improved for favor of VC diagnostic and usage 55 | //////////////////////////////////////////////////////////////////////////////// 56 | 57 | #endif // STATIC_CHECK_INC_ 58 | -------------------------------------------------------------------------------- /MultiMethods.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////// 2 | // Generated header: MultiMethods.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | //////////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/MultiMethods.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/MultiMethods.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/MultiMethods.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/MultiMethods.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/MultiMethods.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/MultiMethods.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/MultiMethods.h" 23 | # else 24 | # include "Reference/MultiMethods.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /NullType.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////// 2 | // Generated header: NullType.h 3 | // Forwards to the appropriate code 4 | // that works on the detected compiler 5 | // Generated on Mon Sep 30 23:14:48 2002 6 | //////////////////////////////// 7 | 8 | #ifdef LOKI_USE_REFERENCE 9 | # include "Reference/NullType.h" 10 | #else 11 | # if (__INTEL_COMPILER) 12 | # include "Reference/NullType.h" 13 | # elif (__MWERKS__) 14 | # include "Reference/NullType.h" 15 | # elif (__BORLANDC__ >= 0x560) 16 | # include "Borland/NullType.h" 17 | # elif (_MSC_VER >= 1301) 18 | # include "Reference/NullType.h" 19 | # elif (_MSC_VER >= 1300) 20 | # include "MSVC/1300/NullType.h" 21 | # elif (_MSC_VER >= 1200) 22 | # include "MSVC/1200/NullType.h" 23 | # else 24 | # include "Reference/NullType.h" 25 | # endif 26 | #endif 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Loki 2 | ==== 3 | 4 | A C++ Template library, developed by Andrei Alexandrescu, the author of the book _Modern C++ Design_. 5 | 6 | Source code in this project is tied to _Modern C++ Design_. For the mostly recent updates, please refer to the official project in SourceForge.net: http://sourceforge.net/projects/loki-lib/files/Loki/ 7 | 8 | The purpose to create this repository is just to do experiments in _Modern C++ Design_. 9 | 10 | Quotation from the original readme.txt 11 | ==== 12 | 13 | Last update: Aug 29, 2002 14 | 15 | Directions: 16 | 17 | To use Loki, simply extract the files from the archive, give your compiler access to their path, and include them appropriately in your code via #include. 18 | 19 | If you use the small object allocator directly or indirectly (through the Functor class) you must add SmallObj.cpp to your project/makefile. 20 | 21 | If you use Singletons with longevity you must add Singleton.cpp to your project/makefile. 22 | 23 | 24 | Compatibility: 25 | 26 | Supported Compilers: 27 | Gcc v2.95.3 28 | Microsoft Visual C++ v7.0 29 | Borland C++ Builder v6.0 30 | 31 | Mostly Supported: 32 | CodeWarrior 6.0 33 | 34 | TypeList: 35 | Microsoft Visual C++ v6.0 36 | 37 | 38 | CodeWarrior has a problem with the Conversion template (see TypeManip.h) and, though it compiles it, it doesn't provide correct results. Consequently, the DerivedToFront algorithm in Typelist.h does not function. This affects the static dispatcher in Multimethods.h. As a fix, you must order the types (putting the most derived ones in the front) when providing the typelist argument to StaticDispatcher. 39 | 40 | 41 | 42 | More info: 43 | 44 | http://moderncppdesign.com 45 | 46 | http://sourceforge.net/projects/loki-lib/ 47 | 48 | http://sourceforge.net/projects/loki-exp/ 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Reference/AbstractFactory.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Copyright (c) 2001 by Andrei Alexandrescu 4 | // This code accompanies the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // Permission to use, copy, modify, distribute and sell this software for any 8 | // purpose is hereby granted without fee, provided that the above copyright 9 | // notice appear in all copies and that both that copyright notice and this 10 | // permission notice appear in supporting documentation. 11 | // The author or Addison-Wesley Longman make no representations about the 12 | // suitability of this software for any purpose. It is provided "as is" 13 | // without express or implied warranty. 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | // Last update: June 20, 2001 17 | 18 | #ifndef ABSTRACTFACTORY_INC_ 19 | #define ABSTRACTFACTORY_INC_ 20 | 21 | #include "Typelist.h" 22 | #include "TypeManip.h" 23 | #include "HierarchyGenerators.h" 24 | 25 | #include 26 | 27 | namespace Loki 28 | { 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // class template AbstractFactoryUnit 32 | // The building block of an Abstract Factory 33 | //////////////////////////////////////////////////////////////////////////////// 34 | 35 | template 36 | class AbstractFactoryUnit 37 | { 38 | public: 39 | virtual T* DoCreate(Type2Type) = 0; 40 | virtual ~AbstractFactoryUnit() {} 41 | }; 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // class template AbstractFactory 45 | // Defines an Abstract Factory interface starting from a typelist 46 | //////////////////////////////////////////////////////////////////////////////// 47 | 48 | template 49 | < 50 | class TList, 51 | template class Unit = AbstractFactoryUnit 52 | > 53 | class AbstractFactory : public GenScatterHierarchy 54 | { 55 | public: 56 | typedef TList ProductList; 57 | 58 | template T* Create() 59 | { 60 | Unit& unit = *this; 61 | return unit.DoCreate(Type2Type()); 62 | } 63 | }; 64 | 65 | //////////////////////////////////////////////////////////////////////////////// 66 | // class template OpNewFactoryUnit 67 | // Creates an object by invoking the new operator 68 | //////////////////////////////////////////////////////////////////////////////// 69 | 70 | template 71 | class OpNewFactoryUnit : public Base 72 | { 73 | typedef typename Base::ProductList BaseProductList; 74 | 75 | protected: 76 | typedef typename BaseProductList::Tail ProductList; 77 | 78 | public: 79 | typedef typename BaseProductList::Head AbstractProduct; 80 | ConcreteProduct* DoCreate(Type2Type) 81 | { 82 | return new ConcreteProduct; 83 | } 84 | }; 85 | 86 | //////////////////////////////////////////////////////////////////////////////// 87 | // class template PrototypeFactoryUnit 88 | // Creates an object by cloning a prototype 89 | // There is a difference between the implementation herein and the one described 90 | // in the book: GetPrototype and SetPrototype use the helper friend 91 | // functions DoGetPrototype and DoSetPrototype. The friend functions avoid 92 | // name hiding issues. Plus, GetPrototype takes a reference to pointer 93 | // instead of returning the pointer by value. 94 | //////////////////////////////////////////////////////////////////////////////// 95 | 96 | template 97 | class PrototypeFactoryUnit : public Base 98 | { 99 | typedef typename Base::ProductList BaseProductList; 100 | 101 | protected: 102 | typedef typename BaseProductList::Tail ProductList; 103 | 104 | public: 105 | typedef typename BaseProductList::Head AbstractProduct; 106 | 107 | PrototypeFactoryUnit(AbstractProduct* p = 0) 108 | : pPrototype_(p) 109 | {} 110 | 111 | friend void DoGetPrototype(const PrototypeFactoryUnit& me, 112 | AbstractProduct*& pPrototype) 113 | { pPrototype = me.pPrototype_; } 114 | 115 | friend void DoSetPrototype(PrototypeFactoryUnit& me, 116 | AbstractProduct* pObj) 117 | { me.pPrototype_ = pObj; } 118 | 119 | template 120 | void GetPrototype(U*& p) 121 | { return DoGetPrototype(*this, p); } 122 | 123 | template 124 | void SetPrototype(U* pObj) 125 | { DoSetPrototype(*this, pObj); } 126 | 127 | AbstractProduct* DoCreate(Type2Type) 128 | { 129 | assert(pPrototype_); 130 | return pPrototype_->Clone(); 131 | } 132 | 133 | private: 134 | AbstractProduct* pPrototype_; 135 | }; 136 | 137 | //////////////////////////////////////////////////////////////////////////////// 138 | // class template ConcreteFactory 139 | // Implements an AbstractFactory interface 140 | //////////////////////////////////////////////////////////////////////////////// 141 | 142 | template 143 | < 144 | class AbstractFact, 145 | template class Creator = OpNewFactoryUnit, 146 | class TList = typename AbstractFact::ProductList 147 | > 148 | class ConcreteFactory 149 | : public GenLinearHierarchy< 150 | typename TL::Reverse::Result, Creator, AbstractFact> 151 | { 152 | public: 153 | typedef typename AbstractFact::ProductList ProductList; 154 | typedef TList ConcreteProductList; 155 | }; 156 | 157 | } // namespace Loki 158 | 159 | //////////////////////////////////////////////////////////////////////////////// 160 | // Change log: 161 | // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! 162 | // September 25, 2004: Fixed bug in PrototypeFactoryUnit::GetPrototype, thanks 163 | // to a bug report submitted by funcall. 164 | //////////////////////////////////////////////////////////////////////////////// 165 | 166 | #endif // ABSTRACTFACTORY_INC_ 167 | -------------------------------------------------------------------------------- /Reference/DataGenerators.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // The Loki Library 3 | // Data Generator by Shannon Barber 4 | // This code DOES NOT accompany the book: 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 6 | // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 7 | // 8 | // Code covered by the MIT License 9 | // The author makes no representations about the suitability of this software 10 | // for any purpose. It is provided "as is" without express or implied warranty. 11 | //////////////////////////////////////////////////////////////////////////////// 12 | 13 | // Last update: Oct 10, 2002 14 | 15 | #ifndef DATAGENERATORS_H 16 | #define DATAGENERATORS_H 17 | #include "Typelist.h" 18 | 19 | //Reference version 20 | 21 | /************************************************************************************ 22 | // class template GenData 23 | // Iteratates a Typelist, and invokes the functor GenFunc 24 | // for each type in the list, passing a functor along the way. 25 | // The functor is designed to be an insertion iterator which GenFunc 26 | // can use to output information about the types in the list. 27 | // 28 | 29 | Example Use 30 | 31 | template 32 | struct ExtractDataType 33 | { 34 | some_type operator()() 35 | { 36 | return create_value_from_type; 37 | } 38 | }; 39 | 40 | Loki::IterateTypes gendata; 41 | std::vector stuff; 42 | gendata(std::back_inserter(stuff)); 43 | *******************************************************************************/ 44 | namespace Loki 45 | { 46 | namespace TL 47 | { 48 | template 49 | struct nameof_type 50 | { 51 | const char* operator()() 52 | { 53 | return typeid(T).name(); 54 | } 55 | }; 56 | template 57 | struct sizeof_type 58 | { 59 | size_t operator()() 60 | { 61 | return sizeof(T); 62 | } 63 | }; 64 | template class GenFunc> 65 | struct IterateTypes; 66 | 67 | template class GenFunc> 68 | struct IterateTypes, GenFunc> 69 | { 70 | typedef IterateTypes head_t; 71 | head_t head; 72 | typedef IterateTypes tail_t; 73 | tail_t tail; 74 | template 75 | void operator()(II ii) 76 | { 77 | head.operator()(ii); 78 | tail.operator()(ii); 79 | } 80 | }; 81 | 82 | template class GenFunc> 83 | struct IterateTypes 84 | { 85 | template 86 | void operator()(II ii) 87 | { 88 | GenFunc genfunc; 89 | *ii = genfunc(); 90 | ++ii; //Is this even needed? 91 | } 92 | }; 93 | 94 | template