Update of /cvsroot/pclasses/pclasses2/include/pclasses
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24381
Added Files:
FactoryReg.h
Log Message:
egg
--- NEW FILE: FactoryReg.h ---
////////////////////////////////////////////////////////////////////////
// FactoryReg.h
// A "supermacro"-style classloader registration snippet for P::Factory.
////////////////////////////////////////////////////////////////////////
// Macros to be set before including this file:
//
// PFACREG_TYPE: type to be registered.
//
// PFACREG_TYPE_NAME: string name to register PFACREG_TYPE with.
//
// PFACREG_TYPE_INTERFACE: base-most type of PFACREG_TYPE.
// Defaults to PFACREG_TYPE.
//
// OPTIONAL/special-case macros:
//
// PFACREG_TYPE_IS_ABSTRACT:
// This macro should be used only when PFACREG_TYPE is an abstract type.
// If PFACREG_TYPE is an abstract base class, define this
// macro to any value. If this is set then a no-op specialization
// of P::Hook::FactoryCreateHook<> is installed so no calls to
// new PFACREG_TYPE will be made by the default factories.
//
//
// All of the above macros are #undef'd by this file, so it may be
// included multiple times in succession.
////////////////////////////////////////////////////////////////////////
#ifndef PFACREG_TYPE
# error "You must define PFACREG_TYPE before including this file."
#endif
#ifndef PFACREG_TYPE_NAME
# error "You must define PFACREG_TYPE_NAME before including this file."
#endif
#ifndef PFACREG_TYPE_INTERFACE
# define PFACREG_TYPE_INTERFACE PFACREG_TYPE
#endif
# ifdef PFACREG_TYPE_IS_ABSTRACT
// install a specialization of Factory's default factory type,
// so that we won't try to instantiation a PFACREG_TYPE object.
// Remember that this code will only happen when
// ( PFACREG_TYPE_INTERFACE == PFACREG_TYPE )
// assuming the user doesn't mis-use the supermacro API.
namespace P { namespace Hook {
template <>
struct FactoryCreateHook< PFACREG_TYPE_INTERFACE , PFACREG_TYPE >
{
typedef PFACREG_TYPE_INTERFACE * result_type;
typedef PFACREG_TYPE actual_type;
static result_type create()
{
return 0;
}
};
} } // namespace P::Hook
# endif // PFACREG_TYPE_IS_ABSTRACT
namespace {
# ifndef p_FACTORY_REG_CONTEXT_DEFINED
# define p_FACTORY_REG_CONTEXT_DEFINED 1
///////////////////////////////////////////////////////////////
// we must not include this more than once per compilation unit
///////////////////////////////////////////////////////////////
// A unique (per Context/per compilation unit) space to assign
// a bogus value for classloader registration purposes (see
// the classloader docs for a full description of how this
// works).
template <typename Context>
struct pfactory_reg_context
{
static bool placeholder;
};
template <typename Context> bool pfactory_reg_context<Context>::placeholder = false;
# endif // !p_FACTORY_REG_CONTEXT_DEFINED
# define FACTORY_FUNCTION_ ::P::Hook::FactoryCreateHook< PFACREG_TYPE_INTERFACE , PFACREG_TYPE >::create
////////////////////////////////////////////////////////////////////////
// Register a factory with the classloader:
bool pfactory_reg_context< PFACREG_TYPE >::placeholder= (
P::NamedTypeFactory< PFACREG_TYPE_INTERFACE >::instance().registerFactory( PFACREG_TYPE_NAME, FACTORY_FUNCTION_ ),
true);
# undef FACTORY_FUNCTION_
} // anon namespace
#ifdef PFACREG_TYPE_IS_ABSTRACT
# undef PFACREG_TYPE_IS_ABSTRACT
#endif
#undef PFACREG_TYPE
#undef PFACREG_TYPE_INTERFACE
#undef PFACREG_TYPE_NAME
|