Files
mlpack/fastlib/trilinos/include/Teuchos_AbstractFactoryStd.hpp
T

206 lines
7.8 KiB
C++

// @HEADER
// ***********************************************************************
//
// Teuchos: Common Tools Package
// Copyright (2004) Sandia Corporation
//
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ***********************************************************************
// @HEADER
#ifndef TEUCHOS_ABSTRACT_FACTORY_STD_HPP
#define TEUCHOS_ABSTRACT_FACTORY_STD_HPP
#include "Teuchos_AbstractFactory.hpp"
namespace Teuchos {
/** \brief Default post-modification policy class for
* <tt>AbstractFactorStd</tt> which does nothing!
*/
template<class T_impl>
class PostModNothing {
public:
/** \brief . */
void initialize(T_impl* p) const {} // required!
};
/** \brief Default allocation policy class for
* <tt>AbstractFactoryStd</tt> which returns <tt>new T_impl()</tt>.
*/
template<class T_impl>
class AllocatorNew {
public:
/** \brief . */
typedef Teuchos::RCP<T_impl> ptr_t; // required!
/** \brief . */
const ptr_t allocate() const { return Teuchos::rcp(new T_impl()); } // required!
};
/** \brief Simple, templated concrete subclass of universal "Abstract
* Factory" interface for the creation of objects.
*
* This concrete subclass represents a general
* <tt>AbstractFactory</tt> subclass that can be modified through
* policy template parameters. This class is templated on the
* interface type <tt>T_itfc</tt> that is exposed by the
* <tt>AbstractFactory<T_itfc></tt> base interface and by a (concrete)
* implementation type <tt>T_impl</tt>. The most typical use of this
* subclass is to use a concrete, default-constructable subclass for
* <tt>T_impl</tt> and then to simply instantiate a concrete abstract
* factory for that class using:
\verbatim
Teuchos::AbstractFactoryStd<T_itfc,T_impl> abstractFactory;
\endverbatim
*
* For this default usage, The only requirements for the derived classes type
* <tt>T_impl</tt> is that it allow the default constructor
* <tt>T_impl::T_impl()</tt> (i.e. dont make <tt>T_impl::T_impl()</tt>
* private) and that it allow <tt>T_impl::new()</tt> and
* <tt>T_impl::delete</tt> (i.e. don't make them private functions, see
* Meyers, More Effective C++, Item 27).
* However, this subclass is also templated on two other policy types that
* allow a modification on how objects are created and destroyed. The first
* templated policy type, <tt>T_PostMod</tt>, defines how an object is
* modified after it is initially created. The second templated policy type,
* <tt>T_Allocator</tt>, defines exactly how an object is created (and
* therefore also how it is destroyed). These type two policy classes are
* described in more detail below.
*
* The type <tt>T_PostMod</tt> is responsible for performing any post
* modifications on a dynamically allocated object before returning it from
* <tt>create()</tt>. The requirements for the type <tt>T_PostMod</tt> are
* that it has a default constructor, a copy constructor and a method
* <tt>T_PostMod::initialize(T_itfc2*) const</tt> that will perform any
* required post modifications (initializations). The type <tt>T_itfc2</tt>
* argument for this function must be a base class of <tt>T_impl</tt> of
* course. The default type for <tt>T_PostMod</tt> is
* <tt>PostModNothing</tt><tt><T_impl></tt> which does nothing.
*
* The type <tt>T_Allocator</tt> allows for specialized memory allocation and
* cleanup. This type must allow the default constructor and copy constructor
* and have a method <tt>Teuchos::RCP<T_impl> T_Allocator::allocate()
* const</tt> which creates a smart reference-counted pointer to the allocated
* object. Also, in returning a <tt>RCP<></tt> object, the client can
* set a deallocatioin policy object that can specialize the deallocation of
* the object (see <tt>RCP</tt>). In defining a specialized
* <tt>T_Allocator</tt> class, the client can all initialize the object using
* more than just the default constructor. Therefore, if the client provides
* a specialized <tt>T_Allocator</tt> class, there are no restrictions on the
* class <tt>T_impl</tt> (i.e. does not have to have a default constructor or
* allow <tt>new</tt> or <tt>delete</tt>). The default class for
* <tt>T_Allocator</tt> is <tt>AllocatorNew</tt><tt><T_impl></tt> who's
* <tt>allocate()</tt> function just returns <tt>rcp(new T_impl())</tt>.
*
* Since the <tt>T_Allocator</tt> class can specialize both the memory
* management and can initialize the object using more that the default
* constructor, the class <tt>T_PostMod</tt> may seem unecessary. However, it
* is more likely that the client will want to define an initialization for a
* set of classes through an abstract interface and can not for a particular
* concrete subclass. Also the initialization for an object can be orthogonal
* to how it is created and destroyed, thus the two classes <tt>T_PostMod</tt>
* and <tt>T_Allocator</tt> are both needed for a more general implementation.
*/
template<class T_itfc, class T_impl
,class T_PostMod = PostModNothing<T_impl>
,class T_Allocator = AllocatorNew<T_impl>
>
class AbstractFactoryStd : public AbstractFactory<T_itfc> {
public:
typedef typename Teuchos::AbstractFactory<T_itfc>::obj_ptr_t obj_ptr_t; // RAB: 20030916: G++ 3.2 complains without this
/** \brief . */
AbstractFactoryStd( const T_PostMod& post_mod = T_PostMod(), const T_Allocator& alloc = T_Allocator() );
/** @name Overriden from AbstractFactory */
//@{
/** \brief . */
obj_ptr_t create() const;
//@}
private:
T_PostMod post_mod_;
T_Allocator alloc_;
};
/** \brief Nonmember constructor for an standar abstract factory object.
*
* \relates AbstractFactoryStd
*/
template<class T_itfc, class T_impl>
RCP<const AbstractFactory<T_itfc> >
abstractFactoryStd()
{
return rcp(
new AbstractFactoryStd<T_itfc,T_impl,PostModNothing<T_impl>,AllocatorNew<T_impl> >()
);
}
/** \brief Nonmember constructor for an standar abstract factory object.
*
* \relates AbstractFactoryStd
*/
template<class T_itfc, class T_impl, class T_Allocator>
RCP<const AbstractFactory<T_itfc> >
abstractFactoryStd( const T_Allocator& alloc = T_Allocator() )
{
return rcp(
new AbstractFactoryStd<T_itfc,T_impl,PostModNothing<T_impl>,T_Allocator>(
PostModNothing<T_impl>(), alloc
)
);
}
// ///////////////////////////////////////////////////////
// Template member definitions
template<class T_itfc, class T_impl, class T_PostMod, class T_Allocator>
inline
AbstractFactoryStd<T_itfc,T_impl,T_PostMod,T_Allocator>::AbstractFactoryStd(
const T_PostMod& post_mod, const T_Allocator& alloc
)
:post_mod_(post_mod)
,alloc_(alloc)
{}
template<class T_itfc, class T_impl, class T_PostMod, class T_Allocator>
inline
typename AbstractFactoryStd<T_itfc,T_impl,T_PostMod,T_Allocator>::obj_ptr_t
AbstractFactoryStd<T_itfc,T_impl,T_PostMod,T_Allocator>::create() const
{
typename T_Allocator::ptr_t
ptr = alloc_.allocate();
post_mod_.initialize(ptr.get());
return ptr;
}
} // end Teuchos
#endif // TEUCHOS_ABSTRACT_FACTORY_STD_HPP