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:
parent
52020f94e0
commit
08bd05c8c4
27 changed files with 2717 additions and 1276 deletions
|
@ -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
335
MSVC/1200/AssocVector.h
Normal 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
37
MSVC/1200/EmptyType.h
Normal 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
153
MSVC/1200/Factory.h
Normal 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
39
MSVC/1200/NullType.h
Normal 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
53
MSVC/1200/Singleton.cpp
Normal 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
499
MSVC/1200/Singleton.h
Normal 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
213
MSVC/1200/Threads.h
Normal 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
106
MSVC/1200/TypeInfo.h
Normal 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_
|
|
@ -786,4 +786,3 @@ public:
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // TYPELIST_INC_
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
MSVC6
|
||||
Jonathan H. Lundquist
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue