No message

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@40 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
tslettebo 2002-08-23 07:22:07 +00:00
parent 5ca0b883b1
commit b5d2cd3d11
23 changed files with 742 additions and 1184 deletions

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.04; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef ABSTRACTFACTORY_INC_
#define ABSTRACTFACTORY_INC_
@ -181,8 +159,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // ABSTRACTFACTORY_INC_
@

View file

@ -1,40 +1,20 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.04; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// 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 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"
// 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: August 9, 2002
#ifndef ASSOCVECTOR_INC_
#define ASSOCVECTOR_INC_
@ -62,21 +42,21 @@ namespace Loki
public:
AssocVectorCompare()
{}
AssocVectorCompare(const C& src) : C(src)
{}
bool operator()(const first_argument_type& lhs,
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,
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); }
@ -94,8 +74,6 @@ namespace Loki
// * iterators are random
////////////////////////////////////////////////////////////////////////////////
#ifdef __BORLANDC__
template
<
class K,
@ -103,7 +81,7 @@ namespace Loki
class C = std::less<K>,
class A = std::allocator< std::pair<K, V> >
>
class AssocVector
class AssocVector
: private std::vector< std::pair<K, V>, A >
, private Private::AssocVectorCompare<V, C>
{
@ -128,12 +106,12 @@ namespace Loki
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
class value_compare
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)
{}
@ -142,278 +120,28 @@ namespace Loki
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())
: std::vector< std::pair<K, V>, A >(alloc), MyCompare(comp)
{}
template <class InputIterator>
AssocVector(InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const A& alloc = A())
: std::vector< std::pair<K, V>, A >(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 std::vector< std::pair<K, V>, A >::begin(); }
const_iterator begin() const { return std::vector< std::pair<K, V>, A >::begin(); }
iterator end() { return std::vector< std::pair<K, V>, A >::end(); }
const_iterator end() const { return std::vector< std::pair<K, V>, A >::end(); }
reverse_iterator rbegin() { return std::vector< std::pair<K, V>, A >::rbegin(); }
const_reverse_iterator rbegin() const { return std::vector< std::pair<K, V>, A >::rbegin(); }
reverse_iterator rend() { return std::vector< std::pair<K, V>, A >::rend(); }
const_reverse_iterator rend() const { return std::vector< std::pair<K, V>, A >::rend(); }
// capacity:
bool empty() const { return std::vector< std::pair<K, V>, A >::empty(); }
size_type size() const { return std::vector< std::pair<K, V>, A >::size(); }
size_type max_size() { return std::vector< std::pair<K, V>, A >::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 = std::vector< std::pair<K, V>, A >::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 std::vector< std::pair<K, V>, A >::insert(pos, val);
}
return insert(val).first;
}
template <class InputIterator>
iterator insert(InputIterator first, InputIterator last)
{ for (; first != last; ++first) insert(*first); }
void erase(iterator pos)
{ std::vector< std::pair<K, V>, A >::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)
{ std::vector< std::pair<K, V>, A >::erase(first, last); }
void swap(AssocVector& other)
{
using namespace std;
std::vector< std::pair<K, V>, A >::swap(other);
MyCompare& me = *this;
MyCompare& rhs = other;
swap(me, rhs);
}
void clear()
{ std::vector< std::pair<K, V>, A >::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 std::vector< std::pair<K, V>, A >& me = lhs;
return me == rhs;
}
bool operator<(const AssocVector& rhs) const
{
const std::vector< std::pair<K, V>, A >& me = *this;
const std::vector< std::pair<K, V>, A >& 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); }
#else
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(),
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(),
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;
{
AssocVector<K, V, C, A>(rhs).swap(*this); // ### Borland fix: template params added to cast
return *this;
}
// iterators:
@ -426,7 +154,7 @@ namespace Loki
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(); }
@ -452,7 +180,7 @@ namespace Loki
iterator insert(iterator pos, const value_type& val)
{
if (pos != end() && operator()(*pos, val) &&
if (pos != end() && operator()(*pos, val) &&
(pos == end() - 1 ||
!operator()(val, pos[1]) &&
operator()(pos[1], val)))
@ -461,11 +189,11 @@ namespace Loki
}
return insert(val).first;
}
template <class InputIterator>
iterator insert(InputIterator first, InputIterator last)
void insert(InputIterator first, InputIterator last)
{ for (; first != last; ++first) insert(*first); }
void erase(iterator pos)
{ Base::erase(pos); }
@ -482,13 +210,13 @@ namespace Loki
void swap(AssocVector& other)
{
using namespace std;
using std::swap;
Base::swap(other);
MyCompare& me = *this;
MyCompare& rhs = other;
swap(me, rhs);
}
void clear()
{ Base::clear(); }
@ -514,7 +242,7 @@ namespace Loki
}
const_iterator find(const key_type& k) const
{
{
const_iterator i(lower_bound(k));
if (i != end() && operator()(k, i->first))
{
@ -562,28 +290,28 @@ namespace Loki
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); }
{ 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); }
{ return !(lhs < rhs); }
friend bool operator<=(const AssocVector& lhs, const AssocVector& rhs)
{ return !(rhs < lhs); }
@ -593,9 +321,7 @@ namespace Loki
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); }
#endif
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
@ -604,8 +330,9 @@ namespace Loki
// 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
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// June 25, 2002: fixed template insert() - credit due to Robert Minsk
// June 27, 2002: fixed member swap() - credit due to David Brookman
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // ASSOCVECTOR_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef EMPTYTYPE_INC_
#define EMPTYTYPE_INC_
@ -54,8 +32,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // EMPTYTYPE_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,12 +13,12 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef FACTORY_INC_
#define FACTORY_INC_
#include "TypeInfo.h"
#include "Loki_TypeInfo.h"
#include "AssocVector.h"
#include <exception>
@ -57,13 +35,9 @@ namespace Loki
{
struct Exception : public std::exception
{
#ifdef __BORLANDC__
const char* what() { return "Unknown Type"; }
#else
const char* what() const { return "Unknown Type"; }
#endif
const char* what() const throw() { return "Unknown Type"; }
};
static AbstractProduct* OnUnknownType(IdentifierType)
{
throw Exception();
@ -77,16 +51,18 @@ namespace Loki
template
<
class AbstractProduct,
class AbstractProduct,
typename IdentifierType,
typename ProductCreator = AbstractProduct* (*)(),
template<typename, class>
class FactoryErrorPolicy = DefaultFactoryError
>
class Factory
class Factory
: public FactoryErrorPolicy<IdentifierType, AbstractProduct>
{
public:
typedef ProductCreator ProductCreator; //### added for convenience, Pavel
bool Register(const IdentifierType& id, ProductCreator creator)
{
return associations_.insert(
@ -100,7 +76,7 @@ namespace Loki
AbstractProduct* CreateObject(const IdentifierType& id)
{
typename IdToProductMap::const_iterator i = associations_.find(id);
typename IdToProductMap::iterator i = associations_.find(id);
if (i != associations_.end())
{
return (i->second)();
@ -121,7 +97,7 @@ namespace Loki
template
<
class AbstractProduct,
class ProductCreator =
class ProductCreator =
AbstractProduct* (*)(const AbstractProduct*),
template<typename, class>
class FactoryErrorPolicy = DefaultFactoryError
@ -130,6 +106,8 @@ namespace Loki
: public FactoryErrorPolicy<TypeInfo, AbstractProduct>
{
public:
typedef ProductCreator ProductCreator; //### added for convenience, Pavel
bool Register(const TypeInfo& ti, ProductCreator creator)
{
return associations_.insert(
@ -145,7 +123,7 @@ namespace Loki
{
if (model == 0) return 0;
typename IdToProductMap::const_iterator i =
typename IdToProductMap::iterator i =
associations_.find(typeid(*model));
if (i != associations_.end())
{
@ -163,8 +141,10 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// 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.
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // FACTORY_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef FUNCTOR_INC_
#define FUNCTOR_INC_
@ -738,7 +716,7 @@ namespace Loki
// A generalized functor implementation with value semantics
////////////////////////////////////////////////////////////////////////////////
template <typename R, class TList = NullType,
template <typename R = void, class TList = NullType,
template<class> class ThreadingModel = DEFAULT_THREADING>
class Functor
{
@ -1161,8 +1139,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // FUNCTOR_INC_
@

View file

@ -1,41 +1,19 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// 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 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"
// 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: March 05, 2001
// Last update: August 9, 2002
#ifndef HIERARCHYGENERATORS_INC_
#define HIERARCHYGENERATORS_INC_
@ -51,13 +29,13 @@ namespace Loki
// Generates a scattered hierarchy starting from a typelist and a template
// Invocation (TList is a typelist, Model is a template of one arg):
// GenScatterHierarchy<TList, Model>
// The generated class inherits all classes generated by instantiating the
// template 'Model' with the types contained in TList
// The generated class inherits all classes generated by instantiating the
// template 'Model' with the types contained in TList
////////////////////////////////////////////////////////////////////////////////
template <class TList, template <class> class Unit>
class GenScatterHierarchy;
template <class T1, class T2, template <class> class Unit>
class GenScatterHierarchy<Typelist<T1, T2>, Unit>
: public GenScatterHierarchy<T1, Unit>
@ -72,7 +50,7 @@ namespace Loki
typedef Unit<T> Result;
};
};
template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType>
{
@ -82,7 +60,7 @@ namespace Loki
typedef Unit<T> Result;
};
};
template <template <class> class Unit>
class GenScatterHierarchy<NullType, Unit>
{
@ -91,31 +69,31 @@ namespace Loki
typedef Unit<T> Result;
};
};
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
// T is a type in the typelist used to generate H):
// Field<T>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
// returns a reference to Unit<T>, where Unit is the template used to generate H
////////////////////////////////////////////////////////////////////////////////
template <class T, class H>
typename H::Rebind<T>::Result& Field(H& obj)
typename H::template Rebind<T>::Result& Field(H& obj)
{
return obj;
}
template <class T, class H>
const typename H::Rebind<T>::Result& Field(const H& obj)
const typename H::template Rebind<T>::Result& Field(const H& obj)
{
return obj;
}
////////////////////////////////////////////////////////////////////////////////
// function template TupleUnit
// The building block of tuples
// The building block of tuples
////////////////////////////////////////////////////////////////////////////////
template <class T>
@ -128,30 +106,41 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// class template Tuple
// Implements a tuple class that holds a number of values and provides field
// access to them via the Field function (below)
// Implements a tuple class that holds a number of values and provides field
// access to them via the Field function (below)
////////////////////////////////////////////////////////////////////////////////
// template <class TList>
// struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
// {
// };
template <class TList>
struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
{
};
////////////////////////////////////////////////////////////////////////////////
// helper class template FieldHelper
// See Field below
////////////////////////////////////////////////////////////////////////////////
//### BCB: the problem of not treating enum as bool value, like in MultiMethods
template <int flag, typename T, typename U>
struct IntSelect
{
typedef T Result;
};
template <typename T, typename U>
struct IntSelect<0, T, U>
{
typedef U Result;
};
/*
template <class H, unsigned int i> struct FieldHelper;
template <class H>
struct FieldHelper<H, 0>
{
typedef typename H::TList::Head ElementType;
typedef typename H::Rebind<ElementType>::Result UnitType;
typedef typename H::template Rebind<ElementType>::Result UnitType;
enum
{
isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
@ -159,16 +148,16 @@ namespace Loki
};
typedef const typename H::LeftBase ConstLeftBase;
typedef typename Select<isConst, ConstLeftBase,
typedef typename IntSelect<isConst, ConstLeftBase,
typename H::LeftBase>::Result LeftBase;
typedef typename Select<isTuple, ElementType,
typedef typename IntSelect<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
typedef typename IntSelect<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj)
{
LeftBase& leftBase = obj;
@ -180,7 +169,7 @@ namespace Loki
struct FieldHelper
{
typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
typedef typename H::Rebind<ElementType>::Result UnitType;
typedef typename H::template Rebind<ElementType>::Result UnitType;
enum
{
@ -190,15 +179,15 @@ namespace Loki
typedef const typename H::RightBase ConstRightBase;
typedef typename Select<isConst, ConstRightBase,
typedef typename IntSelect<isConst, ConstRightBase,
typename H::RightBase>::Result RightBase;
typedef typename Select<isTuple, ElementType,
typedef typename IntSelect<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
typedef typename IntSelect<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj)
{
RightBase& rightBase = obj;
@ -206,8 +195,6 @@ namespace Loki
}
};
*/
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
@ -215,27 +202,23 @@ namespace Loki
// i is the index of a type in the typelist used to generate H):
// Field<i>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
// and T is the i-th type in the typelist
// and T is the i-th type in the typelist
////////////////////////////////////////////////////////////////////////////////
/*
template <int i, class H>
typename FieldHelper<H, i>::ResultType&
Field(H& obj)
{
return FieldHelper<H, i>::Do(obj);
}
template <int i, class H>
const typename FieldHelper<H, i>::ResultType&
Field(const H& obj)
{
return FieldHelper<H, i>::Do(obj);
}
*/
// template <int i, class H>
// const typename FieldHelper<H, i>::ResultType&
// Field(const H& obj)
// {
// return FieldHelper<H, i>::Do(obj);
// }
////////////////////////////////////////////////////////////////////////////////
// class template GenLinearHierarchy
// Generates a linear hierarchy starting from a typelist and a template
@ -279,8 +262,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // HIERARCHYGENERATORS_INC_
@

View file

@ -1,49 +1,28 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// 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 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"
// 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
// Last update: August 9, 2002
#ifndef MULTIMETHODS_INC_
#define MULTIMETHODS_INC_
#include "Typelist.h"
#include "TypeInfo.h"
#include "Loki_TypeInfo.h" //### BCB
#include "Functor.h"
#include "AssocVector.h"
#include <iostream> // ***
////////////////////////////////////////////////////////////////////////////////
// IMPORTANT NOTE:
@ -60,25 +39,50 @@ namespace Loki
namespace Private
{
template <class SomeLhs, class SomeRhs,
class Executor, typename ResultType>
/* ### BCB checks existence Fire(rhs, lhs) even when this function is not
needed, fails to compile
template <class SomeLhs, class SomeRhs,
class Executor, typename ResultType>
struct InvocationTraits
{
static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<false>)
static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<false>)
{
return exec.Fire(lhs, rhs);
}
static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<true>)
static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<true>)
{
return exec.Fire(rhs, lhs);
}
};
*/
template <class SomeLhs, class SomeRhs, class Executor, typename
ResultType>
struct NormalInvocation
{
static ResultType DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec)
{
return exec.Fire(lhs, rhs);
}
};
template <class SomeLhs, class SomeRhs, class Executor, typename
ResultType>
struct SwappedInvocation
{
static ResultType DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec)
{
return exec.Fire(rhs, lhs);
}
};
}
////////////////////////////////////////////////////////////////////////////////
// class template StaticDispatcher
// Implements an automatic static double dispatcher based on two typelists
@ -87,7 +91,7 @@ namespace Loki
template
<
class Executor,
class BaseLhs,
class BaseLhs,
class TypesLhs,
bool symmetric = true,
class BaseRhs = BaseLhs,
@ -100,39 +104,43 @@ namespace Loki
static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
Executor exec, NullType)
{ return exec.OnError(lhs, rhs); }
template <class TList, class SomeLhs>
static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
Executor exec, TList)
{
typedef typename TList::Head Head;
typedef typename TList::Tail Tail;
if (Head* p2 = dynamic_cast<Head*>(&rhs))
{
Int2Type<(symmetric &&
int(TL::IndexOf<TypesRhs, Head>::value) <
int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t;
//### BCB - original statement was too complex for this compiler
enum { val1 = int(TL::IndexOf<TypesRhs, Head>::value) };
enum { val2 = int(TL::IndexOf<TypesLhs, SomeLhs>::value) };
enum { val3 = symmetric && (val1 < val2) };
// BCB doesn't properly converts enum to bool
enum { val4 = val3 != 0 };
const bool val5 = (val4 == 0) ? false : true; // it must be so clumsy
typedef Private::InvocationTraits<
SomeLhs, Head, Executor, ResultType> CallTraits;
return CallTraits::DoDispatch(lhs, *p2, exec, i2t);
typedef Private::NormalInvocation<SomeLhs, Head, Executor, ResultType> t1;
typedef Private::SwappedInvocation<SomeLhs, Head, Executor, ResultType> t2;
typedef Select<val4, t1, t2>::Result invocation_t;
return invocation_t::DoDispatch(lhs, *p2, exec);
}
return DispatchRhs(lhs, rhs, exec, Tail());
}
static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
Executor exec, NullType)
{ return exec.OnError(lhs, rhs); }
template <class TList>
static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
Executor exec, TList)
{
typedef typename TList::Head Head;
typedef typename TList::Tail Tail;
if (Head* p1 = dynamic_cast<Head*>(&lhs))
{
return DispatchRhs(*p1, rhs, exec, TypesRhs());
@ -145,7 +153,7 @@ namespace Loki
Executor exec)
{ return DispatchLhs(lhs, rhs, exec, TypesLhs()); }
};
////////////////////////////////////////////////////////////////////////////////
// class template BasicDispatcher
// Implements a logarithmic double dispatcher for functors (or functions)
@ -165,53 +173,55 @@ namespace Loki
typedef CallbackType MappedType;
typedef AssocVector<KeyType, MappedType> MapType;
MapType callbackMap_;
void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun);
bool DoRemove(TypeInfo lhs, TypeInfo rhs);
public:
template <class SomeLhs, class SomeRhs>
void Add(CallbackType fun)
{
DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun);
}
template <class SomeLhs, class SomeRhs>
bool Remove()
{
return DoRemove(typeid(SomeLhs), typeid(SomeRhs));
}
ResultType Go(BaseLhs& lhs, BaseRhs& rhs);
};
// Non-inline to reduce compile time overhead...
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
void BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun)
::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun)
{
callbackMap_[KeyType(lhs, rhs)] = fun;
}
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
bool BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::DoRemove(TypeInfo lhs, TypeInfo rhs)
{
return callbackMap_.erase(KeyType(lhs, rhs)) == 1;
}
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
ResultType BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::Go(BaseLhs& lhs, BaseRhs& rhs)
{
typename MapType::key_type k(typeid(lhs),typeid(rhs));
typename MapType::key_type k(typeid(lhs),typeid(rhs));
typename MapType::iterator i = callbackMap_.find(k);
if (i == callbackMap_.end())
{
throw std::runtime_error("Function not found");
std::cout << "Function not found\n";
// throw std::runtime_error("Function not found");
}
return (i->second)(lhs, rhs);
}
@ -252,7 +262,7 @@ namespace Loki
namespace Private
{
template <class BaseLhs, class BaseRhs,
class SomeLhs, class SomeRhs,
class SomeLhs, class SomeRhs,
typename ResultType,
class CastLhs, class CastRhs,
ResultType (*Callback)(SomeLhs&, SomeRhs&)>
@ -282,43 +292,45 @@ namespace Loki
class DispatcherBackend = BasicDispatcher>
class FnDispatcher
{
DispatcherBackend<BaseLhs, BaseRhs, ResultType,
DispatcherBackend<BaseLhs, BaseRhs, ResultType,
ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;
public:
template <class SomeLhs, class SomeRhs>
void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&))
//### BCB - here it was probably buggy
void Add(ResultType (*pFun)(SomeLhs&, SomeRhs&))
{
return backEnd_.Add<SomeLhs, SomeRhs>(pFun);
}
return backEnd_.Add<SomeLhs, SomeRhs>((ResultType (*)(BaseLhs&,
BaseRhs&))pFun);
}
template <class SomeLhs, class SomeRhs,
ResultType (*callback)(SomeLhs&, SomeRhs&)>
void Add()
{
typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>,
callback> Local;
typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>,
callback> Local;
Add<SomeLhs, SomeRhs>(&Local::Trampoline);
}
template <class SomeLhs, class SomeRhs,
ResultType (*callback)(SomeLhs&, SomeRhs&),
bool symmetric>
void Add()
{
typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>,
callback> Local;
typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>,
callback> Local;
Add<SomeLhs, SomeRhs>(&Local::Trampoline);
if (symmetric)
@ -326,7 +338,7 @@ namespace Loki
Add<SomeRhs, SomeLhs>(&Local::TrampolineR);
}
}
template <class SomeLhs, class SomeRhs>
void Remove()
{
@ -346,12 +358,12 @@ namespace Loki
namespace Private
{
template <class BaseLhs, class BaseRhs,
class SomeLhs, class SomeRhs,
typename ResultType,
class CastLhs, class CastRhs,
class Fun, bool SwapArgs>
class FunctorDispatcherHelper
template <class BaseLhs, class BaseRhs,
class SomeLhs, class SomeRhs,
typename ResultType,
class CastLhs, class CastRhs,
class Fun, bool SwapArgs>
class FunctorDispatcherHelper
{
Fun fun_;
ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>)
@ -380,50 +392,53 @@ namespace Loki
template <class BaseLhs, class BaseRhs = BaseLhs,
typename ResultType = void,
template <class, class> class CastingPolicy = DynamicCaster,
template <class, class> class CastingPolicy = DynamicCaster,
template <class, class, class, class>
class DispatcherBackend = BasicDispatcher>
class FunctorDispatcher
{
typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList;
typedef Functor<ResultType, ArgsList, DEFAULT_THREADING> FunctorType;
//### BCB - this causes compiler crash (even when only one parameter is used)
typedef Functor<ResultType, ArgsList, DEFAULT_THREADING>
FunctorType;
DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> backEnd_;
DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType>
backEnd_;
public:
template <class SomeLhs, class SomeRhs, class Fun>
void Add(const Fun& fun)
{
typedef Private::FunctorDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs, BaseLhs>,
CastingPolicy<SomeRhs, BaseRhs>,
Fun, false> Adapter;
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs, BaseLhs>,
CastingPolicy<SomeRhs, BaseRhs>,
Fun, false> Adapter;
backEnd_.Add<SomeLhs, SomeRhs>(FunctorType(Adapter(fun)));
}
}
template <class SomeLhs, class SomeRhs, bool symmetric, class Fun>
void Add(const Fun& fun)
{
Add<SomeLhs,SomeRhs>(fun);
Add<SomeLhs,SomeRhs>(fun);
if (symmetric)
{
// Note: symmetry only makes sense where BaseLhs==BaseRhs
typedef Private::FunctorDispatcherHelper<
BaseLhs, BaseLhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs, BaseLhs>,
CastingPolicy<SomeRhs, BaseLhs>,
Fun, true> AdapterR;
if (symmetric)
{
// Note: symmetry only makes sense where BaseLhs==BaseRhs
typedef Private::FunctorDispatcherHelper<
BaseLhs, BaseLhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs, BaseLhs>,
CastingPolicy<SomeRhs, BaseLhs>,
Fun, true> AdapterR;
backEnd_.Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));
}
backEnd_.Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));
}
}
template <class SomeLhs, class SomeRhs>
void Remove()
{
@ -440,8 +455,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: November 22, 2001
// Last update: August 9, 2002
#ifndef NULLTYPE_INC_
#define NULLTYPE_INC_
@ -56,8 +34,7 @@ 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
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // NULLTYPE_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @// @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#include "Singleton.h"
@ -58,7 +36,7 @@ void Loki::Private::AtExitFn()
// Don't check errors - realloc with less memory
// can't fail
pTrackerArray = static_cast<TrackerArray>(std::realloc(
pTrackerArray, sizeof(T) * --elements));
pTrackerArray, sizeof(*pTrackerArray) * --elements));
// Destroy the element
delete pTop;
}
@ -68,6 +46,6 @@ void Loki::Private::AtExitFn()
// 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
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// May 08, 2002: Refixed bug in call to realloc
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,6 +13,8 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: August 9, 2002
#ifndef SINGLETON_INC_
#define SINGLETON_INC_
@ -44,6 +24,11 @@ text
#include <cassert>
#include <cstdlib>
#include <new>
#include <string>
#ifdef __BORLANDC__
# define ATEXIT_FIXED
#endif
namespace Loki
{
@ -65,7 +50,7 @@ namespace Loki
static bool Compare(const LifetimeTracker* lhs,
const LifetimeTracker* rhs)
{
return rhs->longevity_ > lhs->longevity_;
return lhs->longevity_ > rhs->longevity_;
}
private:
@ -125,7 +110,7 @@ namespace Loki
TrackerArray pNewArray = static_cast<TrackerArray>(
std::realloc(pTrackerArray,
sizeof(T) * (elements + 1)));
sizeof(*pTrackerArray) * (elements + 1)));
if (!pNewArray) throw std::bad_alloc();
// Delayed assignment for exception safety
@ -225,7 +210,7 @@ namespace Loki
p->~T();
}
};
////////////////////////////////////////////////////////////////////////////////
// class template DefaultLifetime
// Implementation of the LifetimePolicy used by SingletonHolder
@ -236,15 +221,11 @@ namespace Loki
template <class T>
struct DefaultLifetime
{
//#ifdef __BORLANDC__
// static void ScheduleDestruction(T*, void (cdecl *pFun)())
//#else
static void ScheduleDestruction(T*, void (*pFun)())
//#endif
{ std::atexit(pFun); }
static void OnDeadReference()
{ throw std::logic_error("Dead Reference Detected"); }
{ throw std::logic_error(std::string("Dead Reference Detected")); }
};
////////////////////////////////////////////////////////////////////////////////
@ -317,7 +298,7 @@ namespace Loki
}
static void OnDeadReference()
{ throw std::logic_error("Dead Reference Detected"); }
{ throw std::logic_error(std::string("Dead Reference Detected")); }
};
////////////////////////////////////////////////////////////////////////////////
@ -467,8 +448,9 @@ namespace Loki
// Eike Petersen
// March 08, 2002: moved the assignment to pTrackerArray in SetLongevity to fix
// exception safety issue. Credit due to Kari Hoijarvi
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// May 09, 2002: Fixed bug in Compare that caused longevities to act backwards.
// Credit due to Scott McDonald.
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // SINGLETON_INC_
@

View file

@ -1,41 +1,19 @@
head 1.1;
access;
symbols;
locks; strict;
comment @// @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// 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 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"
// 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: March 20, 2001
// Last update: August 9, 2002
#include "SmallObj.h"
#include <cassert>
@ -43,6 +21,13 @@ text
using namespace Loki;
// Used by std::lower_bound in SmallObjAllocator
static bool operator <(const FixedAllocator& lhs, const FixedAllocator& rhs)
{
return lhs.BlockSize() < rhs.BlockSize();
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// FixedAllocator::Chunk::Init
// Initializes a chunk object
@ -53,7 +38,7 @@ void FixedAllocator::Chunk::Init(std::size_t blockSize, unsigned char blocks)
assert(blockSize > 0);
assert(blocks > 0);
// Overflow check
assert((blockSize * blocks) / blockSize == blocks);
assert((blockSize * blocks) / blockSize == (unsigned)blocks);
pData_ = new unsigned char[blockSize * blocks];
Reset(blockSize, blocks);
@ -69,7 +54,7 @@ void FixedAllocator::Chunk::Reset(std::size_t blockSize, unsigned char blocks)
assert(blockSize > 0);
assert(blocks > 0);
// Overflow check
assert((blockSize * blocks) / blockSize == blocks);
assert((blockSize * blocks) / blockSize == (unsigned)blocks);
firstAvailableBlock_ = 0;
blocksAvailable_ = blocks;
@ -102,7 +87,7 @@ void* FixedAllocator::Chunk::Allocate(std::size_t blockSize)
if (!blocksAvailable_) return 0;
assert((firstAvailableBlock_ * blockSize) / blockSize ==
firstAvailableBlock_);
(unsigned)firstAvailableBlock_);
unsigned char* pResult =
pData_ + (firstAvailableBlock_ * blockSize);
@ -129,7 +114,7 @@ void FixedAllocator::Chunk::Deallocate(void* p, std::size_t blockSize)
firstAvailableBlock_ = static_cast<unsigned char>(
(toRelease - pData_) / blockSize);
// Truncation check
assert(firstAvailableBlock_ == (toRelease - pData_) / blockSize);
assert((unsigned)firstAvailableBlock_ == (toRelease - pData_) / blockSize);
++blocksAvailable_;
}
@ -153,7 +138,7 @@ FixedAllocator::FixedAllocator(std::size_t blockSize)
else if (numBlocks == 0) numBlocks = 8 * blockSize;
numBlocks_ = static_cast<unsigned char>(numBlocks);
assert(numBlocks_ == numBlocks);
assert((unsigned)numBlocks_ == numBlocks);
}
////////////////////////////////////////////////////////////////////////////////
@ -256,7 +241,7 @@ void* FixedAllocator::Allocate()
}
assert(allocChunk_ != 0);
assert(allocChunk_->blocksAvailable_ > 0);
return allocChunk_->Allocate(blockSize_);
}
@ -316,6 +301,7 @@ FixedAllocator::Chunk* FixedAllocator::VicinityFind(void* p)
if (++hi == hiBound) hi = 0;
}
}
//#pragma warn -8066
assert(false);
return 0;
}
@ -342,8 +328,8 @@ void FixedAllocator::DoDeallocate(void* p)
if (&lastChunk == deallocChunk_)
{
// check if we have two last chunks empty
if (chunks_.size() > 1 &&
if (chunks_.size() > 1 &&
deallocChunk_[-1].blocksAvailable_ == numBlocks_)
{
// Two free chunks, discard the last one
@ -353,7 +339,7 @@ void FixedAllocator::DoDeallocate(void* p)
}
return;
}
if (lastChunk.blocksAvailable_ == numBlocks_)
{
// Two free blocks, discard one
@ -398,7 +384,9 @@ void* SmallObjAllocator::Allocate(std::size_t numBytes)
{
return pLastAlloc_->Allocate();
}
Pool::iterator i = std::lower_bound(pool_.begin(), pool_.end(), numBytes);
FixedAllocator aux(numBytes);
Pool::iterator i = std::lower_bound(pool_.begin(), pool_.end(), aux);
if (i == pool_.end() || i->BlockSize() != numBytes)
{
i = pool_.insert(i, FixedAllocator(numBytes));
@ -423,7 +411,8 @@ void SmallObjAllocator::Deallocate(void* p, std::size_t numBytes)
pLastDealloc_->Deallocate(p);
return;
}
Pool::iterator i = std::lower_bound(pool_.begin(), pool_.end(), numBytes);
FixedAllocator aux(numBytes);
Pool::iterator i = std::lower_bound(pool_.begin(), pool_.end(), aux);
assert(i != pool_.end());
assert(i->BlockSize() == numBytes);
pLastDealloc_ = &*i;
@ -432,9 +421,8 @@ void SmallObjAllocator::Deallocate(void* p, std::size_t numBytes)
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20: fix exception safety issue in FixedAllocator::Allocate
// March 20: fix exception safety issue in FixedAllocator::Allocate
// (thanks to Chris Udazvinis for pointing that out)
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef SMALLOBJ_INC_
#define SMALLOBJ_INC_
@ -45,6 +23,8 @@ text
#include <cstddef>
#include <vector>
#pragma warning(disable: 111 444 981)
#ifndef DEFAULT_CHUNK_SIZE
#define DEFAULT_CHUNK_SIZE 4096
#endif
@ -155,9 +135,9 @@ namespace Loki
class SmallObject : public ThreadingModel<
SmallObject<ThreadingModel, chunkSize, maxSmallObjectSize> >
{
typedef ThreadingModel< SmallObject<ThreadingModel,
chunkSize, maxSmallObjectSize> > MyThreadingModel;
typedef ThreadingModel< SmallObject<ThreadingModel,
chunkSize, maxSmallObjectSize> > MyThreadingModel;
struct MySmallObjAllocator : public SmallObjAllocator
{
MySmallObjAllocator()
@ -191,7 +171,7 @@ namespace Loki
SingletonHolder<MySmallObjAllocator, CreateStatic,
PhoenixSingleton>::Instance().Deallocate(p, size);
#else
::operator delete(p, size);
::operator delete(p); //### BCB doesn't like size parameter
#endif
}
virtual ~SmallObject() {}
@ -201,8 +181,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // SMALLOBJ_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef SMARTPTR_INC_
#define SMARTPTR_INC_
@ -67,7 +45,7 @@ namespace Loki
template <class T>
class DefaultSPStorage
{
protected:
public:
typedef T* StoredType; // the type of the pointee_ object
typedef T* PointerType; // type returned by operator->
typedef T& ReferenceType; // type returned by operator*
@ -98,11 +76,11 @@ namespace Loki
friend inline PointerType GetImpl(const DefaultSPStorage& sp)
{ return sp.pointee_; }
friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp)
{ return sp.pointee_; }
friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp)
{ return sp.pointee_; }
friend inline StoredType& GetImplRef(DefaultSPStorage& sp)
{ return sp.pointee_; }
friend inline StoredType& GetImplRef(DefaultSPStorage& sp)
{ return sp.pointee_; }
protected:
// Destroys the data stored
@ -172,7 +150,7 @@ namespace Loki
// Data
unsigned int* pCount_;
};
////////////////////////////////////////////////////////////////////////////////
// class template RefCountedMT
// Implementation of the OwnershipPolicy used by SmartPtr
@ -183,7 +161,7 @@ namespace Loki
class RefCountedMT : public ThreadingModel< RefCountedMT<P, ThreadingModel> >
{
public:
RefCountedMT()
RefCountedMT()
{
pCount_ = static_cast<unsigned int*>(
SmallObject<ThreadingModel>::operator new(
@ -191,37 +169,37 @@ namespace Loki
assert(pCount_);
*pCount_ = 1;
}
RefCountedMT(const RefCountedMT& rhs)
RefCountedMT(const RefCountedMT& rhs)
: pCount_(rhs.pCount_)
{}
// MWCW lacks template friends, hence the following kludge
template <typename P1>
RefCountedMT(const RefCountedMT<P1, ThreadingModel>& rhs)
RefCountedMT(const RefCountedMT<P1, ThreadingModel>& rhs)
: pCount_(reinterpret_cast<const RefCounted<P>&>(rhs).pCount_)
{}
P Clone(const P& val)
{
ThreadingModel<RefCountedMT>::AtomicIncrement(*pCount_);
return val;
}
bool Release(const P&)
{
if (!ThreadingModel<RefCountedMT>::AtomicDecrement(*pCount_))
{
SmallObject<ThreadingModel>::operator delete(pCount_,
SmallObject<ThreadingModel>::operator delete(pCount_,
sizeof(unsigned int));
return true;
}
return false;
}
void Swap(RefCountedMT& rhs)
{ std::swap(pCount_, rhs.pCount_); }
enum { destructiveCopy = false };
private:
@ -241,22 +219,22 @@ namespace Loki
public:
COMRefCounted()
{}
template <class U>
COMRefCounted(const COMRefCounted<U>&)
{}
static P Clone(const P& val)
{
val->AddRef();
return val;
}
static bool Release(const P& val)
{ val->Release(); return false; }
enum { destructiveCopy = false };
static void Swap(COMRefCounted&)
{}
};
@ -264,7 +242,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// class template DeepCopy
// Implementation of the OwnershipPolicy used by SmartPtr
// Implements deep copy semantics, assumes existence of a Clone() member
// Implements deep copy semantics, assumes existence of a Clone() member
// function of the pointee type
////////////////////////////////////////////////////////////////////////////////
@ -273,23 +251,23 @@ namespace Loki
{
DeepCopy()
{}
template <class P1>
DeepCopy(const DeepCopy<P1>&)
{}
static P Clone(const P& val)
{ return val->Clone(); }
static bool Release(const P& val)
{ return true; }
static void Swap(DeepCopy&)
{}
enum { destructiveCopy = false };
};
////////////////////////////////////////////////////////////////////////////////
// class template RefLinked
// Implementation of the OwnershipPolicy used by SmartPtr
@ -569,7 +547,7 @@ namespace Loki
static void OnDefault(P val)
{ assert(val); }
static void OnInit(P val)
{ assert(val); }
@ -589,7 +567,7 @@ namespace Loki
{
NullPointerException() : std::runtime_error("")
{ }
const char* what() const
const char* what() const throw () //### BCB: throw() added
{ return "Null Pointer Exception"; }
};
@ -604,35 +582,35 @@ namespace Loki
{
RejectNullStatic()
{}
template <class P1>
RejectNullStatic(const RejectNullStatic<P1>&)
{}
template <class P1>
RejectNullStatic(const NoCheck<P1>&)
{}
template <class P1>
RejectNullStatic(const AssertCheck<P1>&)
{}
template <class P1>
RejectNullStatic(const AssertCheckStrict<P1>&)
{}
static void OnDefault(const P&)
{
CompileTimeError<false>
ERROR_This_Policy_Does_Not_Allow_Default_Initialization;
}
static void OnInit(const P& val)
{ if (!val) throw NullPointerException(); }
static void OnDereference(const P& val)
{ if (!val) throw NullPointerException(); }
static void Swap(RejectNullStatic&)
{}
};
@ -681,7 +659,7 @@ namespace Loki
template <class P1>
RejectNullStrict(const RejectNullStrict<P1>&)
{}
template <class P1>
RejectNullStrict(const RejectNull<P1>&)
{}
@ -708,8 +686,7 @@ namespace Loki
public:
ByRef(T& v) : value_(v) {}
operator T&() { return value_; }
// gcc doesn't like this:
// operator const T&() const { return value_; }
operator const T&() const { return value_; }
private:
T& value_;
};
@ -756,18 +733,19 @@ namespace Loki
typedef typename SP::PointerType PointerType;
typedef typename SP::StoredType StoredType;
typedef typename SP::ReferenceType ReferenceType;
typedef typename Select<OP::destructiveCopy,
SmartPtr, const SmartPtr>::Result
CopyArg;
enum { aux = OP::destructiveCopy }; //### BCB
typedef const SmartPtr<T, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy> Ptr_t;
typedef const Ptr_t cPtr_t;
typedef typename Select<aux, Ptr_t, cPtr_t>::Result CopyArg;
SmartPtr()
{ KP::OnDefault(GetImpl(*this)); }
SmartPtr(const StoredType& p) : SP(p)
{ KP::OnInit(GetImpl(*this)); }
SmartPtr(CopyArg& rhs)
SmartPtr(CopyArg& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
@ -779,9 +757,9 @@ namespace Loki
template <class> class KP1,
template <class> class SP1
>
SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
template
<
@ -791,23 +769,25 @@ namespace Loki
template <class> class KP1,
template <class> class SP1
>
SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
SmartPtr(ByRef<SmartPtr> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
//### BCB
SmartPtr(ByRef<Ptr_t> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{}
operator ByRef<SmartPtr>()
//### BCB
operator ByRef<Ptr_t>()
{ return ByRef<SmartPtr>(*this); }
SmartPtr& operator=(CopyArg& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
SmartPtr& operator=(CopyArg& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
template
<
@ -817,13 +797,13 @@ namespace Loki
template <class> class KP1,
template <class> class SP1
>
SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
template
<
typename T1,
@ -832,65 +812,65 @@ namespace Loki
template <class> class KP1,
template <class> class SP1
>
SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
void Swap(SmartPtr& rhs)
{
OP::Swap(rhs);
CP::Swap(rhs);
KP::Swap(rhs);
SP::Swap(rhs);
}
~SmartPtr()
{
if (OP::Release(GetImpl(*static_cast<SP*>(this))))
{
SP::Destroy();
}
}
friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
{
p = GetImplRef(sp);
GetImplRef(sp) = SP::Default();
}
friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
{ SmartPtr(p).Swap(sp); }
SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
void Swap(SmartPtr& rhs)
{
OP::Swap(rhs);
CP::Swap(rhs);
KP::Swap(rhs);
SP::Swap(rhs);
}
~SmartPtr()
{
if (OP::Release(GetImpl(*static_cast<SP*>(this))))
{
SP::Destroy();
}
}
friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
{
p = GetImplRef(sp);
GetImplRef(sp) = SP::Default();
}
friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
{ SmartPtr(p).Swap(sp); }
PointerType operator->()
T* operator->() //### BCB PointerType causes internal compiler crash
{
KP::OnDereference(GetImplRef(*this));
return SP::operator->();
}
PointerType operator->() const
T* operator->() const //### BCB PointerType causes internal compiler crash
{
KP::OnDereference(GetImplRef(*this));
return SP::operator->();
}
ReferenceType operator*()
T& operator*() //### BCB ReferenceType causes internal compiler crash
{
KP::OnDereference(GetImplRef(*this));
return SP::operator*();
}
ReferenceType operator*() const
T& operator*() const //### BCB ReferenceType causes internal compiler crash
{
KP::OnDereference(GetImplRef(*this));
return SP::operator*();
}
bool operator!() const // Enables "if (!sp) ..."
{ return GetImpl(*this) == 0; }
inline friend bool operator==(const SmartPtr& lhs,
const T* rhs)
{ return GetImpl(lhs) == rhs; }
@ -967,11 +947,12 @@ namespace Loki
{
Insipid(PointerType) {}
};
typedef typename Select<CP::allow, PointerType, Insipid>::Result
enum { aux2 = CP::allow }; // ### BCB, PointerType must be also removed
typedef typename Select<aux2, T*, Insipid>::Result
AutomaticConversionResult;
public:
public:
operator AutomaticConversionResult() const
{ return GetImpl(*this); }
};
@ -1210,10 +1191,9 @@ namespace std
////////////////////////////////////////////////////////////////////////////////
// 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!!!
// December 09, 2001: Included <cassert>
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // SMARTPTR_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,8 +13,10 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef THREADS_H_
#define THREADS_H_
// Last update: August 9, 2002
#ifndef THREADS_INC_
#define THREADS_INC_
////////////////////////////////////////////////////////////////////////////////
// macro DEFAULT_THREADING
@ -46,6 +26,15 @@ text
// affects only default template arguments
////////////////////////////////////////////////////////////////////////////////
#ifdef __WIN32__
# ifndef _WINDOWS_
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# endif
#endif
#include <cassert>
// Last update: June 20, 2001
#ifndef DEFAULT_THREADING
@ -99,7 +88,8 @@ namespace Loki
{ lval = val; }
};
#ifdef _WINDOWS_
//#ifdef _WINDOWS_ Borland doesn't use this
#ifdef __WIN32__
////////////////////////////////////////////////////////////////////////////////
// class template ObjectLevelLockable
@ -129,7 +119,7 @@ namespace Loki
class Lock
{
ObjectLevelLockable& host_;
Lock(const Lock&);
Lock& operator=(const Lock&);
public:
@ -155,16 +145,20 @@ namespace Loki
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); }
};
template <class Host>
class ClassLevelLockable
{
static CRITICAL_SECTION mtx_;
static volatile LONG mtx_initialisation_started;
static volatile LONG mtx_initialisation_done;
//### Borland C++ doesn't like this (it is ignored)
/*
struct Initializer;
friend struct Initializer;
struct Initializer
@ -178,24 +172,78 @@ namespace Loki
::DeleteCriticalSection(&mtx_);
}
};
static Initializer initializer_;
*/
public:
class Lock;
friend class Lock;
typedef volatile Host VolatileType;
typedef LONG IntType;
static IntType AtomicIncrement(volatile IntType& lval)
{ return InterlockedIncrement(&const_cast<IntType&>(lval)); }
static IntType AtomicDivide(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); }
private:
// used to protect critical section initialisation
static LONG AtomicExchange(volatile IntType& lval, IntType& new_value) {
return InterlockedExchange(&lval, new_value);
}
public:
class Lock
{
Lock(const Lock&);
Lock& operator=(const Lock&);
//### BCB: the initialisation itself must be protected as it is not done during static initialisation
void initialize_impl(void)
{
LONG now = true;
now = ClassLevelLockable<Host>::AtomicExchange(ClassLevelLockable<Host>::mtx_initialisation_started, now);
assert(ClassLevelLockable<Host>::mtx_initialisation_started);
if (!now) {
assert(!ClassLevelLockable<Host>::mtx_initialisation_done);
::InitializeCriticalSection(&mtx_);
ClassLevelLockable<Host>::mtx_initialisation_done = true;
} else {
// critical section is just being initialized by other thread
while (!ClassLevelLockable<Host>::mtx_initialisation_done) {
Sleep(0);
}
}
}
public:
Lock()
{
//### Here's the trick to make it working on BC++B 6.0
// (because the static Initializer struct is ignored)
//
// The critical section isn't deleted by atexit().
// Shouldn't matter in practise. You may add it here if you want.
if (!mtx_initialisation_done) {
initialize_impl();
}
::EnterCriticalSection(&mtx_);
}
Lock(Host&)
{
if (!mtx_initialisation_done) {
initialize_impl();
}
::EnterCriticalSection(&mtx_);
}
~Lock()
@ -203,40 +251,29 @@ namespace Loki
::LeaveCriticalSection(&mtx_);
}
};
typedef volatile Host VolatileType;
typedef LONG IntType;
static IntType AtomicIncrement(volatile IntType& lval)
{ return InterlockedIncrement(&const_cast<IntType&>(lval)); }
static IntType AtomicDivide(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); }
};
template <class Host>
CRITICAL_SECTION ClassLevelLockable<Host>::mtx_;
template <class Host>
typename ClassLevelLockable<Host>::Initializer
ClassLevelLockable<Host>::initializer_;
#endif
LONG volatile ClassLevelLockable<Host>::mtx_initialisation_started;
template <class Host>
LONG volatile ClassLevelLockable<Host>::mtx_initialisation_done;
//### Borland C++ does like this
// template <class Host>
// typename ClassLevelLockable<Host>::Initializer
// ClassLevelLockable<Host>::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
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
////////////////////////////////////////////////////////////////////////////////
// This file is intentionally left empty
@ -43,4 +21,3 @@ text
// HierarchyGenerators.h
////////////////////////////////////////////////////////////////////////////////
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: July 10, 2002
// Last update: August 9, 2002
#ifndef TYPEMANIP_INC_
#define TYPEMANIP_INC_
@ -200,8 +178,7 @@ namespace Loki
// (credit due to Brad Town)
// 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ø to Borland C++ Builder 6.0
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // TYPEMANIP_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,6 +13,8 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: August 9, 2002
#ifndef TYPETRAITS_INC_
#define TYPETRAITS_INC_
@ -291,8 +271,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // TYPETRAITS_INC_
@

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,6 +13,8 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: August 9, 2002
#ifndef TYPELIST_INC_
#define TYPELIST_INC_
@ -683,11 +663,11 @@ namespace Loki
typename Reverse<Tail>::Result, Head>::Result Result;
};
template <>
struct Reverse<NullType>
{
typedef NullType Result;
};
template <>
struct Reverse<NullType>
{
typedef NullType Result;
};
////////////////////////////////////////////////////////////////////////////////
// class template MostDerived
@ -761,8 +741,7 @@ namespace Loki
// Adam Wilkshire;
// Friedrik Hedman who fixed the bug but didn't send the fix;
// Kevin Cline who sent the first actual fix)
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // TYPELIST_INC_
@

View file

@ -1,47 +1,24 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// 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 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"
// 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
// Last update: August 9, 2002
#ifndef VISITOR_INC_
#define VISITOR_INC_
#include "Typelist.h"
#include "HierarchyGenerators.h"
namespace Loki
{
@ -56,7 +33,7 @@ namespace Loki
public:
virtual ~BaseVisitor() {}
};
////////////////////////////////////////////////////////////////////////////////
// class template Visitor
// The building block of Acyclic Visitor
@ -69,15 +46,15 @@ namespace Loki
typedef R ReturnType;
virtual ReturnType Visit(T&) = 0;
};
////////////////////////////////////////////////////////////////////////////////
// class template Visitor (specialization)
// This specialization is not present in the book. It makes it easier to define
// Visitors for multiple types in a shot by using a typelist. Example:
//
// class SomeVisitor :
// class SomeVisitor :
// public BaseVisitor // required
// public Visitor<TYPELIST_2(RasterBitmap, Paragraph)>,
// public Visitor<TYPELIST_2(RasterBitmap, Paragraph)>,
// public Visitor<Paragraph>
// {
// public:
@ -95,7 +72,7 @@ namespace Loki
// using Visitor<Head, R>::Visit;
// using Visitor<Tail, R>::Visit;
};
template <class Head, typename R>
class Visitor<Typelist<Head, NullType>, R> : public Visitor<Head, R>
{
@ -123,7 +100,7 @@ namespace Loki
virtual R Visit(Head&)
{ return R(); }
};
template <class Head, typename R>
class BaseVisitorImpl<Typelist<Head, NullType>, R>
: public Visitor<Head, R>
@ -132,7 +109,7 @@ namespace Loki
virtual R Visit(Head&)
{ return R(); }
};
////////////////////////////////////////////////////////////////////////////////
// class template BaseVisitable
////////////////////////////////////////////////////////////////////////////////
@ -148,9 +125,9 @@ struct DefaultCatchAll
// class template BaseVisitable
////////////////////////////////////////////////////////////////////////////////
template
template
<
typename R = void,
typename R = void,
template <typename, class> class CatchAll = DefaultCatchAll
>
class BaseVisitable
@ -159,7 +136,7 @@ struct DefaultCatchAll
typedef R ReturnType;
virtual ~BaseVisitable() {}
virtual ReturnType Accept(BaseVisitor&) = 0;
protected: // give access only to the hierarchy
template <class T>
static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
@ -175,17 +152,18 @@ struct DefaultCatchAll
////////////////////////////////////////////////////////////////////////////////
// macro DEFINE_VISITABLE
// Put it in every class that you want to make visitable (in addition to
// Put it in every class that you want to make visitable (in addition to
// deriving it from BaseVisitable<R>
////////////////////////////////////////////////////////////////////////////////
//### BCB port - added Loki:: prefix
#define DEFINE_VISITABLE() \
virtual ReturnType Accept(BaseVisitor& guest) \
virtual ReturnType Accept(Loki::BaseVisitor& guest) \
{ return AcceptImpl(*this, guest); }
////////////////////////////////////////////////////////////////////////////////
// class template CyclicVisitor
// Put it in every class that you want to make visitable (in addition to
// Put it in every class that you want to make visitable (in addition to
// deriving it from BaseVisitable<R>
////////////////////////////////////////////////////////////////////////////////
@ -195,7 +173,7 @@ struct DefaultCatchAll
public:
typedef R ReturnType;
// using Visitor<TList, R>::Visit;
template <class Visited>
ReturnType GenericVisit(Visited& host)
{
@ -203,7 +181,7 @@ struct DefaultCatchAll
return subObj.Visit(host);
}
};
////////////////////////////////////////////////////////////////////////////////
// macro DEFINE_CYCLIC_VISITABLE
// Put it in every class that you want to make visitable by a cyclic visitor
@ -218,9 +196,8 @@ struct DefaultCatchAll
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20: add default argument DefaultCatchAll to BaseVisitable
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // VISITOR_INC_
@

108
Borland/loki_typeinfo.h Normal file
View file

@ -0,0 +1,108 @@
////////////////////////////////////////////////////////////////////////////////
// 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: August 9, 2002
#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!!!
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // TYPEINFO_INC_

View file

@ -1 +0,0 @@
?

22
Borland/readme.txt Normal file
View file

@ -0,0 +1,22 @@
Last update: August 9, 2002
Directions:
To use Loki, simply extract the files from the archive, give your compiler access to their path, and include them appropriately in your code via #include.
If you use the small object allocator directly or indirectly (through the Functor class) you must add SmallObj.cpp to your project/makefile.
If you use Singletons with longevity you must add Singleton.cpp to your project/makefile.
Compatibility:
Loki has been tested with Metrowerks CodeWarrior Pro 6 under Windows. CodeWarrior has a problem with the Conversion template (see TypeManip.h) and, though it compiles it, it doesn't provide correct results. Consequently, the DerivedToFront algorithm in Typelist.h does not function. This affects the static dispatcher in Multimethods.h. As a fix, you must order the types (putting the most derived ones in the front) when providing the typelist argument to StaticDispatcher.
Also, Loki has been ported to g++ 2.95.3 by Nick Thurn.
This is a ported version of Loki to Borland C++ Builder 6.0. However, it uses standard C++, so it should work on the other compilers, as well.
More info:
http://moderncppdesign.com

View file

@ -1,26 +1,4 @@
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2002.07.16.22.42.05; author tslettebo; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial commit
@
text
@////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
@ -35,7 +13,7 @@ text
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
// Last update: August 9, 2002
#ifndef STATIC_CHECK_INC_
#define STATIC_CHECK_INC_
@ -59,17 +37,24 @@ namespace Loki
// If expr is zero, id will appear in a compile-time error message.
////////////////////////////////////////////////////////////////////////////////
#define STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
template<bool>
struct CompileTimeChecker
{
CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> {};
#define STATIC_CHECK(expr, msg)\
{\
class ERROR_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr)>(ERROR_##msg()));\
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20, 2001: add extra parens to STATIC_CHECK - it looked like a fun
// definition
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø to BCC 5.6
// definition
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// July 16, 2002: Ported by Terje Slettebø and Pavel Vozenilek to BCC 5.6
////////////////////////////////////////////////////////////////////////////////
#endif // STATIC_CHECK_INC_
@