From 65396373572cb64fe49c906f54ea87addae00339 Mon Sep 17 00:00:00 2001 From: tslettebo Date: Mon, 6 Jan 2003 02:18:31 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@85 7ec92016-0320-0410-acc4-a06ded1c099a --- MSVC/1200/AssocVector.h | 335 ----------------- MSVC/1200/EmptyType.h | 37 -- MSVC/1200/Factory.h | 153 -------- MSVC/1200/NullType.h | 39 -- MSVC/1200/Singleton.cpp | 53 --- MSVC/1200/Singleton.h | 499 ------------------------- MSVC/1200/Threads.h | 213 ----------- MSVC/1200/TypeInfo.h | 106 ------ MSVC/1200/TypeManip.h | 302 --------------- MSVC/1200/TypeTraits.h | 374 ------------------- MSVC/1200/Typelist.h | 788 ---------------------------------------- 11 files changed, 2899 deletions(-) delete mode 100644 MSVC/1200/AssocVector.h delete mode 100644 MSVC/1200/EmptyType.h delete mode 100644 MSVC/1200/Factory.h delete mode 100644 MSVC/1200/NullType.h delete mode 100644 MSVC/1200/Singleton.cpp delete mode 100644 MSVC/1200/Singleton.h delete mode 100644 MSVC/1200/Threads.h delete mode 100644 MSVC/1200/TypeInfo.h delete mode 100644 MSVC/1200/TypeManip.h delete mode 100644 MSVC/1200/TypeTraits.h delete mode 100644 MSVC/1200/Typelist.h diff --git a/MSVC/1200/AssocVector.h b/MSVC/1200/AssocVector.h deleted file mode 100644 index 2b4386e..0000000 --- a/MSVC/1200/AssocVector.h +++ /dev/null @@ -1,335 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -#ifndef ASSOCVECTOR_INC_ -#define ASSOCVECTOR_INC_ - -#include -#include -#include -#include - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template AssocVectorCompare -// Used by AssocVector -//////////////////////////////////////////////////////////////////////////////// - - namespace Private - { - template - class AssocVectorCompare : public C - { - typedef std::pair - Data; - typedef typename C::first_argument_type first_argument_type; - - public: - AssocVectorCompare() - {} - - AssocVectorCompare(const C& src) : C(src) - {} - - bool operator()(const first_argument_type& lhs, - const first_argument_type& rhs) const - { return C::operator()(lhs, rhs); } - - bool operator()(const Data& lhs, const Data& rhs) const - { return operator()(lhs.first, rhs.first); } - - bool operator()(const Data& lhs, - const first_argument_type& rhs) const - { return operator()(lhs.first, rhs); } - - bool operator()(const first_argument_type& lhs, - const Data& rhs) const - { return operator()(lhs, rhs.first); } - }; - } - -//////////////////////////////////////////////////////////////////////////////// -// class template AssocVector -// An associative vector built as a syntactic drop-in replacement for std::map -// BEWARE: AssocVector doesn't respect all map's guarantees, the most important -// being: -// * iterators are invalidated by insert and erase operations -// * the complexity of insert/erase is O(N) not O(log N) -// * value_type is std::pair not std::pair -// * iterators are random -//////////////////////////////////////////////////////////////////////////////// - - template - < - class K, - class V, - class C = std::less, - class A = std::allocator< std::pair > - > - class AssocVector - : private std::vector< std::pair, A > - , private Private::AssocVectorCompare - { - typedef std::vector, A> Base; - typedef Private::AssocVectorCompare MyCompare; - - public: - typedef K key_type; - typedef V mapped_type; - typedef typename Base::value_type value_type; - - typedef C key_compare; - typedef A allocator_type; - typedef typename A::reference reference; - typedef typename A::const_reference const_reference; - typedef typename Base::iterator iterator; - typedef typename Base::const_iterator const_iterator; - typedef typename Base::size_type size_type; - typedef typename Base::difference_type difference_type; - typedef typename A::pointer pointer; - typedef typename A::const_pointer const_pointer; - typedef typename Base::reverse_iterator reverse_iterator; - typedef typename Base::const_reverse_iterator const_reverse_iterator; - - class value_compare - : public std::binary_function - , private key_compare - { - friend class AssocVector; - - protected: - value_compare(key_compare pred) : key_compare(pred) - {} - - public: - bool operator()(const value_type& lhs, const value_type& rhs) const - { return key_compare::operator()(lhs.first, rhs.first); } - }; - - // 23.3.1.1 construct/copy/destroy - - explicit AssocVector(const key_compare& comp = key_compare(), - const A& alloc = A()) - : Base(alloc), MyCompare(comp) - {} - - template - AssocVector(InputIterator first, InputIterator last, - const key_compare& comp = key_compare(), - const A& alloc = A()) - : Base(first, last, alloc), MyCompare(comp) - { - MyCompare& me = *this; - std::sort(begin(), end(), me); - } - - AssocVector& operator=(const AssocVector& rhs) - { - AssocVector(rhs).swap(*this); - return *this; - } - - // iterators: - // The following are here because MWCW gets 'using' wrong - iterator begin() { return Base::begin(); } - const_iterator begin() const { return Base::begin(); } - iterator end() { return Base::end(); } - const_iterator end() const { return Base::end(); } - reverse_iterator rbegin() { return Base::rbegin(); } - const_reverse_iterator rbegin() const { return Base::rbegin(); } - reverse_iterator rend() { return Base::rend(); } - const_reverse_iterator rend() const { return Base::rend(); } - - // capacity: - bool empty() const { return Base::empty(); } - size_type size() const { return Base::size(); } - size_type max_size() { return Base::max_size(); } - - // 23.3.1.2 element access: - mapped_type& operator[](const key_type& key) - { return insert(value_type(key, mapped_type())).first->second; } - - // modifiers: - std::pair insert(const value_type& val) - { - bool found(true); - iterator i(lower_bound(val.first)); - - if (i == end() || operator()(val.first, i->first)) - { - i = Base::insert(i, val); - found = false; - } - return std::make_pair(i, !found); - } - - iterator insert(iterator pos, const value_type& val) - { - if (pos != end() && operator()(*pos, val) && - (pos == end() - 1 || - !operator()(val, pos[1]) && - operator()(pos[1], val))) - { - return Base::insert(pos, val); - } - return insert(val).first; - } - - template - void insert(InputIterator first, InputIterator last) - { for (; first != last; ++first) insert(*first); } - - void erase(iterator pos) - { Base::erase(pos); } - - size_type erase(const key_type& k) - { - iterator i(find(k)); - if (i == end()) return 0; - erase(i); - return 1; - } - - void erase(iterator first, iterator last) - { Base::erase(first, last); } - - void swap(AssocVector& other) - { - using std::swap; - Base::swap(other); - MyCompare& me = *this; - MyCompare& rhs = other; - swap(me, rhs); - } - - void clear() - { Base::clear(); } - - // observers: - key_compare key_comp() const - { return *this; } - - value_compare value_comp() const - { - const key_compare& comp = *this; - return value_compare(comp); - } - - // 23.3.1.3 map operations: - iterator find(const key_type& k) - { - iterator i(lower_bound(k)); - if (i != end() && operator()(k, i->first)) - { - i = end(); - } - return i; - } - - const_iterator find(const key_type& k) const - { - const_iterator i(lower_bound(k)); - if (i != end() && operator()(k, i->first)) - { - i = end(); - } - return i; - } - - size_type count(const key_type& k) const - { return find(k) != end(); } - - iterator lower_bound(const key_type& k) - { - MyCompare& me = *this; - return std::lower_bound(begin(), end(), k, me); - } - - const_iterator lower_bound(const key_type& k) const - { - const MyCompare& me = *this; - return std::lower_bound(begin(), end(), k, me); - } - - iterator upper_bound(const key_type& k) - { - MyCompare& me = *this; - return std::upper_bound(begin(), end(), k, me); - } - - const_iterator upper_bound(const key_type& k) const - { - const MyCompare& me = *this; - return std::upper_bound(begin(), end(), k, me); - } - - std::pair equal_range(const key_type& k) - { - MyCompare& me = *this; - return std::equal_range(begin(), end(), k, me); - } - - std::pair equal_range( - const key_type& k) const - { - const MyCompare& me = *this; - return std::equal_range(begin(), end(), k, me); - } - - friend bool operator==(const AssocVector& lhs, const AssocVector& rhs) - { - const Base& me = lhs; - return me == rhs; - } - - bool operator<(const AssocVector& rhs) const - { - const Base& me = *this; - const Base& yo = rhs; - return me < yo; - } - - friend bool operator!=(const AssocVector& lhs, const AssocVector& rhs) - { return !(lhs == rhs); } - - friend bool operator>(const AssocVector& lhs, const AssocVector& rhs) - { return rhs < lhs; } - - friend bool operator>=(const AssocVector& lhs, const AssocVector& rhs) - { return !(lhs < rhs); } - - friend bool operator<=(const AssocVector& lhs, const AssocVector& rhs) - { return !(rhs < lhs); } - }; - - // specialized algorithms: - template - void swap(AssocVector& lhs, AssocVector& rhs) - { lhs.swap(rhs); } - -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// May 20, 2001: change operator= - credit due to Cristoph Koegl -// June 11, 2001: remove paren in equal_range - credit due to Cristoph Koegl -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// January 22, 2002: fixed operator= - credit due to Tom Hyer -// June 25, 2002: fixed template insert() - credit due to Robert Minsk -// June 27, 2002: fixed member swap() - credit due to David Brookman -//////////////////////////////////////////////////////////////////////////////// - -#endif // ASSOCVECTOR_INC_ diff --git a/MSVC/1200/EmptyType.h b/MSVC/1200/EmptyType.h deleted file mode 100644 index e8ffb17..0000000 --- a/MSVC/1200/EmptyType.h +++ /dev/null @@ -1,37 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: June 20, 2001 - -#ifndef EMPTYTYPE_INC_ -#define EMPTYTYPE_INC_ - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class EmptyType -// Used as a class type that doesn't hold anything -// Useful as a strawman class -//////////////////////////////////////////////////////////////////////////////// - - class EmptyType {}; -} - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -//////////////////////////////////////////////////////////////////////////////// - -#endif // EMPTYTYPE_INC_ diff --git a/MSVC/1200/Factory.h b/MSVC/1200/Factory.h deleted file mode 100644 index d72416b..0000000 --- a/MSVC/1200/Factory.h +++ /dev/null @@ -1,153 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: October 12, 2002 - -#ifndef FACTORY_INC_ -#define FACTORY_INC_ - -#include "TypeInfo.h" -#include "AssocVector.h" -#include - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -// class DefaultFactoryError -// Manages the "Unknown Type" error in an object factory -//////////////////////////////////////////////////////////////////////////////// - - struct DefaultFactoryError - { - - struct Exception : public std::exception - { - const char* what() const throw() { return "Unknown Type"; } - }; - - template - static AbstractProduct* OnUnknownType(IdentifierType,AbstractProduct *) - { - throw Exception(); - } - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template Factory -// Implements a generic object factory -//////////////////////////////////////////////////////////////////////////////// - - template - < - class AbstractProduct, - typename IdentifierType, - typename ProductCreator = AbstractProduct* (*)(), - class FactoryErrorPolicy = DefaultFactoryError - > - class Factory - : public FactoryErrorPolicy - { - public: - bool Register(const IdentifierType& id, ProductCreator creator) - { - return associations_.insert( - IdToProductMap::value_type(id, creator)).second; - } - - bool Unregister(const IdentifierType& id) - { - return associations_.erase(id) == 1; - } - - AbstractProduct* CreateObject(const IdentifierType& id) - { - typename IdToProductMap::iterator i = associations_.find(id); - if (i != associations_.end()) - { - return (i->second)(); - } - - AbstractProduct *dummy; - - return OnUnknownType(id,dummy); - } - - private: - typedef AssocVector IdToProductMap; - IdToProductMap associations_; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template CloneFactory -// Implements a generic cloning factory -//////////////////////////////////////////////////////////////////////////////// - - template - < - class AbstractProduct, - class ProductCreator = - AbstractProduct* (*)(const AbstractProduct*), - typename FactoryErrorPolicy = DefaultFactoryError - > - class CloneFactory - : public FactoryErrorPolicy - { - public: - bool Register(const TypeInfo& ti, ProductCreator creator) - { - return associations_.insert( - IdToProductMap::value_type(ti, creator)).second; - } - - bool Unregister(const TypeInfo& id) - { - return associations_.erase(id) == 1; - } - - AbstractProduct* CreateObject(const AbstractProduct* model) - { - if (model == 0) return 0; - - typename IdToProductMap::iterator i = - associations_.find(typeid(*model)); - if (i != associations_.end()) - { - return (i->second)(model); - } - - AbstractProduct *dummy; - - return OnUnknownType(TypeInfo(typeid(*model)),dummy); - } - - private: - typedef AssocVector IdToProductMap; - IdToProductMap associations_; - }; -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// May 08, 2002: replaced const_iterator with iterator so that self-modifying -// ProductCreators are supported. Also, added a throw() spec to what(). -// Credit due to Jason Fischl. -// October 12, 2002: Ported to MSVC 6 by Terje Slettebų. Interface for Factory -// and CloneFactory changed from using template template parameter, -// to using class with member template, for the FactoryErrorPolicy. -//////////////////////////////////////////////////////////////////////////////// - -#endif // FACTORY_INC_ diff --git a/MSVC/1200/NullType.h b/MSVC/1200/NullType.h deleted file mode 100644 index c2f31be..0000000 --- a/MSVC/1200/NullType.h +++ /dev/null @@ -1,39 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: November 22, 2001 - -#ifndef NULLTYPE_INC_ -#define NULLTYPE_INC_ - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class NullType -// Used as a placeholder for "no type here" -// Useful as an end marker in typelists -//////////////////////////////////////////////////////////////////////////////// - - class NullType {}; - -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// November 22, 2001: minor change to support porting to boost -//////////////////////////////////////////////////////////////////////////////// - -#endif // NULLTYPE_INC_ diff --git a/MSVC/1200/Singleton.cpp b/MSVC/1200/Singleton.cpp deleted file mode 100644 index 6be0957..0000000 --- a/MSVC/1200/Singleton.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: June 20, 2001 - -#include "Singleton.h" - -using namespace Loki::Private; - -Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0; -unsigned int Loki::Private::elements = 0; - -//////////////////////////////////////////////////////////////////////////////// -// function AtExitFn -// Ensures proper destruction of objects with longevity -//////////////////////////////////////////////////////////////////////////////// - -void Loki::Private::AtExitFn() -{ - assert(elements > 0 && pTrackerArray != 0); - // Pick the element at the top of the stack - LifetimeTracker* pTop = pTrackerArray[elements - 1]; - // Remove that object off the stack - // Don't check errors - realloc with less memory - // can't fail - pTrackerArray = static_cast(realloc( - pTrackerArray, sizeof(*pTrackerArray) * --elements)); - // Destroy the element - delete pTop; -} - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// January 10, 2002: Fixed bug in call to realloc - credit due to Nigel Gent and -// Eike Petersen -// May 08, 2002: Refixed bug in call to realloc -// October 12, 2002: Ported to MSVC 6 by Terje Slettebų. -// Interface for SingletonHolder changed from using template template -// parameters, to using classes with member templates. -//////////////////////////////////////////////////////////////////////////////// diff --git a/MSVC/1200/Singleton.h b/MSVC/1200/Singleton.h deleted file mode 100644 index 775d409..0000000 --- a/MSVC/1200/Singleton.h +++ /dev/null @@ -1,499 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -#ifndef SINGLETON_INC_ -#define SINGLETON_INC_ - -#include "Threads.h" -#include -#include -#include -#include -#include - -namespace Loki -{ - namespace Private - { - template< typename T > - struct MSVCNeverTrue - { - enum { value = false }; - }; - - template - struct Apply - { - #ifdef _MSC_VER - // based on the (non-conforming) MSVC trick from MPL - - template - struct MetaFunctionWrapper_VC : MetaFunctionWrapper {}; - - //illegal C++ which causes VC to admit that MetaFunctionWrapper_VC - //can have a nested template: - - template<> - struct MetaFunctionWrapper_VC - {template struct VolatileType; }; - - typedef typename MetaFunctionWrapper_VC< - MSVCNeverTrue::value - >::template VolatileType::Result Result; - #else - typedef typename MetaFunctionWrapper::template VolatileType::Result Result; - #endif - }; - -//////////////////////////////////////////////////////////////////////////////// -// class LifetimeTracker -// Helper class for SetLongevity -//////////////////////////////////////////////////////////////////////////////// - - class LifetimeTracker - { - public: - LifetimeTracker(unsigned int x) : longevity_(x) - {} - - virtual ~LifetimeTracker() = 0; - - static bool Compare(const LifetimeTracker* lhs, - const LifetimeTracker* rhs) - { - return lhs->longevity_ > rhs->longevity_; - } - - private: - unsigned int longevity_; - }; - - // Definition required - inline LifetimeTracker::~LifetimeTracker() {} - - // Helper data - typedef LifetimeTracker** TrackerArray; - extern TrackerArray pTrackerArray; - extern unsigned int elements; - - // Helper destroyer function - template - struct Deleter - { - static void Delete(T* pObj) - { delete pObj; } - }; - - // Concrete lifetime tracker for objects of type T - template - class ConcreteLifetimeTracker : public LifetimeTracker - { - public: - ConcreteLifetimeTracker(T* p,unsigned int longevity, Destroyer d) - : LifetimeTracker(longevity) - , pTracked_(p) - , destroyer_(d) - {} - - ~ConcreteLifetimeTracker() - { destroyer_(pTracked_); } - - private: - T* pTracked_; - Destroyer destroyer_; - }; - - void AtExitFn(); // declaration needed below - - } // namespace Private - -//////////////////////////////////////////////////////////////////////////////// -// function template SetLongevity -// Assigns an object a longevity; ensures ordered destructions of objects -// registered thusly during the exit sequence of the application -//////////////////////////////////////////////////////////////////////////////// - - template - void SetLongevity(T* pDynObject, unsigned int longevity, - Destroyer d = Private::Deleter::Delete) - { - using namespace Private; - - TrackerArray pNewArray = static_cast( - realloc(pTrackerArray, - sizeof(*pTrackerArray) * (elements + 1))); - if (!pNewArray) throw std::bad_alloc(); - - // Delayed assignment for exception safety - pTrackerArray = pNewArray; - - LifetimeTracker* p = new ConcreteLifetimeTracker( - pDynObject, longevity, d); - - // Insert a pointer to the object into the queue - TrackerArray pos = std::upper_bound( - pTrackerArray, - pTrackerArray + elements, - p, - LifetimeTracker::Compare); - std::copy_backward( - pos, - pTrackerArray + elements, - pTrackerArray + elements + 1); - *pos = p; - ++elements; - - // Register a call to AtExitFn - atexit(Private::AtExitFn); - } - -//////////////////////////////////////////////////////////////////////////////// -// class template CreateUsingNew -// Implementation of the CreationPolicy used by SingletonHolder -// Creates objects using a straight call to the new operator -//////////////////////////////////////////////////////////////////////////////// - - struct CreateUsingNew - { - template - static T* Create(T*) - { return new T; } - - template - static void Destroy(T* p) - { delete p; } - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template CreateUsingNew -// Implementation of the CreationPolicy used by SingletonHolder -// Creates objects using a call to std::malloc, followed by a call to the -// placement new operator -//////////////////////////////////////////////////////////////////////////////// - - struct CreateUsingMalloc - { - - template - static T* Create(T*) - { - void* p = malloc(sizeof(T)); - if (!p) return 0; - return new(p) T; - } - - template - static void Destroy(T* p) - { - p->~T(); - free(p); - } - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template CreateStatic -// Implementation of the CreationPolicy used by SingletonHolder -// Creates an object in static memory -// Implementation is slightly nonportable because it uses the MaxAlign trick -// (an union of all types to ensure proper memory alignment). This trick is -// nonportable in theory but highly portable in practice. -//////////////////////////////////////////////////////////////////////////////// - - struct CreateStatic - { - template - static T* Create(T*) - { - union MaxAlign - { - char t_[sizeof(T)]; - short int shortInt_; - int int_; - long int longInt_; - float float_; - double double_; - long double longDouble_; - struct Test; - int Test::* pMember_; - int (Test::*pMemberFn_)(int); - }; - - static MaxAlign staticMemory_; - return new(&staticMemory_) T; - } - - template - static void Destroy(T* p) - { - p->~T(); - } - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template DefaultLifetime -// Implementation of the LifetimePolicy used by SingletonHolder -// Schedules an object's destruction as per C++ rules -// Forwards to std::atexit -//////////////////////////////////////////////////////////////////////////////// - - struct DefaultLifetime - { - template - static void ScheduleDestruction(T*, void (*pFun)()) - { atexit(pFun); } - - template - static void OnDeadReference(T*) - { throw std::exception("Dead Reference Detected"); } - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template PhoenixSingleton -// Implementation of the LifetimePolicy used by SingletonHolder -// Schedules an object's destruction as per C++ rules, and it allows object -// recreation by not throwing an exception from OnDeadReference -//////////////////////////////////////////////////////////////////////////////// - - class PhoenixSingleton - { - public: - template - static void ScheduleDestruction(T*, void (*pFun)()) - { -#ifndef ATEXIT_FIXED - if (!destroyedOnce_) -#endif - atexit(pFun); - } - - template - static void OnDeadReference(T*) - { -#ifndef ATEXIT_FIXED - destroyedOnce_ = true; -#endif - } - - private: -#ifndef ATEXIT_FIXED - static bool destroyedOnce_; -#endif - }; - -#ifndef ATEXIT_FIXED - bool PhoenixSingleton::destroyedOnce_ = false; -#endif - -//////////////////////////////////////////////////////////////////////////////// -// class template Adapter -// Helper for SingletonWithLongevity below -//////////////////////////////////////////////////////////////////////////////// - - namespace Private - { - template - struct Adapter - { - void operator()(T*) { pFun_(); } - void (*pFun_)(); - }; - } - -//////////////////////////////////////////////////////////////////////////////// -// class template SingletonWithLongevity -// Implementation of the LifetimePolicy used by SingletonHolder -// Schedules an object's destruction in order of their longevities -// Assumes a visible function GetLongevity(T*) that returns the longevity of the -// object -//////////////////////////////////////////////////////////////////////////////// - - class SingletonWithLongevity - { - public: - template - static void ScheduleDestruction(T* pObj, void (*pFun)()) - { - Private::Adapter adapter = { pFun }; - SetLongevity(pObj, GetLongevity(pObj), adapter); - } - - template - static void OnDeadReference(T*) - { throw std::exception("Dead Reference Detected"); } - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template NoDestroy -// Implementation of the LifetimePolicy used by SingletonHolder -// Never destroys the object -//////////////////////////////////////////////////////////////////////////////// - - struct NoDestroy - { - template - static void ScheduleDestruction(T*, void (*)()) - {} - - template - static void OnDeadReference(T*) - {} - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template SingletonHolder -// Provides Singleton amenities for a type T -// To protect that type from spurious instantiations, you have to protect it -// yourself. -//////////////////////////////////////////////////////////////////////////////// - - template - < - typename T, - class CreationPolicy = CreateUsingNew, - class LifetimePolicy = DefaultLifetime, - class ThreadingModel = SingleThreaded - > - class SingletonHolder - { - public: - static T& Instance(); - - private: - // Helpers - static void MakeInstance(); - static void DestroySingleton(); - - // Protection - SingletonHolder(); - - // Data - typedef typename Private::Apply::Result PtrInstanceType; - -// typedef typename ThreadingModel::VolatileType::Result PtrInstanceType; - static PtrInstanceType pInstance_; - static bool destroyed_; - }; - -//////////////////////////////////////////////////////////////////////////////// -// SingletonHolder's data -//////////////////////////////////////////////////////////////////////////////// - - template - < - class T, - class C, - class L, - class M - > - typename SingletonHolder::PtrInstanceType - SingletonHolder::pInstance_; - - template - < - class T, - class C, - class L, - class M - > - bool SingletonHolder::destroyed_; - -//////////////////////////////////////////////////////////////////////////////// -// SingletonHolder::Instance -//////////////////////////////////////////////////////////////////////////////// - - template - < - class T, - class CreationPolicy, - class LifetimePolicy, - class ThreadingModel - > - inline T& SingletonHolder::Instance() - { - if (!pInstance_) - { - MakeInstance(); - } - return *pInstance_; - } - -//////////////////////////////////////////////////////////////////////////////// -// SingletonHolder::MakeInstance (helper for Instance) -//////////////////////////////////////////////////////////////////////////////// - - template - < - class T, - class CreationPolicy, - class LifetimePolicy, - class ThreadingModel - > - void SingletonHolder::MakeInstance() - { - typename ThreadingModel::Lock guard; - (void)guard; - - if (!pInstance_) - { - if (destroyed_) - { - T* dummy; - - LifetimePolicy::OnDeadReference(dummy); - destroyed_ = false; - } - - T* dummy; - - pInstance_ = CreationPolicy::Create(dummy); - LifetimePolicy::ScheduleDestruction(pInstance_, - &DestroySingleton); - } - } - - template - < - class T, - class CreationPolicy, - class L, - class M - > - void SingletonHolder::DestroySingleton() - { - assert(!destroyed_); - CreationPolicy::Destroy(pInstance_); - pInstance_ = 0; - destroyed_ = true; - } -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// May 21, 2001: Correct the volatile qualifier - credit due to Darin Adler -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// January 08, 2002: Fixed bug in call to realloc - credit due to Nigel Gent and -// Eike Petersen -// March 08, 2002: moved the assignment to pTrackerArray in SetLongevity to fix -// exception safety issue. Credit due to Kari Hoijarvi -// May 09, 2002: Fixed bug in Compare that caused longevities to act backwards. -// Credit due to Scott McDonald. -// October 12, 2002: Ported to MSVC 6 by Terje Slettebų. -// Interface for SingletonHolder changed from using template template -// parameters, to using classes with member templates. -//////////////////////////////////////////////////////////////////////////////// - -#endif // SINGLETON_INC_ diff --git a/MSVC/1200/Threads.h b/MSVC/1200/Threads.h deleted file mode 100644 index d45b5df..0000000 --- a/MSVC/1200/Threads.h +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef THREADS_H_ -#define THREADS_H_ - -//////////////////////////////////////////////////////////////////////////////// -// macro DEFAULT_THREADING -// Selects the default threading model for certain components of Loki -// If you don't define it, it defaults to single-threaded -// All classes in Loki have configurable threading model; DEFAULT_THREADING -// affects only default template arguments -//////////////////////////////////////////////////////////////////////////////// - -// Last update: June 20, 2001 - -#ifndef DEFAULT_THREADING -#define DEFAULT_THREADING /**/ ::Loki::SingleThreaded -#endif - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template SingleThreaded -// Implementation of the ThreadingModel policy used by various classes -// Implements a single-threaded model; no synchronization -//////////////////////////////////////////////////////////////////////////////// - - class SingleThreaded - { - public: - template - struct Lock - { - Lock() {} - Lock(const Host&) {} - }; - - template - struct VolatileType - { - typedef Host Result; - }; - - typedef int IntType; - - static IntType AtomicAdd(volatile IntType& lval, IntType val) - { return lval += val; } - - static IntType AtomicSubtract(volatile IntType& lval, IntType val) - { return lval -= val; } - - static IntType AtomicMultiply(volatile IntType& lval, IntType val) - { return lval *= val; } - - static IntType AtomicDivide(volatile IntType& lval, IntType val) - { return lval /= val; } - - static IntType AtomicIncrement(volatile IntType& lval) - { return ++lval; } - - static IntType AtomicDecrement(volatile IntType& lval) - { return --lval; } - - static void AtomicAssign(volatile IntType & lval, IntType val) - { lval = val; } - - static void AtomicAssign(IntType & lval, volatile IntType & val) - { lval = val; } - }; - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) - -#include - -//////////////////////////////////////////////////////////////////////////////// -// class template ObjectLevelLockable -// Implementation of the ThreadingModel policy used by various classes -// Implements a object-level locking scheme -//////////////////////////////////////////////////////////////////////////////// - - class ObjectLevelLockable - { - CRITICAL_SECTION mtx_; - - public: - ObjectLevelLockable() - { - InitializeCriticalSection(&mtx_); - } - - ~ObjectLevelLockable() - { - DeleteCriticalSection(&mtx_); - } - - template - class Lock - { - ObjectLevelLockable& host_; - - Lock(const Lock&); - Lock& operator=(const Lock&); - public: - Lock(Host& host) : host_(host) - { - ::EnterCriticalSection(&host_.mtx_); - } - ~Lock() - { - ::LeaveCriticalSection(&host_.mtx_); - } - }; - - template - struct VolatileType - { - typedef volatile Host Result; - }; - - typedef LONG IntType; - - static IntType AtomicIncrement(volatile IntType& lval) - { return InterlockedIncrement(&const_cast(lval)); } - - static IntType AtomicDecrement(volatile IntType& lval) - { return InterlockedDecrement(&const_cast(lval)); } - - static void AtomicAssign(volatile IntType& lval, IntType val) - { InterlockedExchange(&const_cast(lval), val); } - - static void AtomicAssign(IntType& lval, volatile IntType& val) - { InterlockedExchange(&lval, val); } - }; - - class ClassLevelLockable - { - struct Initializer; - friend struct Initializer; - struct Initializer - { - Initializer() - { - InitializeCriticalSection(&mtx_); - } - ~Initializer() - { - DeleteCriticalSection(&mtx_); - } - }; - - static Initializer initializer_; - - public: - static CRITICAL_SECTION mtx_; - - template - class Lock - { - Lock(const Lock&); - Lock& operator=(const Lock&); - public: - Lock() - { - EnterCriticalSection(&mtx_); - } - Lock(Host&) - { - EnterCriticalSection(&mtx_); - } - ~Lock() - { - LeaveCriticalSection(&mtx_); - } - }; - - template - struct VolatileType - { - typedef Host Result; - }; - - typedef LONG IntType; - - static IntType AtomicIncrement(volatile IntType& lval) - { return InterlockedIncrement(&const_cast(lval)); } - - static IntType AtomicDecrement(volatile IntType& lval) - { return InterlockedDecrement(&const_cast(lval)); } - - static void AtomicAssign(volatile IntType& lval, IntType val) - { InterlockedExchange(&const_cast(lval), val); } - - static void AtomicAssign(IntType& lval, volatile IntType& val) - { InterlockedExchange(&lval, val); } - }; - - CRITICAL_SECTION ClassLevelLockable::mtx_; - - ClassLevelLockable::Initializer ClassLevelLockable::initializer_; - -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// January 10, 2002: Fixed bug in AtomicDivide - credit due to Jordi Guerrero -// August 14, 2002: Changed some AtomicDivide's to AtomicDecrement's MKH -// October 12, 2002: Ported to MSVC 6 by Terje Slettebų. -// SingleThreaded, ObjectLevelLockable and ClassLevelLockable changed from -// templates to classes with member templates, to be usable as policies in -// the other ported components. -//////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/MSVC/1200/TypeInfo.h b/MSVC/1200/TypeInfo.h deleted file mode 100644 index f9ed1a5..0000000 --- a/MSVC/1200/TypeInfo.h +++ /dev/null @@ -1,106 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: June 20, 2001 - -#ifndef TYPEINFO_INC_ -#define TYPEINFO_INC_ - -#include -#include -#include "Typelist.h" - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class TypeInfo -// Purpose: offer a first-class, comparable wrapper over std::type_info -//////////////////////////////////////////////////////////////////////////////// - - class TypeInfo - { - public: - // Constructors - TypeInfo(); // needed for containers - TypeInfo(const std::type_info&); // non-explicit - - // Access for the wrapped std::type_info - const std::type_info& Get() const; - // Compatibility functions - bool before(const TypeInfo& rhs) const; - const char* name() const; - - private: - const std::type_info* pInfo_; - }; - -// Implementation - - inline TypeInfo::TypeInfo() - { - class Nil {}; - pInfo_ = &typeid(Nil); - assert(pInfo_); - } - - inline TypeInfo::TypeInfo(const std::type_info& ti) - : pInfo_(&ti) - { assert(pInfo_); } - - inline bool TypeInfo::before(const TypeInfo& rhs) const - { - assert(pInfo_); - return pInfo_->before(*rhs.pInfo_); - } - - inline const std::type_info& TypeInfo::Get() const - { - assert(pInfo_); - return *pInfo_; - } - - inline const char* TypeInfo::name() const - { - assert(pInfo_); - return pInfo_->name(); - } - -// Comparison operators - - inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs) - { return lhs.Get() == rhs.Get(); } - - inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs) - { return lhs.before(rhs); } - - inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs) - { return !(lhs == rhs); } - - inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs) - { return rhs < lhs; } - - inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs) - { return !(lhs > rhs); } - - inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs) - { return !(lhs < rhs); } -} - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -//////////////////////////////////////////////////////////////////////////////// - -#endif // TYPEINFO_INC_ diff --git a/MSVC/1200/TypeManip.h b/MSVC/1200/TypeManip.h deleted file mode 100644 index ab12100..0000000 --- a/MSVC/1200/TypeManip.h +++ /dev/null @@ -1,302 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Welsey Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: August 22, 2001 - -#ifndef TYPEMANIP_INC_ -#define TYPEMANIP_INC_ - -namespace Loki { - - namespace Private { - - struct big { char c[2]; }; - - struct any { - template - any(const T&); - }; - - } // namespace Private - -//////////////////////////////////////////////////////////////////////////////// -// class template Int2Type -// Converts each integral constant into a unique type -// Invocation: Int2Type where v is a compile-time constant integral -// Defines 'value', an enum that evaluates to v -//////////////////////////////////////////////////////////////////////////////// - - template - struct Int2Type - { - enum { value = v }; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template Type2Type -// Converts each type into a unique, insipid type -// Invocation Type2Type where T is a type -// Defines the type OriginalType which maps back to T -//////////////////////////////////////////////////////////////////////////////// - - template - struct Type2Type - { - typedef T OriginalType; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template Select -// Selects one of two types based upon a boolean constant -// Invocation: Select::Result -// where: -// flag is a compile-time boolean constant -// T and U are types -// Result evaluates to T if flag is true, and to U otherwise. -//////////////////////////////////////////////////////////////////////////////// - -namespace Private { - -namespace Select_ { - -struct ChooseT { - template - struct Choose { - typedef T Result; - }; -}; - -struct ChooseU { - template - struct Choose { - typedef U Result; - }; -}; - -template -struct Selector { - typedef ChooseT Result; -}; - -template<> -struct Selector { - typedef ChooseU Result; -}; - -} // namespace Select_ - -} // namespace Private - -template -struct Select { -private: - typedef typename Private::Select_::Selector::Result selector; -public: - typedef typename selector::Choose::Result Result; -}; - -namespace Private { - -template -struct is_void { - enum { value = 0 }; -}; - -template<> -struct is_void { - enum { value = 1 }; -}; - -namespace is_same_ { - -template -char test_same(T*, T*); - -template -big test_same(T*, any); - -template -struct is_same_imp { - static T t; - static U u; - enum { result = sizeof(test_same(&t, &u)) == sizeof(char) }; -}; - -} // namespace is_same_ - -template -struct is_same { - enum { voidT = is_void::value }; - enum { voidU = is_void::value }; - struct BothVoid { - enum { result = 1 }; - }; - struct OneVoid { - enum { result = 0 }; - }; - typedef typename Select - >::Result - >::Result tester; - enum { result = tester::result }; -}; - -} // namespace Private - -//////////////////////////////////////////////////////////////////////////////// -// class template Conversion -// Figures out the conversion relationships between two types -// Invocations (T and U are types): -// a) Conversion::exists -// returns (at compile time) true if there is an implicit conversion from T -// to U (example: Derived to Base) -// b) Conversion::exists2Way -// returns (at compile time) true if there are both conversions from T -// to U and from U to T (example: int to char and back) -// c) Conversion::sameType -// returns (at compile time) true if T and U represent the same type -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -//////////////////////////////////////////////////////////////////////////////// - -namespace Private { - -namespace Conversion_ { - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4181) -#pragma warning(disable:4800) -#pragma warning(disable:4244) -#endif -template -struct Determine { - template - struct tester { - static char test(X, Y); - static big test(any, any); - }; - static T t; - static U u; - enum { exists = sizeof(tester::test(t, t)) == sizeof(char) }; - enum { exists2Way = exists & (sizeof(tester::test(u, u)) == sizeof(char)) }; - enum { sameType = exists2Way & is_same::result }; -}; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -} // namespace Conversion_ - -} // namespace Private - -template -struct Conversion { -private: - enum { voidT = Private::is_void::value }; - enum { voidU = Private::is_void::value }; - - struct both_void { - enum { exists = 1, exists2Way = 1, sameType = 1 }; - }; - - struct one_void { - enum { exists = 1, exists2Way = 0, sameType = 0 }; - }; - - typedef typename Select - >::Result - >::Result Chooser; -public: - enum { exists = Chooser::exists }; - enum { exists2Way = Chooser::exists2Way }; - enum { sameType = Chooser::sameType }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template SuperSubclass -// Invocation: SuperSubclass::value where B and D are types. -// Returns true if B is a public base of D, or if B and D are aliases of the -// same type. -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -//////////////////////////////////////////////////////////////////////////////// - -template -struct SuperSubclass -{ - enum { value = (::Loki::Conversion::exists && - !::Loki::Conversion::sameType) }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template SuperSubclassStrict -// Invocation: SuperSubclassStrict::value where B and D are types. -// Returns true if B is a public base of D. -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -//////////////////////////////////////////////////////////////////////////////// - -template -struct SuperSubclassStrict -{ - enum { value = (::Loki::Conversion::exists && - !::Loki::Conversion::sameType && - !::Loki::Conversion::sameType) }; -}; - -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// macro SUPERSUBCLASS -// Invocation: SUPERSUBCLASS(B, D) where B and D are types. -// Returns true if B is a public base of D, or if B and D are aliases of the -// same type. -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -// Deprecated: Use SuperSubclass class template instead. -//////////////////////////////////////////////////////////////////////////////// - -#define SUPERSUBCLASS(T, U) \ - ::Loki::SuperSubclass::value - -//////////////////////////////////////////////////////////////////////////////// -// macro SUPERSUBCLASS_STRICT -// Invocation: SUPERSUBCLASS(B, D) where B and D are types. -// Returns true if B is a public base of D. -// -// Caveat: might not work if T and U are in a private inheritance hierarchy. -// Deprecated: Use SuperSubclassStrict class template instead. -//////////////////////////////////////////////////////////////////////////////// - -#define SUPERSUBCLASS_STRICT(T, U) \ - ::Loki::SuperSubclassStrict::value - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// August 22, 2001: ported by Jonathan H Lundquist to MSVC -// October 12, 2002: Added SuperSubclass and SuperSubclassStrict templates. -// The corresponding macros are deprecated. T.S. -//////////////////////////////////////////////////////////////////////////////// - -#endif // TYPEMANIP_INC_ diff --git a/MSVC/1200/TypeTraits.h b/MSVC/1200/TypeTraits.h deleted file mode 100644 index 4ff198c..0000000 --- a/MSVC/1200/TypeTraits.h +++ /dev/null @@ -1,374 +0,0 @@ -#ifndef TYPETRAITS_INC_ -#define TYPETRAITS_INC_ - -#include "Typelist.h" - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template IsCustomUnsignedInt -// Offers a means to integrate nonstandard built-in unsigned integral types -// (such as unsigned __int64 or unsigned long long int) with the TypeTraits -// class template defined below. -// Invocation: IsCustomUnsignedInt where T is any type -// Defines 'value', an enum that is 1 iff T is a custom built-in unsigned -// integral type -// Specialize this class template for nonstandard unsigned integral types -// and define value = 1 in those specializations -//////////////////////////////////////////////////////////////////////////////// - - template - struct IsCustomUnsignedInt - { - enum { value = 0 }; - }; - -#ifdef _MSC_VER - template<> - struct IsCustomUnsignedInt { - enum { value = 1 }; - }; -#endif - -//////////////////////////////////////////////////////////////////////////////// -// class template IsCustomSignedInt -// Offers a means to integrate nonstandard built-in unsigned integral types -// (such as unsigned __int64 or unsigned long long int) with the TypeTraits -// class template defined below. -// Invocation: IsCustomSignedInt where T is any type -// Defines 'value', an enum that is 1 iff T is a custom built-in signed -// integral type -// Specialize this class template for nonstandard unsigned integral types -// and define value = 1 in those specializations -//////////////////////////////////////////////////////////////////////////////// - - template - struct IsCustomSignedInt - { - enum { value = 0 }; - }; - -#ifdef _MSC_VER - template<> - struct IsCustomSignedInt<__int64> { - enum { value = 1 }; - }; -#endif - -//////////////////////////////////////////////////////////////////////////////// -// class template IsCustomFloat -// Offers a means to integrate nonstandard floating point types with the -// TypeTraits class template defined below. -// Invocation: IsCustomFloat where T is any type -// Defines 'value', an enum that is 1 iff T is a custom built-in -// floating point type -// Specialize this class template for nonstandard unsigned integral types -// and define value = 1 in those specializations -//////////////////////////////////////////////////////////////////////////////// - - template - struct IsCustomFloat - { - enum { value = 0 }; - }; - -//////////////////////////////////////////////////////////////////////////////// -// Helper types for class template TypeTraits defined below -//////////////////////////////////////////////////////////////////////////////// - - namespace Private - { - typedef TYPELIST_4(unsigned char, unsigned short int, - unsigned int, unsigned long int) StdUnsignedInts; - typedef TYPELIST_4(signed char, short int, - int, long int) StdSignedInts; - typedef TYPELIST_3(bool, char, wchar_t) StdOtherInts; - typedef TYPELIST_3(float, double, long double) StdFloats; - - char test_ptr(const volatile void*, const volatile void*); - big test_ptr(any, any); - - template - T* unrefptr(T&); - - char test_const(const volatile void*); - big test_const(volatile void*); - char test_volatile(const volatile void*); - big test_volatile(const void*); - - template - char test_mptr(V X::*, any); - - big test_mptr(any, any); - - template - struct AddReferenceImp { - template - struct Imp { - typedef T Result; - }; - }; - - template<> - struct AddReferenceImp { - template - struct Imp { - typedef T& Result; - }; - }; - -#ifndef _MSC_VER - template struct PointerTraits - { - enum { result = false }; - typedef NullType PointeeType; - }; - - template struct PointerTraits - { - enum { result = true }; - typedef U PointeeType; - }; -#else - template - struct PointerTraits { - private: - static U u; - public: - typedef void PointeeType; // unable to determine correctly - enum { result = sizeof(Private::test_ptr(&u, u)) == sizeof(char) }; - }; - - template<> - struct PointerTraits { - typedef void PointeeType; - enum { result = 0 }; - }; -#endif -#ifndef _MSC_VER - template struct ReferenceTraits - { - enum { result = false }; - typedef U ReferredType; - }; - - template struct ReferenceTraits - { - enum { result = true }; - typedef U ReferredType; - }; -#else -#pragma warning(push) -#pragma warning(disable:4181) - template - struct ReferenceTraits { - typedef U const volatile cv_u; - static cv_u u; - public: - enum { result = (sizeof(Private::test_const(&u)) != sizeof(char)) - | (sizeof(Private::test_volatile(&u)) != sizeof(char)) }; - typedef void ReferredType; // unable to determine correctly - }; -#pragma warning(pop) - - template<> - struct ReferenceTraits { - enum { result = 0 }; - typedef void ReferredType; - }; -#endif -#ifndef _MSC_VER - template struct PToMTraits - { - enum { result = false }; - }; - - template - struct PToMTraits - { - enum { result = true }; - }; -#else - template - struct PToMTraits { - private: - static U u; - public: - enum { result = sizeof(Private::test_mptr(u, &u)) == sizeof(char) }; - }; - - template<> - struct PToMTraits { - enum { result = 0 }; - }; -#endif -#ifndef _MSC_VER - template struct UnConst - { - typedef U Result; - enum { isConst = 0 }; - }; - - template struct UnConst - { - typedef U Result; - enum { isConst = 1 }; - }; -#else - template - struct UnConst { - private: - static U u; - public: - typedef void Result; // unable to determine correctly - enum { isConst = sizeof(Private::test_const(Private::unrefptr(u))) == sizeof(char) }; - }; - - template<> - struct UnConst { - typedef void Result; - enum { isConst = 0 }; - }; -#endif -#ifndef _MSC_VER - template struct UnVolatile - { - typedef U Result; - enum { isVolatile = 0 }; - }; - - template struct UnVolatile - { - typedef U Result; - enum { isVolatile = 1 }; - }; -#else - template - struct UnVolatile { - private: - static U u; - public: - typedef void Result; // unable to determine correctly - enum { isVolatile = sizeof(Private::test_volatile(Private::unrefptr(u))) == sizeof(char) }; - }; - - template<> - struct UnVolatile { - typedef void Result; - enum { isVolatile = 0 }; - }; -#endif - template - struct AddReference { - typedef typename Private::AddReferenceImp::template Imp::Result Result; - }; - - template<> - struct AddReference { - typedef void Result; - }; - } - -//////////////////////////////////////////////////////////////////////////////// -// class template TypeTraits -// Figures out various properties of any given type -// Invocations (T is a type): -// a) TypeTraits::isPointer -// returns (at compile time) true if T is a pointer type -// b) TypeTraits::PointeeType -// returns the type to which T points is T is a pointer type, NullType otherwise -// a) TypeTraits::isReference -// returns (at compile time) true if T is a reference type -// b) TypeTraits::ReferredType -// returns the type to which T refers is T is a reference type, NullType -// otherwise -// c) TypeTraits::isMemberPointer -// returns (at compile time) true if T is a pointer to member type -// d) TypeTraits::isStdUnsignedInt -// returns (at compile time) true if T is a standard unsigned integral type -// e) TypeTraits::isStdSignedInt -// returns (at compile time) true if T is a standard signed integral type -// f) TypeTraits::isStdIntegral -// returns (at compile time) true if T is a standard integral type -// g) TypeTraits::isStdFloat -// returns (at compile time) true if T is a standard floating-point type -// h) TypeTraits::isStdArith -// returns (at compile time) true if T is a standard arithmetic type -// i) TypeTraits::isStdFundamental -// returns (at compile time) true if T is a standard fundamental type -// j) TypeTraits::isUnsignedInt -// returns (at compile time) true if T is a unsigned integral type -// k) TypeTraits::isSignedInt -// returns (at compile time) true if T is a signed integral type -// l) TypeTraits::isIntegral -// returns (at compile time) true if T is a integral type -// m) TypeTraits::isFloat -// returns (at compile time) true if T is a floating-point type -// n) TypeTraits::isArith -// returns (at compile time) true if T is a arithmetic type -// o) TypeTraits::isFundamental -// returns (at compile time) true if T is a fundamental type -// p) TypeTraits::ParameterType -// returns the optimal type to be used as a parameter for functions that take Ts -// q) TypeTraits::isConst -// returns (at compile time) true if T is a const-qualified type -// r) TypeTraits::NonConstType -// removes the 'const' qualifier from T, if any -// s) TypeTraits::isVolatile -// returns (at compile time) true if T is a volatile-qualified type -// t) TypeTraits::NonVolatileType -// removes the 'volatile' qualifier from T, if any -// u) TypeTraits::UnqualifiedType -// removes both the 'const' and 'volatile' qualifiers from T, if any -//////////////////////////////////////////////////////////////////////////////// - - template - class TypeTraits - { - public: - enum { isPointer = Private::PointerTraits::result }; - typedef typename Private::PointerTraits::PointeeType PointeeType; - - enum { isReference = Private::ReferenceTraits::result }; - typedef typename Private::ReferenceTraits::ReferredType ReferredType; - - enum { isMemberPointer = Private::PToMTraits::result }; - - enum { isStdUnsignedInt = - TL::IndexOf::value >= 0 }; - enum { isStdSignedInt = - TL::IndexOf::value >= 0 }; - enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt || - TL::IndexOf::value >= 0 }; - enum { isStdFloat = TL::IndexOf::value >= 0 }; - enum { isStdArith = isStdIntegral || isStdFloat }; - enum { isStdFundamental = isStdArith || isStdFloat || - Conversion::sameType }; - - enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt::value }; - enum { isSignedInt = isStdSignedInt || IsCustomSignedInt::value }; - enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt }; - enum { isFloat = isStdFloat || IsCustomFloat::value }; - enum { isArith = isIntegral || isFloat }; - enum { isFundamental = isStdFundamental || isArith || isFloat }; - - typedef typename Select::Result - >::Result ParameterType; - - enum { isConst = Private::UnConst::isConst }; - typedef typename Private::UnConst::Result NonConstType; - enum { isVolatile = Private::UnVolatile::isVolatile }; - typedef typename Private::UnVolatile::Result NonVolatileType; - typedef typename Private::UnVolatile::Result>::Result - UnqualifiedType; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// August 22, 2001: ported by Jonathan H Lundquist to MSVC -//////////////////////////////////////////////////////////////////////////////// - -#endif // TYPETRAITS_INC_ diff --git a/MSVC/1200/Typelist.h b/MSVC/1200/Typelist.h deleted file mode 100644 index abe6a41..0000000 --- a/MSVC/1200/Typelist.h +++ /dev/null @@ -1,788 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Welsey Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// - -// Last update: August 22, 2001 - -#ifndef TYPELIST_INC_ -#define TYPELIST_INC_ - -#include "NullType.h" -#include "TypeManip.h" - -//////////////////////////////////////////////////////////////////////////////// -// macros TYPELIST_1, TYPELIST_2, ... TYPELIST_50 -// Each takes a number of arguments equal to its numeric suffix -// The arguments are type names. TYPELIST_NN generates a typelist containing -// all types passed as arguments, in that order. -// Example: TYPELIST_2(char, int) generates a type containing char and int. -//////////////////////////////////////////////////////////////////////////////// - -#define TYPELIST_1(T1) ::Loki::Typelist - -#define TYPELIST_2(T1, T2) ::Loki::Typelist - -#define TYPELIST_3(T1, T2, T3) ::Loki::Typelist - -#define TYPELIST_4(T1, T2, T3, T4) \ - ::Loki::Typelist - -#define TYPELIST_5(T1, T2, T3, T4, T5) \ - ::Loki::Typelist - -#define TYPELIST_6(T1, T2, T3, T4, T5, T6) \ - ::Loki::Typelist - -#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ - ::Loki::Typelist - -#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ - ::Loki::Typelist - -#define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ - ::Loki::Typelist - -#define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ - ::Loki::Typelist - -#define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ - ::Loki::Typelist - -#define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ - ::Loki::Typelist - -#define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \ - ::Loki::Typelist - -#define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14) \ - ::Loki::Typelist - -#define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15) \ - ::Loki::Typelist - -#define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16) \ - ::Loki::Typelist - -#define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17) \ - ::Loki::Typelist - -#define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18) \ - ::Loki::Typelist - -#define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19) \ - ::Loki::Typelist - -#define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \ - ::Loki::Typelist - -#define TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \ - ::Loki::Typelist - -#define TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \ - ::Loki::Typelist - -#define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \ - ::Loki::Typelist - -#define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \ - ::Loki::Typelist - -#define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \ - ::Loki::Typelist - -#define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26) \ - ::Loki::Typelist - -#define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27) \ - ::Loki::Typelist - -#define TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28) \ - ::Loki::Typelist - -#define TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29) \ - ::Loki::Typelist - -#define TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \ - ::Loki::Typelist - -#define TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \ - ::Loki::Typelist - -#define TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \ - ::Loki::Typelist - -#define TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \ - ::Loki::Typelist - -#define TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \ - ::Loki::Typelist - -#define TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35) \ - ::Loki::Typelist - -#define TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36) \ - ::Loki::Typelist - -#define TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37) \ - ::Loki::Typelist - -#define TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38) \ - ::Loki::Typelist - -#define TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39) \ - ::Loki::Typelist - -#define TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \ - ::Loki::Typelist - -#define TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \ - ::Loki::Typelist - -#define TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \ - ::Loki::Typelist - -#define TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \ - ::Loki::Typelist - -#define TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \ - ::Loki::Typelist - -#define TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45) \ - ::Loki::Typelist - -#define TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46) \ - ::Loki::Typelist - -#define TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47) \ - ::Loki::Typelist - -#define TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48) \ - ::Loki::Typelist - -#define TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48, T49) \ - ::Loki::Typelist - -#define TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ - T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ - T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ - T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ - T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \ - ::Loki::Typelist - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template Typelist -// The building block of typelists of any length -// Use it through the TYPELIST_NN macros -// Defines nested types: -// Head (first element, a non-typelist type by convention) -// Tail (second element, can be another typelist) -//////////////////////////////////////////////////////////////////////////////// - - template - struct Typelist - { - typedef T Head; - typedef U Tail; - }; - - namespace TL - { -//////////////////////////////////////////////////////////////////////////////// -// class template Length -// Computes the length of a typelist -// Invocation (TList is a typelist): -// Length::value -// returns a compile-time constant containing the length of TList, not counting -// the end terminator (which by convention is NullType) -//////////////////////////////////////////////////////////////////////////////// - - template struct Length; - template <> struct Length - { - enum { value = 0 }; - }; - - template - struct Length - { - enum { value = 1 + Length::value }; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template TypeAt -// Finds the type at a given index in a typelist -// Invocation (TList is a typelist and index is a compile-time integral -// constant): -// TypeAt::Result -// returns the type in position 'index' in TList -// If you pass an out-of-bounds index, the result is a compile-time error -//////////////////////////////////////////////////////////////////////////////// - - namespace TypeAt_ { - - template - struct Index { - template - struct Which { - typedef typename Index::Which::Result Result; - }; - }; - - template<> - struct Index<0> { - template - struct Which { - typedef typename TList::Head Result; - }; - }; - - } // namespace TypeAt_ - - template - struct TypeAt { - typedef typename TypeAt_::Index::Which::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template TypeAtNonStrict -// Finds the type at a given index in a typelist -// Invocations (TList is a typelist and index is a compile-time integral -// constant): -// a) TypeAt::Result -// returns the type in position 'index' in TList, or NullType if index is -// out-of-bounds -// b) TypeAt::Result -// returns the type in position 'index' in TList, or D if index is out-of-bounds -//////////////////////////////////////////////////////////////////////////////// - - namespace TypeAtNonStrict_ { - - template - struct ListType; - - template - struct Index; - - template<> - struct ListType { - template - struct Remainder { - typedef DefaultType Result; - }; - }; - - template<> - struct Index<0> { - template - struct Remainder { - typedef typename TList::Head Result; - }; - }; - - template - struct Index { - template - struct Remainder { - enum { isSameType = Conversion::sameType }; - typedef typename Select::Remainder::Result>::Result Result; - }; - }; - - template - struct ListType { - template - struct Remainder { - typedef typename Index::Remainder::Result Result; - }; - }; - - } // namespace TypeAtNonStrict_ - - template - struct TypeAtNonStrict { - typedef typename TypeAtNonStrict_::ListType::Remainder::Result Result; - }; - -} // namespace TL - -//////////////////////////////////////////////////////////////////////////////// -// class template IndexOf -// Finds the index of a type in a typelist -// Invocation (TList is a typelist and T is a type): -// IndexOf::value -// returns the position of T in TList, or NullType if T is not found in TList -//////////////////////////////////////////////////////////////////////////////// - -namespace Private { - -namespace IndexOf_ { - -template -struct Head { - typedef typename TList::Head Result; -}; - -template<> -struct Head { - typedef void Result; -}; - -struct IsNull { - enum { value = -1 }; -}; - -struct IsTHead { - enum { value = 0 }; -}; - -template -struct IsNotTHead { - typedef typename TList::Tail Tail; - typedef typename Select::result, - IsNull, - typename Select::Result, T>::result, - IsTHead, IsNotTHead - >::Result - >::Result chooser; - enum { temp = chooser::value }; - enum { value = temp == -1 ? -1 : 1 + temp }; -}; - -template -struct IsNotNull { - typedef typename Select::result, - IsTHead, - IsNotTHead - >::Result chooser; - enum { value = chooser::value }; -}; - -} // namespace IndexOf_ - -} // namespace Private - -namespace TL { - -template -struct IndexOf { -private: - typedef typename Select::result, - Private::IndexOf_::IsNull, - Private::IndexOf_::IsNotNull - >::Result chooser; -public: - enum { value = chooser::value }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// class template Append -// Appends a type or a typelist to another -// Invocation (TList is a typelist and T is either a type or a typelist): -// Append::Result -// returns a typelist that is TList followed by T and NullType-terminated -//////////////////////////////////////////////////////////////////////////////// - - namespace Append_ { - - template - struct Helper { - struct big { char i[2]; }; - template - static char Test(const Typelist&); - static big Test(...); - static T makeT(); - }; - - } // namespace Append_ - - template - struct Append; - - template<> - struct Append { - typedef NullType Result; - }; - - template - struct Append { - private: - enum { T_is_list = sizeof(Append_::Helper::Test(Append_::Helper::MakeT())) == sizeof(char) }; - enum { TList_is_null = Conversion::sameType }; - typedef typename Select::Result Result1; - typedef typename Select, Result1>::Result Result2; - public: - typedef typename Select::Result>, Result2>::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template Erase -// Erases the first occurence, if any, of a type in a typelist -// Invocation (TList is a typelist and T is a type): -// Erase::Result -// returns a typelist that is TList without the first occurence of T -//////////////////////////////////////////////////////////////////////////////// - - template - struct Erase { - private: - enum { TList_is_null = Conversion::sameType }; - enum { Head_is_T = Conversion::sameType }; - typedef typename Select::Result Result1; - public: - typedef typename Select::Result>, Result1>::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template EraseAll -// Erases all first occurences, if any, of a type in a typelist -// Invocation (TList is a typelist and T is a type): -// EraseAll::Result -// returns a typelist that is TList without any occurence of T -//////////////////////////////////////////////////////////////////////////////// - - template - struct EraseAll { - private: - enum { TList_is_null = Conversion::sameType }; - enum { Head_is_T = Conversion::sameType }; - typedef typename Select::Result, NullType>::Result Result1; - public: - typedef typename Select::Result>, Result1>::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template NoDuplicates -// Removes all duplicate types in a typelist -// Invocation (TList is a typelist): -// NoDuplicates::Result -//////////////////////////////////////////////////////////////////////////////// - - template - struct NoDuplicates; - - template<> - struct NoDuplicates { - typedef NullType Result; - }; - - template - struct NoDuplicates { - private: - typedef typename NoDuplicates::Result L1; - typedef typename Erase::Result L2; - public: - typedef Typelist Result; - }; - - -//////////////////////////////////////////////////////////////////////////////// -// class template Replace -// Replaces the first occurence of a type in a typelist, with another type -// Invocation (TList is a typelist, T, U are types): -// Replace::Result -// returns a typelist in which the first occurence of T is replaced with U -//////////////////////////////////////////////////////////////////////////////// - - template - struct Replace { - private: - enum { TList_is_null = Conversion::sameType }; - enum { Head_is_T = Conversion::sameType }; - typedef typename Select, NullType>::Result Result1; - public: - typedef typename Select::Result>, Result1>::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template ReplaceAll -// Replaces all occurences of a type in a typelist, with another type -// Invocation (TList is a typelist, T, U are types): -// Replace::Result -// returns a typelist in which all occurences of T is replaced with U -//////////////////////////////////////////////////////////////////////////////// - - template - struct ReplaceAll { - private: - enum { TList_is_null = Conversion::sameType }; - enum { Head_is_T = Conversion::sameType }; - typedef typename Select::Result>, NullType>::Result Result1; - public: - typedef typename Select::Result>, Result1>::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template Reverse -// Reverses a typelist -// Invocation (TList is a typelist): -// Reverse::Result -// returns a typelist that is TList reversed -//////////////////////////////////////////////////////////////////////////////// - - template - struct Reverse { - private: - enum { list_of_one = Conversion::sameType }; - public: - typedef typename Select::Result, - typename TList::Head - >::Result - >::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template MostDerived -// Finds the type in a typelist that is the most derived from a given type -// Invocation (TList is a typelist, T is a type): -// Replace::Result -// returns the type in TList that's the most derived from T -//////////////////////////////////////////////////////////////////////////////// - - template - struct MostDerived { - private: - enum { TList_is_null = Conversion::sameType }; - typedef typename Select::Result>::Result Candidate; - public: - typedef typename Select::Result - >::Result Result; - }; - -//////////////////////////////////////////////////////////////////////////////// -// class template DerivedToFront -// Arranges the types in a typelist so that the most derived types appear first -// Invocation (TList is a typelist): -// DerivedToFront::Result -// returns the reordered TList -//////////////////////////////////////////////////////////////////////////////// - - namespace DerivedToFront_ { - - template - struct ListType { - }; - - template<> - struct ListType { - typedef NullType Result; - }; - - } // namespace DerivedToFront_ - - template - struct DerivedToFront; - - template<> - struct DerivedToFront { - typedef NullType Result; - }; - - template - struct DerivedToFront { - private: - typedef typename MostDerived::Result TheMostDerived; - typedef typename Replace::Result L; - public: - typedef Typelist Result; - }; - - } // namespace TL - -} // namespace Loki - -//////////////////////////////////////////////////////////////////////////////// -// Change log: -// June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27 -// (credit due to Dave Taylor) -// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! -// August 22, 2001: ported by Jonathan H Lundquist to MSVC -//////////////////////////////////////////////////////////////////////////////// - -#endif // TYPELIST_INC_