no message

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@70 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
tslettebo 2002-10-13 09:38:20 +00:00
parent 52020f94e0
commit 08bd05c8c4
27 changed files with 2717 additions and 1276 deletions

View file

@ -143,6 +143,38 @@ namespace Loki
static const bool sameType = true;
};
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclass
// Invocation: SuperSubclass<B, D>::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 <class T, class U>
struct SuperSubclass
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
!::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
};
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclassStrict
// Invocation: SuperSubclassStrict<B, D>::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<class T,class U>
struct SuperSubclassStrict
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
!::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
!::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
};
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
@ -152,23 +184,23 @@ namespace Loki
// 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::Conversion<const volatile U *, const volatile T *>::exists && \
!::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
::Loki::SuperSubclass<T,U>::value
////////////////////////////////////////////////////////////////////////////////
// macro SUPERSUBCLASS
// 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) \
((SUPERSUBCLASS(T, U) && \
!::Loki::Conversion<const volatile T *, const volatile U *>::sameType))
::Loki::SuperSubclassStrict<T,U>::value
////////////////////////////////////////////////////////////////////////////////
// Change log:
@ -179,6 +211,8 @@ namespace Loki
// November 23, 2001: (well it's 12:01 am) fixed bug in SUPERSUBCLASS - added
// the volatile qualifier to be 100% politically correct
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
// October 12, 2002: Added SuperSubclass and SuperSubclassStrict templates.
// The corresponding macros are deprecated. T.S.
////////////////////////////////////////////////////////////////////////////////
#endif // TYPEMANIP_INC_

335
MSVC/1200/AssocVector.h Normal file
View file

@ -0,0 +1,335 @@
////////////////////////////////////////////////////////////////////////////////
// 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 <algorithm>
#include <functional>
#include <vector>
#include <utility>
namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
// class template AssocVectorCompare
// Used by AssocVector
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <class Value, class C>
class AssocVectorCompare : public C
{
typedef std::pair<typename C::first_argument_type, Value>
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<K, V> not std::pair<const K, V>
// * iterators are random
////////////////////////////////////////////////////////////////////////////////
template
<
class K,
class V,
class C = std::less<K>,
class A = std::allocator< std::pair<K, V> >
>
class AssocVector
: private std::vector< std::pair<K, V>, A >
, private Private::AssocVectorCompare<V, C>
{
typedef std::vector<std::pair<K, V>, A> Base;
typedef Private::AssocVectorCompare<V, C> 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<value_type, value_type, bool>
, 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 <class InputIterator>
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<iterator, bool> 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 <class InputIterator>
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<iterator, iterator> equal_range(const key_type& k)
{
MyCompare& me = *this;
return std::equal_range(begin(), end(), k, me);
}
std::pair<const_iterator, const_iterator> 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 <class K, class V, class C, class A>
void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& 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_

37
MSVC/1200/EmptyType.h Normal file
View file

@ -0,0 +1,37 @@
////////////////////////////////////////////////////////////////////////////////
// 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_

153
MSVC/1200/Factory.h Normal file
View file

@ -0,0 +1,153 @@
////////////////////////////////////////////////////////////////////////////////
// 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 <exception>
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 <typename IdentifierType, class AbstractProduct>
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<IdentifierType, ProductCreator> 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<TypeInfo, ProductCreator> 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_

39
MSVC/1200/NullType.h Normal file
View file

@ -0,0 +1,39 @@
////////////////////////////////////////////////////////////////////////////////
// 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_

53
MSVC/1200/Singleton.cpp Normal file
View file

@ -0,0 +1,53 @@
////////////////////////////////////////////////////////////////////////////////
// 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<TrackerArray>(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.
////////////////////////////////////////////////////////////////////////////////

499
MSVC/1200/Singleton.h Normal file
View file

@ -0,0 +1,499 @@
////////////////////////////////////////////////////////////////////////////////
// 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 <algorithm>
#include <stdexcept>
#include <cassert>
#include <cstdlib>
#include <new>
namespace Loki
{
namespace Private
{
template< typename T >
struct MSVCNeverTrue
{
enum { value = false };
};
template <class MetaFunctionWrapper, class T>
struct Apply
{
#ifdef _MSC_VER
// based on the (non-conforming) MSVC trick from MPL
template<bool>
struct MetaFunctionWrapper_VC : MetaFunctionWrapper {};
//illegal C++ which causes VC to admit that MetaFunctionWrapper_VC
//can have a nested template:
template<>
struct MetaFunctionWrapper_VC<true>
{template<class> struct VolatileType; };
typedef typename MetaFunctionWrapper_VC<
MSVCNeverTrue<MetaFunctionWrapper>::value
>::template VolatileType<T>::Result Result;
#else
typedef typename MetaFunctionWrapper::template VolatileType<T>::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 <typename T>
struct Deleter
{
static void Delete(T* pObj)
{ delete pObj; }
};
// Concrete lifetime tracker for objects of type T
template <typename T, typename Destroyer>
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 <typename T, typename Destroyer>
void SetLongevity(T* pDynObject, unsigned int longevity,
Destroyer d = Private::Deleter<T>::Delete)
{
using namespace Private;
TrackerArray pNewArray = static_cast<TrackerArray>(
realloc(pTrackerArray,
sizeof(*pTrackerArray) * (elements + 1)));
if (!pNewArray) throw std::bad_alloc();
// Delayed assignment for exception safety
pTrackerArray = pNewArray;
LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
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 <class T>
static T* Create(T*)
{ return new T; }
template <class T>
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 <class T>
static T* Create(T*)
{
void* p = malloc(sizeof(T));
if (!p) return 0;
return new(p) T;
}
template <class T>
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 <class T>
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 <class T>
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 <class T>
static void ScheduleDestruction(T*, void (*pFun)())
{ atexit(pFun); }
template <class T>
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 <class T>
static void ScheduleDestruction(T*, void (*pFun)())
{
#ifndef ATEXIT_FIXED
if (!destroyedOnce_)
#endif
atexit(pFun);
}
template <class T>
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 <class T>
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 <class T>
static void ScheduleDestruction(T* pObj, void (*pFun)())
{
Private::Adapter<T> adapter = { pFun };
SetLongevity(pObj, GetLongevity(pObj), adapter);
}
template <class T>
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 <class T>
static void ScheduleDestruction(T*, void (*)())
{}
template <class T>
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<ThreadingModel,T*>::Result PtrInstanceType;
// typedef typename ThreadingModel::VolatileType<T*>::Result PtrInstanceType;
static PtrInstanceType pInstance_;
static bool destroyed_;
};
////////////////////////////////////////////////////////////////////////////////
// SingletonHolder's data
////////////////////////////////////////////////////////////////////////////////
template
<
class T,
class C,
class L,
class M
>
typename SingletonHolder<T, C, L, M>::PtrInstanceType
SingletonHolder<T, C, L, M>::pInstance_;
template
<
class T,
class C,
class L,
class M
>
bool SingletonHolder<T, C, L, M>::destroyed_;
////////////////////////////////////////////////////////////////////////////////
// SingletonHolder::Instance
////////////////////////////////////////////////////////////////////////////////
template
<
class T,
class CreationPolicy,
class LifetimePolicy,
class ThreadingModel
>
inline T& SingletonHolder<T, CreationPolicy,
LifetimePolicy, ThreadingModel>::Instance()
{
if (!pInstance_)
{
MakeInstance();
}
return *pInstance_;
}
////////////////////////////////////////////////////////////////////////////////
// SingletonHolder::MakeInstance (helper for Instance)
////////////////////////////////////////////////////////////////////////////////
template
<
class T,
class CreationPolicy,
class LifetimePolicy,
class ThreadingModel
>
void SingletonHolder<T, CreationPolicy,
LifetimePolicy, ThreadingModel>::MakeInstance()
{
typename ThreadingModel::Lock<T> 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<T, CreationPolicy, L, M>::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_

213
MSVC/1200/Threads.h Normal file
View file

@ -0,0 +1,213 @@
#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 <class Host>
struct Lock
{
Lock() {}
Lock(const Host&) {}
};
template <class Host>
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 <windows.h>
////////////////////////////////////////////////////////////////////////////////
// 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 Host>
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 <class Host>
struct VolatileType
{
typedef volatile Host Result;
};
typedef LONG IntType;
static IntType AtomicIncrement(volatile IntType& lval)
{ return InterlockedIncrement(&const_cast<IntType&>(lval)); }
static IntType AtomicDecrement(volatile IntType& lval)
{ return InterlockedDecrement(&const_cast<IntType&>(lval)); }
static void AtomicAssign(volatile IntType& lval, IntType val)
{ InterlockedExchange(&const_cast<IntType&>(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 Host>
class Lock
{
Lock(const Lock&);
Lock& operator=(const Lock&);
public:
Lock()
{
EnterCriticalSection(&mtx_);
}
Lock(Host&)
{
EnterCriticalSection(&mtx_);
}
~Lock()
{
LeaveCriticalSection(&mtx_);
}
};
template <class Host>
struct VolatileType
{
typedef Host Result;
};
typedef LONG IntType;
static IntType AtomicIncrement(volatile IntType& lval)
{ return InterlockedIncrement(&const_cast<IntType&>(lval)); }
static IntType AtomicDecrement(volatile IntType& lval)
{ return InterlockedDecrement(&const_cast<IntType&>(lval)); }
static void AtomicAssign(volatile IntType& lval, IntType val)
{ InterlockedExchange(&const_cast<IntType&>(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

106
MSVC/1200/TypeInfo.h Normal file
View file

@ -0,0 +1,106 @@
////////////////////////////////////////////////////////////////////////////////
// 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 <typeinfo>
#include <cassert>
#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_

View file

@ -786,4 +786,3 @@ public:
////////////////////////////////////////////////////////////////////////////////
#endif // TYPELIST_INC_

View file

@ -232,6 +232,38 @@ public:
enum { sameType = Chooser::sameType };
};
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclass
// Invocation: SuperSubclass<B, D>::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 <class T, class U>
struct SuperSubclass
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
!::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
};
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclassStrict
// Invocation: SuperSubclassStrict<B, D>::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<class T,class U>
struct SuperSubclassStrict
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
!::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
!::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
};
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
@ -241,28 +273,30 @@ public:
// 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::Conversion<const U*, const T*>::exists && \
!::Loki::Conversion<const T*, const void*>::sameType)
::Loki::SuperSubclass<T,U>::value
////////////////////////////////////////////////////////////////////////////////
// macro SUPERSUBCLASS
// 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) \
(SUPERSUBCLASS(T, U) && \
!::Loki::Conversion<const T, const U>::sameType)
::Loki::SuperSubclassStrict<T,U>::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_

View file

@ -1,2 +0,0 @@
MSVC6
Jonathan H. Lundquist

View file

@ -175,15 +175,6 @@ namespace Loki
enum { sameType = (SameType<T, U>::value) };
};
////////////////////////////////////////////////////////////////////////////////
// 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.
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclass
// Invocation: SuperSubclass<B, D>::value where B and D are types.
@ -216,30 +207,40 @@ struct SuperSubclassStrict
!::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
};
#define SUPERSUBCLASS(T, U) \
(::Loki::Conversion<const volatile U*, const volatile T*>::exists && \
!::Loki::Conversion<const volatile T*, const volatile void*>::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<T,U>::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) \
(SUPERSUBCLASS(T, U) && \
!::Loki::Conversion<const volatile T *, const volatile U *>::sameType)
} // namespace Loki
::Loki::SuperSubclassStrict<T,U>::value
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466)
// Oct 10, 2002: Commented SameType template (not a loki-template - yet)
// October 10, 2002: Commented SameType template (not a Loki-template - yet). MKH
// October 12, 2002: Added SuperSubclass and SuperSubclassStrict templates.
// The corresponding macros are deprecated. T.S.
////////////////////////////////////////////////////////////////////////////////
#endif // TYPEMANIP_INC_

View file

@ -20,6 +20,12 @@
#include <loki/AssocVector.h>
#include "UnitTest.h"
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
#define C_Namespace
#else
#define C_Namespace std
#endif
///////////////////////////////////////////////////////////////////////////////
// AssocVectorTest
///////////////////////////////////////////////////////////////////////////////
@ -36,16 +42,22 @@ public:
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef C_Namespace::size_t size_type;
typedef C_Namespace::ptrdiff_t difference_type;
template <class U>
struct rebind { typedef TestAllocator<U> other; };
TestAllocator() {}
TestAllocator(const TestAllocator&) {}
#if !(defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__))
template <class U>
TestAllocator(const TestAllocator<U>&) {}
#endif
~TestAllocator() {}
pointer address(reference x) const { return &x; }
@ -154,9 +166,9 @@ typedef Loki::AssocVector<int, const char*> test_vect5_t;
void check_insert1(test_vect1_t& v)
{
std::srand(10);
C_Namespace::srand(10);
for (unsigned i = 0; i < 100; ++i) {
int x = std::rand();
int x = C_Namespace::rand();
v.insert(std::make_pair(x, x));
assert(is_sorted(v));
}
@ -272,11 +284,11 @@ void test_vect3()
// 3) or recompile STLPort DLL.
// This all is related to bug in STLPort allocator.
test_vect3_t vec31;
std::srand(111);
C_Namespace::srand(111);
// a stress test
for (unsigned i = 0; i < 2 * 1000; ++i) {
char buffer[16];
std::sprintf(buffer, "string%d", std::rand());
C_Namespace::sprintf(buffer, "string%d", C_Namespace::rand());
std::string s(buffer);
vec31.insert(std::make_pair(s, s));
}

View file

@ -1,80 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// Unit Test for Loki
//
// Copyright Terje Slettebø and Pavel Vozenilek 2002.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.
//
// Last update: September 16, 2002
///////////////////////////////////////////////////////////////////////////////
#ifndef LOKITEST_H
#define LOKITEST_H
#include "TypelistTest.h"
//#include "TypeManipTest.h"
//#include "TypeTraitsTest.h"
//#include "SmallObjectTest.h"
//#include "SingletonTest.h"
//#include "SmartPtrTest.h"
//#include "FactoryTest.h"
//#include "AbstractFactoryTest.h"
//#include "AssocVectorTest.h"
//#include "FunctorTest.h"
#include "DataGeneratorsTest.h"
///////////////////////////////////////////////////////////////////////////////
// LokiTest
///////////////////////////////////////////////////////////////////////////////
class LokiTest
{
public:
LokiTest()
{
addTests();
}
int result()
{
return unitTest.run("Unit Test",tests);
}
private:
void addTests()
{
tests.add(typelistTest);
// tests.add(typeManipTest);
// tests.add(typeTraitsTest);
// tests.add(smallObjectTest);
// tests.add(singletonTest);
// tests.add(smartPtrTest);
// tests.add(factoryTest);
// tests.add(abstractFactoryTest);
// tests.add(assocVectorTest);
// tests.add(functorTest);
tests.add(datageneratorTest);
}
private:
UnitTest unitTest;
TestSuite tests;
TypelistTest typelistTest;
// TypeManipTest typeManipTest;
// TypeTraitsTest typeTraitsTest;
// SmallObjectTest smallObjectTest;
// SingletonTest singletonTest;
// SmartPtrTest smartPtrTest;
// FactoryTest factoryTest;
// AbstractFactoryTest abstractFactoryTest;
// AssocVectorTest assocVectorTest;
// FunctorTest functorTest;
DataGeneratorsTest datageneratorTest;
};
#endif

View file

@ -76,7 +76,7 @@ namespace
typedef SingletonHolder<MyClass<19>, CreateStatic, SingletonWithLongevity, SingleThreaded> t19;
typedef SingletonHolder<MyClass<20>, CreateStatic, NoDestroy, SingleThreaded> t20;
#if !__INTEL_COMPILER && !__GNUC__ && !_MSC_VER
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
typedef SingletonHolder<MyClass<5>, CreateUsingNew, DefaultLifetime, ClassLevelLockable> t5;
typedef SingletonHolder<MyClass<6>, CreateUsingNew, PhoenixSingleton, ClassLevelLockable> t6;
@ -126,7 +126,7 @@ public:
MAKE_TEST(t19)
MAKE_TEST(t20)
#if !__INTEL_COMPILER && !__GNUC__ && !_MSC_VER
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
MAKE_TEST(t5)
MAKE_TEST(t6)

View file

@ -9,26 +9,29 @@
//
// This software is provided "as is" without express or implied warranty.
//
// Last update: October 10, 2002
// Last update: October 12, 2002
///////////////////////////////////////////////////////////////////////////////
#ifdef __INTEL_COMPILER
# pragma warning(disable: 111 193 304 383 444 488 981 1418)
#elif defined(_MSC_VER) && !defined(__MWERKS__)
# pragma warning(disable: 4018 4097 4100 4213 4290 4512 4514 4700 4702 4710 4786 4800)
#endif
//Some platforms might have difficulty with this
//Need to ifdef around those cases.
//TODOSGB
// Some platforms might have difficulty with this
// Need to ifdef around those cases.
// TODO SGB
#include "UnitTest.h"
//static variable defintion, do not remove
// static variable defintion, do not remove
Test::tests_type Test::tests;
//Merely comment out any of the following headers to
// Merely comment out any of the following headers to
// prevent thier execution during the test.
//A pluggable-factory-like method is used to
//
// A pluggable-factory-like method is used to
// auto-register the test, so all that is needed
// is the header inclusion to execute the correspond
// unit test.
@ -45,7 +48,6 @@ Test::tests_type Test::tests;
#include "FunctorTest.h"
#include "DataGeneratorsTest.h"
/*
* AP - All Pass
* FC - Fails to Compile
@ -53,29 +55,37 @@ Test::tests_type Test::tests;
*
* TypelistTest TypeManipTest TypeTraitsTest SmallObjectTest SingletonTest
* gcc 2.95.3 ? ? ? ? ?
* gcc 3.2 AP AP AP AP P #ifdef?
* MSVC 6 ? ? ? ? ?
* MSVC 7 AP Conversion FC AP P #ifdef?
* Intel ? ? ? ? ? ?
* BCB 5.5? ? ? ? ? ?
* gcc 3.2 AP AP AP AP P (Only SingleThreaded)
* MSVC 6.0 P AP FC FC AP
* MSVC 7.0 AP Conversion FC AP P (Only SingleThreaded) ?
* Intel 5.0 AP AP AP FC FC
* Intel 6.0 AP AP AP FC P (Only SingleThreaded)
* Intel 7.0 AP AP AP FC P (Only SingleThreaded)
* BCC 5.5 ? ? ? ? ?
* BCC 5.6 ? ? ? ? ?
* CW 6.0 ? ? ? ? ?
*
* SmartPtrTest FactoryTest AbstractFactoryTest AssocVectorTest FunctorTest
* gcc 2.95.3 ? ? ? ? ?
* gcc 3.2 FC AP AP FC AP
* MSVC 6 ? ? ? ? ?
* MSVC 7 FC AP AP FC AP
* Intel ? ? ? ? ? ?
* BCB 5.5? ? ? ? ? ?
* MSVC 6.0 FC AP FC FC FC
* MSVC 7.0 FC AP AP FC AP
* Intel 5.0 FC FC FC FC FC
* Intel 6.0 FC AP AP FC FC
* Intel 7.0 FC AP AP FC FC
* BCC 5.5 ? ? ? ? ?
* CW 6.0 ? ? ? ? ?
*
* DataGeneratorsTest
* gcc 2.95.3 ?
* gcc 3.2 AP
* MSVC 6 ?
* MSVC 7 AP
* Intel ? ?
* BCB 5.5? ?
* MSVC 6.0 FC
* MSVC 7.0 AP
* Intel 5.0 FC
* Intel 6.0 AP
* Intel 7.0 AP
* BCC 5.5 ?
* BCC 5.6 ?
* CW 6.0 ?
*/
@ -85,10 +95,8 @@ int main()
int result = Test::run("Loki Unit Test");
#if __BORLANDC__
while(true); // Stop console window from closing if run from IDE.
#elif _MSC_VER || __GNUC__
system("pause");
#if defined(__BORLANDC__) || defined(__GNUC__)
system("pause"); // Stop console window from closing if run from IDE.
#endif
return result;

View file

@ -25,12 +25,12 @@
// SameType
///////////////////////////////////////////////////////////////////////////////
#if _MSC_VER && !__INTEL_COMPILER && !__MWERKS__
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
// Rani Sharoni's SameType
//
// Non-conforming workaround for MSVC
//This is non-standard code, you are not allowed to
// specialize a nested template
template<class T1,class T2>
struct SameType
{