Added Doxygen documentation
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@771 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
6060322298
commit
228666b49c
4 changed files with 104 additions and 41 deletions
|
@ -25,6 +25,19 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup FactoriesGroup Factories
|
||||||
|
* \defgroup AbstractFactoryGroup Abstract Factory
|
||||||
|
* \ingroup FactoriesGroup
|
||||||
|
* \brief Implements an abstract object factory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class AbstractFactory
|
||||||
|
* \ingroup AbstractFactoryGroup
|
||||||
|
* \brief Implements an abstract object factory.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Loki
|
namespace Loki
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,9 @@ using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup FactoryGroup Factory
|
* \defgroup FactoriesGroup Factories
|
||||||
* \defgroup CachedFactoryGroup Cached Factory
|
* \defgroup CachedFactoryGroup Cached Factory
|
||||||
* \ingroup FactoryGroup
|
* \ingroup FactoriesGroup
|
||||||
* \brief CachedFactory provides an extension of a Factory with caching
|
* \brief CachedFactory provides an extension of a Factory with caching
|
||||||
* support.
|
* support.
|
||||||
*
|
*
|
||||||
|
@ -630,7 +630,7 @@ namespace Loki
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class CachedFactory
|
* \class CachedFactory
|
||||||
* \ingroup FactoryGroup
|
* \ingroup CachedFactoryGroup
|
||||||
* \brief Factory with caching support
|
* \brief Factory with caching support
|
||||||
*
|
*
|
||||||
* This class acts as a Factory (it creates objects)
|
* This class acts as a Factory (it creates objects)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// Copyright (c) 2001 by Andrei Alexandrescu
|
// Copyright (c) 2001 by Andrei Alexandrescu
|
||||||
// Copyright (c) 2005 by Peter Kuemmel
|
// Copyright (c) 2005 by Peter Kuemmel
|
||||||
// This code DOES NOT accompany the book:
|
// This code DOES NOT accompany 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.
|
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||||||
//
|
//
|
||||||
// Code covered by the MIT License
|
// Code covered by the MIT License
|
||||||
|
@ -28,17 +28,64 @@
|
||||||
//unreachable code if OnUnknownType throws an exception
|
//unreachable code if OnUnknownType throws an exception
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \defgroup FactoryGroup Factory
|
/**
|
||||||
|
* \defgroup FactoriesGroup Factories
|
||||||
|
* \defgroup FactoryGroup Factory
|
||||||
|
* \ingroup FactoriesGroup
|
||||||
|
* \brief Implements a generic object factory.
|
||||||
|
*
|
||||||
|
* <i>The Factory Method pattern is an object-oriented design pattern.
|
||||||
|
* Like other creational patterns, it deals with the problem of creating objects
|
||||||
|
* (products) without specifying the exact class of object that will be created.
|
||||||
|
* Factory Method, one of the patterns from the Design Patterns book, handles
|
||||||
|
* this problem by defining a separate method for creating the objects, which
|
||||||
|
* subclasses can then override to specify the derived type of product that will
|
||||||
|
* be created.
|
||||||
|
* <br>
|
||||||
|
* More generally, the term Factory Method is often used to refer to any method
|
||||||
|
* whose main purpose is creation of objects.</i>
|
||||||
|
* <div ALIGN="RIGHT"><a href="http://en.wikipedia.org/wiki/Factory_method_pattern">
|
||||||
|
* Wikipedia</a></div>
|
||||||
|
*
|
||||||
|
* Loki proposes a generic version of the Factory. Here is a typical use.<br>
|
||||||
|
* <code><br>
|
||||||
|
* 1. Factory< AbstractProduct, int > aFactory;<br>
|
||||||
|
* 2. aFactory.Register( 1, createProductNull );<br>
|
||||||
|
* 3. aFactory.CreateObject( 1 ); <br>
|
||||||
|
* </code><br>
|
||||||
|
* <br>
|
||||||
|
* - 1. The declaration<br>
|
||||||
|
* You want a Factory that produces AbstractProduct.<br>
|
||||||
|
* The client will refer to a creation method through an int.<br>
|
||||||
|
* - 2.The registration<br>
|
||||||
|
* The code that will contribute to the Factory will now need to declare its
|
||||||
|
* ProductCreator by registering them into the Factory.<br>
|
||||||
|
* A ProductCreator is a just a function that will return the right object. ie <br>
|
||||||
|
* <code>
|
||||||
|
* Product* createProductNull()<br>
|
||||||
|
* {<br>
|
||||||
|
* return new Product<br>
|
||||||
|
* }<br>
|
||||||
|
* </code><br>
|
||||||
|
* - 3. The use<br>
|
||||||
|
* Now the client can create object by calling the Factory's CreateObject method
|
||||||
|
* with the right identifier. If the ProductCreator were to have arguments
|
||||||
|
* (<i>ie :Product* createProductParm( int a, int b )</i>)
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Loki
|
namespace Loki
|
||||||
{
|
{
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
/// \class DefaultFactoryError
|
* \defgroup FactoryErrorPoliciesGroup Factory Error Policies
|
||||||
///
|
* \ingroup FactoryGroup
|
||||||
/// \ingroup FactoryGroup
|
* \brief Manages the "Unknown Type" error in an object factory
|
||||||
/// Manages the "Unknown Type" error in an object factory
|
*
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
* \class DefaultFactoryError
|
||||||
|
* \ingroup FactoryErrorPoliciesGroup
|
||||||
|
* \brief Default policy that throws an exception
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
template <typename IdentifierType, class AbstractProduct>
|
template <typename IdentifierType, class AbstractProduct>
|
||||||
struct DefaultFactoryError
|
struct DefaultFactoryError
|
||||||
|
@ -47,14 +94,14 @@ namespace Loki
|
||||||
{
|
{
|
||||||
const char* what() const throw() { return "Unknown Type"; }
|
const char* what() const throw() { return "Unknown Type"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static AbstractProduct* OnUnknownType(IdentifierType)
|
static AbstractProduct* OnUnknownType(IdentifierType)
|
||||||
{
|
{
|
||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define LOKI_ENABLE_NEW_FACTORY_CODE
|
#define LOKI_ENABLE_NEW_FACTORY_CODE
|
||||||
#ifdef LOKI_ENABLE_NEW_FACTORY_CODE
|
#ifdef LOKI_ENABLE_NEW_FACTORY_CODE
|
||||||
|
|
||||||
|
@ -63,7 +110,7 @@ namespace Loki
|
||||||
// class template FunctorImpl
|
// class template FunctorImpl
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct FactoryImplBase
|
struct FactoryImplBase
|
||||||
{
|
{
|
||||||
typedef EmptyType Parm1;
|
typedef EmptyType Parm1;
|
||||||
typedef EmptyType Parm2;
|
typedef EmptyType Parm2;
|
||||||
|
@ -683,15 +730,15 @@ template <typename AP, typename Id, typename P1 >
|
||||||
/// \class Factory
|
/// \class Factory
|
||||||
///
|
///
|
||||||
/// \ingroup FactoryGroup
|
/// \ingroup FactoryGroup
|
||||||
/// Implements a generic object factory.
|
/// Implements a generic object factory.
|
||||||
///
|
///
|
||||||
/// Create functions can have up to 15 parameters.
|
/// Create functions can have up to 15 parameters.
|
||||||
///
|
///
|
||||||
/// \par Singleton lifetime when used with Loki::SingletonHolder
|
/// \par Singleton lifetime when used with Loki::SingletonHolder
|
||||||
/// Because Factory uses internally Functors which inherits from
|
/// Because Factory uses internally Functors which inherits from
|
||||||
/// SmallObject you must use the singleton lifetime
|
/// SmallObject you must use the singleton lifetime
|
||||||
/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
|
/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
|
||||||
/// Alternatively you could suppress for Functor the inheritance
|
/// Alternatively you could suppress for Functor the inheritance
|
||||||
/// from SmallObject by defining the macro:
|
/// from SmallObject by defining the macro:
|
||||||
/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
|
/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -763,7 +810,7 @@ template <typename AP, typename Id, typename P1 >
|
||||||
std::vector<IdentifierType> RegisteredIds()
|
std::vector<IdentifierType> RegisteredIds()
|
||||||
{
|
{
|
||||||
std::vector<IdentifierType> ids;
|
std::vector<IdentifierType> ids;
|
||||||
for(typename IdToProductMap::iterator it = associations_.begin();
|
for(typename IdToProductMap::iterator it = associations_.begin();
|
||||||
it != associations_.end(); ++it)
|
it != associations_.end(); ++it)
|
||||||
{
|
{
|
||||||
ids.push_back(it->first);
|
ids.push_back(it->first);
|
||||||
|
@ -935,13 +982,13 @@ template <typename AP, typename Id, typename P1 >
|
||||||
|
|
||||||
template
|
template
|
||||||
<
|
<
|
||||||
class AbstractProduct,
|
class AbstractProduct,
|
||||||
typename IdentifierType,
|
typename IdentifierType,
|
||||||
typename ProductCreator = AbstractProduct* (*)(),
|
typename ProductCreator = AbstractProduct* (*)(),
|
||||||
template<typename, class>
|
template<typename, class>
|
||||||
class FactoryErrorPolicy = DefaultFactoryError
|
class FactoryErrorPolicy = DefaultFactoryError
|
||||||
>
|
>
|
||||||
class Factory
|
class Factory
|
||||||
: public FactoryErrorPolicy<IdentifierType, AbstractProduct>
|
: public FactoryErrorPolicy<IdentifierType, AbstractProduct>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -950,12 +997,12 @@ template <typename AP, typename Id, typename P1 >
|
||||||
return associations_.insert(
|
return associations_.insert(
|
||||||
typename IdToProductMap::value_type(id, creator)).second;
|
typename IdToProductMap::value_type(id, creator)).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unregister(const IdentifierType& id)
|
bool Unregister(const IdentifierType& id)
|
||||||
{
|
{
|
||||||
return associations_.erase(id) == 1;
|
return associations_.erase(id) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractProduct* CreateObject(const IdentifierType& id)
|
AbstractProduct* CreateObject(const IdentifierType& id)
|
||||||
{
|
{
|
||||||
typename IdToProductMap::iterator i = associations_.find(id);
|
typename IdToProductMap::iterator i = associations_.find(id);
|
||||||
|
@ -965,7 +1012,7 @@ template <typename AP, typename Id, typename P1 >
|
||||||
}
|
}
|
||||||
return this->OnUnknownType(id);
|
return this->OnUnknownType(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
|
typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
|
||||||
IdToProductMap associations_;
|
IdToProductMap associations_;
|
||||||
|
@ -974,17 +1021,20 @@ template <typename AP, typename Id, typename P1 >
|
||||||
|
|
||||||
#endif //#define ENABLE_NEW_FACTORY_CODE
|
#endif //#define ENABLE_NEW_FACTORY_CODE
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
/// \class CloneFactory
|
* \defgroup CloneFactoryGroup Clone Factory
|
||||||
///
|
* \ingroup FactoriesGroup
|
||||||
/// \ingroup FactoryGroup
|
* \brief Creates a copy from a polymorphic object.
|
||||||
/// Implements a generic cloning factory
|
*
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
* \class CloneFactory
|
||||||
|
* \ingroup CloneFactoryGroup
|
||||||
|
* \brief Creates a copy from a polymorphic object.
|
||||||
|
*/
|
||||||
|
|
||||||
template
|
template
|
||||||
<
|
<
|
||||||
class AbstractProduct,
|
class AbstractProduct,
|
||||||
class ProductCreator =
|
class ProductCreator =
|
||||||
AbstractProduct* (*)(const AbstractProduct*),
|
AbstractProduct* (*)(const AbstractProduct*),
|
||||||
template<typename, class>
|
template<typename, class>
|
||||||
class FactoryErrorPolicy = DefaultFactoryError
|
class FactoryErrorPolicy = DefaultFactoryError
|
||||||
|
@ -998,17 +1048,17 @@ template <typename AP, typename Id, typename P1 >
|
||||||
return associations_.insert(
|
return associations_.insert(
|
||||||
typename IdToProductMap::value_type(ti, creator)).second;
|
typename IdToProductMap::value_type(ti, creator)).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unregister(const TypeInfo& id)
|
bool Unregister(const TypeInfo& id)
|
||||||
{
|
{
|
||||||
return associations_.erase(id) == 1;
|
return associations_.erase(id) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractProduct* CreateObject(const AbstractProduct* model)
|
AbstractProduct* CreateObject(const AbstractProduct* model)
|
||||||
{
|
{
|
||||||
if (model == 0) return 0;
|
if (model == 0) return 0;
|
||||||
|
|
||||||
typename IdToProductMap::iterator i =
|
typename IdToProductMap::iterator i =
|
||||||
associations_.find(typeid(*model));
|
associations_.find(typeid(*model));
|
||||||
if (i != associations_.end())
|
if (i != associations_.end())
|
||||||
{
|
{
|
||||||
|
@ -1016,7 +1066,7 @@ template <typename AP, typename Id, typename P1 >
|
||||||
}
|
}
|
||||||
return this->OnUnknownType(typeid(*model));
|
return this->OnUnknownType(typeid(*model));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
|
typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
|
||||||
IdToProductMap associations_;
|
IdToProductMap associations_;
|
||||||
|
@ -1024,7 +1074,7 @@ template <typename AP, typename Id, typename P1 >
|
||||||
} // namespace Loki
|
} // namespace Loki
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning( pop )
|
#pragma warning( pop )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Loki
|
||||||
bool operator<(const Key<F, I> &k1, const Key<F, I> &k2);
|
bool operator<(const Key<F, I> &k1, const Key<F, I> &k2);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* A Key class
|
* A Key class
|
||||||
*/
|
*/
|
||||||
template<
|
template<
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue