////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// Copyright (c) 2005 by Peter Kuemmel
// This code DOES NOT accompany the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
//
// Code covered by the MIT License
// The authors make no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_FACTORYPARM_INC_
#define LOKI_FACTORYPARM_INC_
// $Id$
#include "LokiTypeInfo.h"
#include "Functor.h"
#include "AssocVector.h"
#include "SmallObj.h"
#include "Sequence.h"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4702)
//unreachable code if OnUnknownType throws an exception
#endif
/**
* \defgroup FactoriesGroup Factories
* \defgroup FactoryGroup Factory
* \ingroup FactoriesGroup
* \brief Implements a generic object factory.
*
* 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.
*
* More generally, the term Factory Method is often used to refer to any method
* whose main purpose is creation of objects.
*
*
* Loki proposes a generic version of the Factory. Here is a typical use.
*
* 1. Factory< AbstractProduct, int > aFactory;
* 2. aFactory.Register( 1, createProductNull );
* 3. aFactory.CreateObject( 1 );
*
*
* - 1. The declaration
* You want a Factory that produces AbstractProduct.
* The client will refer to a creation method through an int.
* - 2.The registration
* The code that will contribute to the Factory will now need to declare its
* ProductCreator by registering them into the Factory.
* A ProductCreator is a just a function that will return the right object. ie
*
* Product* createProductNull()
* {
* return new Product
* }
*
* - 3. The use
* Now the client can create object by calling the Factory's CreateObject method
* with the right identifier. If the ProductCreator were to have arguments
* (ie :Product* createProductParm( int a, int b ))
*/
namespace Loki
{
/**
* \defgroup FactoryErrorPoliciesGroup Factory Error Policies
* \ingroup FactoryGroup
* \brief Manages the "Unknown Type" error in an object factory
*
* \class DefaultFactoryError
* \ingroup FactoryErrorPoliciesGroup
* \brief Default policy that throws an exception
*
*/
template
struct DefaultFactoryError
{
struct Exception : public std::exception
{
const char* what() const throw() { return "Unknown Type"; }
};
static AbstractProduct* OnUnknownType(IdentifierType)
{
throw Exception();
}
};
#define LOKI_ENABLE_NEW_FACTORY_CODE
#ifdef LOKI_ENABLE_NEW_FACTORY_CODE
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
////////////////////////////////////////////////////////////////////////////////
struct FactoryImplBase
{
typedef EmptyType Parm1;
typedef EmptyType Parm2;
typedef EmptyType Parm3;
typedef EmptyType Parm4;
typedef EmptyType Parm5;
typedef EmptyType Parm6;
typedef EmptyType Parm7;
typedef EmptyType Parm8;
typedef EmptyType Parm9;
typedef EmptyType Parm10;
typedef EmptyType Parm11;
typedef EmptyType Parm12;
typedef EmptyType Parm13;
typedef EmptyType Parm14;
typedef EmptyType Parm15;
};
template
struct FactoryImpl;
template
struct FactoryImpl
: public FactoryImplBase
{
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id & id ) = 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6 )
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7 )
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
typedef typename TypeTraits::ParameterType Parm11;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10,
Parm11)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
typedef typename TypeTraits::ParameterType Parm11;
typedef typename TypeTraits::ParameterType Parm12;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10,
Parm11,Parm12)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
typedef typename TypeTraits::ParameterType Parm11;
typedef typename TypeTraits::ParameterType Parm12;
typedef typename TypeTraits::ParameterType Parm13;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10,
Parm11,Parm12,Parm13)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
typedef typename TypeTraits::ParameterType Parm11;
typedef typename TypeTraits::ParameterType Parm12;
typedef typename TypeTraits::ParameterType Parm13;
typedef typename TypeTraits::ParameterType Parm14;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm8,Parm10,
Parm11,Parm12,Parm13,Parm14)
= 0;
};
template
struct FactoryImpl >
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
typedef typename TypeTraits::ParameterType Parm11;
typedef typename TypeTraits::ParameterType Parm12;
typedef typename TypeTraits::ParameterType Parm13;
typedef typename TypeTraits::ParameterType Parm14;
typedef typename TypeTraits::ParameterType Parm15;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10,
Parm11,Parm12,Parm13,Parm14,Parm15 )
= 0;
};
#ifndef LOKI_DISABLE_TYPELIST_MACROS
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6 )
= 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7 )
= 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8)
= 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9)
= 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10)
= 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits::ParameterType Parm10;
typedef typename TypeTraits::ParameterType Parm11;
virtual ~FactoryImpl() {}
virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
Parm6, Parm7, Parm8, Parm9,Parm10,
Parm11)
= 0;
};
template
struct FactoryImpl
: public FactoryImplBase
{
typedef typename TypeTraits::ParameterType Parm1;
typedef typename TypeTraits::ParameterType Parm2;
typedef typename TypeTraits::ParameterType Parm3;
typedef typename TypeTraits::ParameterType Parm4;
typedef typename TypeTraits::ParameterType Parm5;
typedef typename TypeTraits::ParameterType Parm6;
typedef typename TypeTraits::ParameterType Parm7;
typedef typename TypeTraits::ParameterType Parm8;
typedef typename TypeTraits::ParameterType Parm9;
typedef typename TypeTraits