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;
|
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
|
} // namespace Loki
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -152,23 +184,23 @@ namespace Loki
|
||||||
// same type.
|
// same type.
|
||||||
//
|
//
|
||||||
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
// Deprecated: Use SuperSubclass class template instead.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define SUPERSUBCLASS(T, U) \
|
#define SUPERSUBCLASS(T, U) \
|
||||||
(::Loki::Conversion<const volatile U *, const volatile T *>::exists && \
|
::Loki::SuperSubclass<T,U>::value
|
||||||
!::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// macro SUPERSUBCLASS
|
// macro SUPERSUBCLASS_STRICT
|
||||||
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
||||||
// Returns true if B is a public base of D.
|
// Returns true if B is a public base of D.
|
||||||
//
|
//
|
||||||
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
// 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) \
|
#define SUPERSUBCLASS_STRICT(T, U) \
|
||||||
((SUPERSUBCLASS(T, U) && \
|
::Loki::SuperSubclassStrict<T,U>::value
|
||||||
!::Loki::Conversion<const volatile T *, const volatile U *>::sameType))
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Change log:
|
// Change log:
|
||||||
|
@ -179,6 +211,8 @@ namespace Loki
|
||||||
// November 23, 2001: (well it's 12:01 am) fixed bug in SUPERSUBCLASS - added
|
// November 23, 2001: (well it's 12:01 am) fixed bug in SUPERSUBCLASS - added
|
||||||
// the volatile qualifier to be 100% politically correct
|
// the volatile qualifier to be 100% politically correct
|
||||||
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
|
// 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_
|
#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_
|
#endif // TYPELIST_INC_
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,38 @@ public:
|
||||||
enum { sameType = Chooser::sameType };
|
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
|
} // namespace Loki
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -241,28 +273,30 @@ public:
|
||||||
// same type.
|
// same type.
|
||||||
//
|
//
|
||||||
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
// Deprecated: Use SuperSubclass class template instead.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define SUPERSUBCLASS(T, U) \
|
#define SUPERSUBCLASS(T, U) \
|
||||||
(::Loki::Conversion<const U*, const T*>::exists && \
|
::Loki::SuperSubclass<T,U>::value
|
||||||
!::Loki::Conversion<const T*, const void*>::sameType)
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// macro SUPERSUBCLASS
|
// macro SUPERSUBCLASS_STRICT
|
||||||
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
||||||
// Returns true if B is a public base of D.
|
// Returns true if B is a public base of D.
|
||||||
//
|
//
|
||||||
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
// 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) \
|
#define SUPERSUBCLASS_STRICT(T, U) \
|
||||||
(SUPERSUBCLASS(T, U) && \
|
::Loki::SuperSubclassStrict<T,U>::value
|
||||||
!::Loki::Conversion<const T, const U>::sameType)
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Change log:
|
// Change log:
|
||||||
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
// August 22, 2001: ported by Jonathan H Lundquist to MSVC
|
// 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_
|
#endif // TYPEMANIP_INC_
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
MSVC6
|
|
||||||
Jonathan H. Lundquist
|
|
|
@ -175,15 +175,6 @@ namespace Loki
|
||||||
enum { sameType = (SameType<T, U>::value) };
|
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
|
// class template SuperSubclass
|
||||||
// Invocation: SuperSubclass<B, D>::value where B and D are types.
|
// 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) };
|
!::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SUPERSUBCLASS(T, U) \
|
} // namespace Loki
|
||||||
(::Loki::Conversion<const volatile U*, const volatile T*>::exists && \
|
|
||||||
!::Loki::Conversion<const volatile T*, const volatile void*>::sameType)
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// macro SUPERSUBCLASS
|
// macro SUPERSUBCLASS
|
||||||
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
// 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.
|
// Returns true if B is a public base of D.
|
||||||
//
|
//
|
||||||
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
// 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) \
|
#define SUPERSUBCLASS_STRICT(T, U) \
|
||||||
(SUPERSUBCLASS(T, U) && \
|
::Loki::SuperSubclassStrict<T,U>::value
|
||||||
!::Loki::Conversion<const volatile T *, const volatile U *>::sameType)
|
|
||||||
|
|
||||||
} // namespace Loki
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Change log:
|
// Change log:
|
||||||
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
// 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)
|
// 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_
|
#endif // TYPEMANIP_INC_
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
#include <loki/AssocVector.h>
|
#include <loki/AssocVector.h>
|
||||||
#include "UnitTest.h"
|
#include "UnitTest.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
|
||||||
|
#define C_Namespace
|
||||||
|
#else
|
||||||
|
#define C_Namespace std
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// AssocVectorTest
|
// AssocVectorTest
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -36,16 +42,22 @@ public:
|
||||||
typedef const value_type* const_pointer;
|
typedef const value_type* const_pointer;
|
||||||
typedef value_type& reference;
|
typedef value_type& reference;
|
||||||
typedef const value_type& const_reference;
|
typedef const value_type& const_reference;
|
||||||
typedef std::size_t size_type;
|
typedef C_Namespace::size_t size_type;
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef C_Namespace::ptrdiff_t difference_type;
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
struct rebind { typedef TestAllocator<U> other; };
|
struct rebind { typedef TestAllocator<U> other; };
|
||||||
|
|
||||||
TestAllocator() {}
|
TestAllocator() {}
|
||||||
TestAllocator(const TestAllocator&) {}
|
TestAllocator(const TestAllocator&) {}
|
||||||
|
|
||||||
|
#if !(defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__))
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
TestAllocator(const TestAllocator<U>&) {}
|
TestAllocator(const TestAllocator<U>&) {}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
~TestAllocator() {}
|
~TestAllocator() {}
|
||||||
|
|
||||||
pointer address(reference x) const { return &x; }
|
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)
|
void check_insert1(test_vect1_t& v)
|
||||||
{
|
{
|
||||||
std::srand(10);
|
C_Namespace::srand(10);
|
||||||
for (unsigned i = 0; i < 100; ++i) {
|
for (unsigned i = 0; i < 100; ++i) {
|
||||||
int x = std::rand();
|
int x = C_Namespace::rand();
|
||||||
v.insert(std::make_pair(x, x));
|
v.insert(std::make_pair(x, x));
|
||||||
assert(is_sorted(v));
|
assert(is_sorted(v));
|
||||||
}
|
}
|
||||||
|
@ -272,11 +284,11 @@ void test_vect3()
|
||||||
// 3) or recompile STLPort DLL.
|
// 3) or recompile STLPort DLL.
|
||||||
// This all is related to bug in STLPort allocator.
|
// This all is related to bug in STLPort allocator.
|
||||||
test_vect3_t vec31;
|
test_vect3_t vec31;
|
||||||
std::srand(111);
|
C_Namespace::srand(111);
|
||||||
// a stress test
|
// a stress test
|
||||||
for (unsigned i = 0; i < 2 * 1000; ++i) {
|
for (unsigned i = 0; i < 2 * 1000; ++i) {
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
std::sprintf(buffer, "string%d", std::rand());
|
C_Namespace::sprintf(buffer, "string%d", C_Namespace::rand());
|
||||||
std::string s(buffer);
|
std::string s(buffer);
|
||||||
vec31.insert(std::make_pair(s, s));
|
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<19>, CreateStatic, SingletonWithLongevity, SingleThreaded> t19;
|
||||||
typedef SingletonHolder<MyClass<20>, CreateStatic, NoDestroy, SingleThreaded> t20;
|
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<5>, CreateUsingNew, DefaultLifetime, ClassLevelLockable> t5;
|
||||||
typedef SingletonHolder<MyClass<6>, CreateUsingNew, PhoenixSingleton, ClassLevelLockable> t6;
|
typedef SingletonHolder<MyClass<6>, CreateUsingNew, PhoenixSingleton, ClassLevelLockable> t6;
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
MAKE_TEST(t19)
|
MAKE_TEST(t19)
|
||||||
MAKE_TEST(t20)
|
MAKE_TEST(t20)
|
||||||
|
|
||||||
#if !__INTEL_COMPILER && !__GNUC__ && !_MSC_VER
|
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
|
||||||
|
|
||||||
MAKE_TEST(t5)
|
MAKE_TEST(t5)
|
||||||
MAKE_TEST(t6)
|
MAKE_TEST(t6)
|
||||||
|
|
|
@ -9,26 +9,29 @@
|
||||||
//
|
//
|
||||||
// This software is provided "as is" without express or implied warranty.
|
// This software is provided "as is" without express or implied warranty.
|
||||||
//
|
//
|
||||||
// Last update: October 10, 2002
|
// Last update: October 12, 2002
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef __INTEL_COMPILER
|
#ifdef __INTEL_COMPILER
|
||||||
# pragma warning(disable: 111 193 304 383 444 488 981 1418)
|
# 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
|
#endif
|
||||||
|
|
||||||
//Some platforms might have difficulty with this
|
// Some platforms might have difficulty with this
|
||||||
//Need to ifdef around those cases.
|
// Need to ifdef around those cases.
|
||||||
//TODOSGB
|
// TODO SGB
|
||||||
|
|
||||||
#include "UnitTest.h"
|
#include "UnitTest.h"
|
||||||
|
|
||||||
//static variable defintion, do not remove
|
// static variable defintion, do not remove
|
||||||
|
|
||||||
Test::tests_type Test::tests;
|
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.
|
// 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
|
// auto-register the test, so all that is needed
|
||||||
// is the header inclusion to execute the correspond
|
// is the header inclusion to execute the correspond
|
||||||
// unit test.
|
// unit test.
|
||||||
|
@ -45,7 +48,6 @@ Test::tests_type Test::tests;
|
||||||
#include "FunctorTest.h"
|
#include "FunctorTest.h"
|
||||||
#include "DataGeneratorsTest.h"
|
#include "DataGeneratorsTest.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AP - All Pass
|
* AP - All Pass
|
||||||
* FC - Fails to Compile
|
* FC - Fails to Compile
|
||||||
|
@ -53,29 +55,37 @@ Test::tests_type Test::tests;
|
||||||
*
|
*
|
||||||
* TypelistTest TypeManipTest TypeTraitsTest SmallObjectTest SingletonTest
|
* TypelistTest TypeManipTest TypeTraitsTest SmallObjectTest SingletonTest
|
||||||
* gcc 2.95.3 ? ? ? ? ?
|
* gcc 2.95.3 ? ? ? ? ?
|
||||||
* gcc 3.2 AP AP AP AP P #ifdef?
|
* gcc 3.2 AP AP AP AP P (Only SingleThreaded)
|
||||||
* MSVC 6 ? ? ? ? ?
|
* MSVC 6.0 P AP FC FC AP
|
||||||
* MSVC 7 AP Conversion FC AP P #ifdef?
|
* MSVC 7.0 AP Conversion FC AP P (Only SingleThreaded) ?
|
||||||
* Intel ? ? ? ? ? ?
|
* Intel 5.0 AP AP AP FC FC
|
||||||
* BCB 5.5? ? ? ? ? ?
|
* 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 ? ? ? ? ?
|
* CW 6.0 ? ? ? ? ?
|
||||||
*
|
*
|
||||||
* SmartPtrTest FactoryTest AbstractFactoryTest AssocVectorTest FunctorTest
|
* SmartPtrTest FactoryTest AbstractFactoryTest AssocVectorTest FunctorTest
|
||||||
* gcc 2.95.3 ? ? ? ? ?
|
* gcc 2.95.3 ? ? ? ? ?
|
||||||
* gcc 3.2 FC AP AP FC AP
|
* gcc 3.2 FC AP AP FC AP
|
||||||
* MSVC 6 ? ? ? ? ?
|
* MSVC 6.0 FC AP FC FC FC
|
||||||
* MSVC 7 FC AP AP FC AP
|
* MSVC 7.0 FC AP AP FC AP
|
||||||
* Intel ? ? ? ? ? ?
|
* Intel 5.0 FC FC FC FC FC
|
||||||
* BCB 5.5? ? ? ? ? ?
|
* Intel 6.0 FC AP AP FC FC
|
||||||
|
* Intel 7.0 FC AP AP FC FC
|
||||||
|
* BCC 5.5 ? ? ? ? ?
|
||||||
* CW 6.0 ? ? ? ? ?
|
* CW 6.0 ? ? ? ? ?
|
||||||
*
|
*
|
||||||
* DataGeneratorsTest
|
* DataGeneratorsTest
|
||||||
* gcc 2.95.3 ?
|
* gcc 2.95.3 ?
|
||||||
* gcc 3.2 AP
|
* gcc 3.2 AP
|
||||||
* MSVC 6 ?
|
* MSVC 6.0 FC
|
||||||
* MSVC 7 AP
|
* MSVC 7.0 AP
|
||||||
* Intel ? ?
|
* Intel 5.0 FC
|
||||||
* BCB 5.5? ?
|
* Intel 6.0 AP
|
||||||
|
* Intel 7.0 AP
|
||||||
|
* BCC 5.5 ?
|
||||||
|
* BCC 5.6 ?
|
||||||
* CW 6.0 ?
|
* CW 6.0 ?
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -85,10 +95,8 @@ int main()
|
||||||
|
|
||||||
int result = Test::run("Loki Unit Test");
|
int result = Test::run("Loki Unit Test");
|
||||||
|
|
||||||
#if __BORLANDC__
|
#if defined(__BORLANDC__) || defined(__GNUC__)
|
||||||
while(true); // Stop console window from closing if run from IDE.
|
system("pause"); // Stop console window from closing if run from IDE.
|
||||||
#elif _MSC_VER || __GNUC__
|
|
||||||
system("pause");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -25,12 +25,12 @@
|
||||||
// SameType
|
// SameType
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if _MSC_VER && !__INTEL_COMPILER && !__MWERKS__
|
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
|
||||||
|
|
||||||
// Rani Sharoni's SameType
|
// 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>
|
template<class T1,class T2>
|
||||||
struct SameType
|
struct SameType
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue