/**
 *  file mirror/doc/factory_generator.hpp
 *  Documentation only header
 *
 *  @author Matus Chochlik
 *
 *  Copyright 2008-2010 Matus Chochlik. Distributed under the Boost
 *  Software License, Version 1.0. (See accompanying file
 *  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef MIRROR_DOC_FACTORY_GENERATOR_1011291729_HPP
#define MIRROR_DOC_FACTORY_GENERATOR_1011291729_HPP

#ifdef MIRROR_DOCUMENTATION_ONLY

#include <mirror/config.hpp>

MIRROR_NAMESPACE_BEGIN

/** @page mirror_factory_generator_utility Factory generator utility
 *
 *  @section mirror_factory_generator_intro Introduction
 *
 *  The factory generator utility allows to easily create implementations
 *  of object factories at compile-time by using the meta-data provided
 *  by Mirror.
 *  By object factories we mean here classes, which can create
 *  instances of various types (@c Products), but do not require that the caller
 *  supplies the parameters for the construction directly.
 *  Factories pick or let the application user pick the @c Product 's most
 *  appropriate constructor, they gather the necessary parameters in
 *  a generic, application-specific way and use the selected constructor
 *  to create an instance of the @c Product.
 *
 *  Obviously the most interesting feature of these factories is, that
 *  they separate the caller (who just needs to get an instance of the
 *  specified type) from the actual method of creation which involves
 *  choosing of right constructor and supplying the
 *  required parameters, which in turn can also be constructed or supplied
 *  in some other way (for example from a pool of existing objects).
 *
 *  This is useful when we need to create instances of (possibly different)
 *  types having multiple constructors from a single point in code and we want
 *  the method of construction to be determined by parameters available only
 *  at run-time.
 *
 *  Here follows a brief list of examples:
 *  - Creation of objects based on user input from a GUI: The factory object
 *    creates a GUI component (a dialog for example) having the necessary
 *    controls for selecting one of the constructors of the constructed type
 *    and for the input of the values of all parameters for the selected
 *    constructor.
 *  - Creation of objects from a database dataset: The factory can go through
 *    the list of constructors and find the one whose parameters are matching
 *    to the columns in a database dataset. Then it calls this constructor
 *    and passes the values of the matching columns as the parameters, doing
 *    the appropriate type conversions where necessary. By doing this repeatedly
 *    we can create multiple objects, each representing a different row in
 *    the dataset.
 *  - Creation of objects from other external representations: Similar to
 *    the option above one can create instances from other file or stream-based
 *    data representations like (XML, JSON, XDR, etc.)
 *
 *  The factories generated by this utility can then be used for example
 *  for the implementation of the Abstract factory design pattern, where
 *  even the exact type of the created object is not known.
 *
 *  Because the factory classes are created by a generic meta-program
 *  at compile-time a good optimizing compiler can generate source
 *  code, which is as efficient as if the factories were hand-coded.
 *  This however depends on the implementation of the application-specific
 *  parts that are supplied to the factory generator.
 *
 *  @section mirror_factory_generator_principles Principles
 *
 *  As we mentioned in the introduction, the factory must handle two important
 *  tasks during the construction of an instance:
 *  - Choose the constructor (default, copy, custom).
 *  - Supply the parameters to the constructor if necessary.
 *
 *  The implementation of these tasks is also the most distinctive thing
 *  about a particular factory. The rest of the process is the same regardless
 *  of the @c Product type. This is why the factory generator utility provides
 *  all the common boilerplate code and the application only specifies how
 *  a constuctor is selected and how the arguments are supplied to it.
 *
 *  Furthermore there are two basic ways how to supply a parameter value:
 *  - Create one from scratch by using the same factory with a different
 *    @c Product type recursivelly.
 *  - Use an existing instance which can be acquired from a pool of instances,
 *    or be a result of a functor call.
 *
 *  In order to create a factory, the application needs to supply the factory
 *  generator with two template classes with the following signature:
 *
 *  @code
 *  template <class Product, class SourceTraits>
 *  class constructor_parameter_source;
 *  @endcode
 *
 *  The first one is referred to as a @c Manufacturer and is responsible
 *  for the creation of new parameter values. The second template is
 *  referred to as @c Suppliers and is responsible for returning of an existing
 *  value.
 *
 *  One of the specializations of the @c Manufacturer template, namely the one
 *  having the @c void type as @c Product is referred to as @c Manager.
 *  This @c Manager is responsible for the selecting of the constructor that
 *  to be used.
 *
 *  Both of these templates have the following parameters:
 *  - @c Product is the type produced by the source. A @c Manufacturer creates
 *    a new instance of @c Product and @c Suppliers return an
 *    existing instance of @c Product (one of possibly multiple candidates)
 *  - @c SourceTraits is an optional type parameter used by some factory
 *    implementations for the configuration and fine tuning of the factory's
 *    behavior and appearance.
 *
 *  Whether these sources (@c Manufacturer or @c Suppliers) are going to be used
 *  for the supplying of a constructor parameter and if so, which of them,
 *  depends on the selected constructor:
 *  - If the @c Product 's default constructor is selected, then no parameters
 *    are required and neither the @c Manufacturer nor the @c Suppliers are used.
 *  - If the copy constructor is selected then the @c Suppliers template
 *    (which returns existing instances of the same type) is used.
 *  - If another constructor was picked, then the @c Manufacturer template is used
 *    to create the individual parameters.
 *
 *  @subsection mirror_factory_generator_manufacturer The Manufacturer
 *
 *  The application-defined @c Manufacturer template should have several
 *  distinct specializations, which serve for different purposes.
 *
 *  As mentioned before, a @c Manufacturer with the @c void type as @c Product
 *  serves as a manager which is responsible for choosing the constructor
 *  that is ultimately to be used for the construction of an instance
 *  of the @c Product. This means that besides the regular @c Manufacturer
 *  which in fact creates the instances, there is one instance of the @c Manager
 *  for every @c Product in the generated factory. The @c Manager has also
 *  a different interface then the other @c Manufacturers.
 *
 *  Other specializations of the @c Manufacturer should handle the creation of
 *  values of some special types (like the native C++ types; boolean, integers,
 *  floating points, strings, etc), considered atomic (i.e. not eleborated)
 *  by the factory. Values of such types can be input directly by the user
 *  into some kind of UI, they can be converted from some external representation
 *  like the value of row/column in a database dataset, or a value of an XML
 *  attribute, etc.
 *
 *  The default implementation of the @c Manufacturer is for elaborated types and it
 *  uses a generated factory to recursively create instances of the constructor
 *  parameters.
 *
 *  @subsection mirror_factory_generator_suppliers The Suppliers
 *
 *  The @c Suppliers template is responsible for returning existing instances
 *  of the type passed as the @c Product parameter. Depending on the specific
 *  factory and the @c Product, the suppliers may or may not have means
 *  to get instances of that particular @c Product type and should be implemented
 *  accordingly. If there are multiple possible sources of values of a type
 *  then the specialization of @c Suppliers must provide some means how to
 *  select which of the external sources is to be used.
 *
 *  @subsection mirror_factory_generator_source_traits The parameter source traits
 *
 *  For additional flexibility both the @c Manufacturer and the @c Suppliers
 *  template have (besides the @c Product type they create) an aditional template
 *  type parameter called @c SourceTraits. This type is usually defined together
 *  with the @c Manufacturer and @c Suppliers and is passed to the instantiations
 *  of these templates by the factory generator when a new factory is created.
 *  The factory generator treats this type as opaque.
 *  If a concrete implementation of the parameter sources (@c Manufacturer and
 *  @c Suppliers) has no use for this additional parameter, the void type
 *  can be passed to the factory generator.
 *
 *  @subsection mirror_factory_generator_factory_maker Factory and Factory Maker
 *
 *  The @c Manufacturers, the @c Suppliers, the @c SourceTraits and
 *  the boilerplate code common to all factories is tied together by
 *  the @c mirror::factory template, with the following definition:
 *
 *  @code
 *  template <
 *          template <class, class> class Manufacturer,
 *          template <class, class> class Suppliers,
 *          class SourceTraits,
 *          typename Product
 *  > class factory
 *  {
 *  public:
 *      Product operator()(void);
 *      Product* new_(void);
 *  };
 *  @endcode
 *
 *  Perhaps a more convenient way how to create factories, especially when
 *  one wants to create multiple factories of the same kind (with the same
 *  @c Manufacturers, @c Suppliers and @c SourceTraits) for constructing
 *  different @c Product types is to use the @c mirror::factory_maker template
 *  class defined as follows:
 *
 *  @code
 *  template <
 *          template <class, class> class Manufacturer,
 *          template <class, class> class Suppliers,
 *          class SourceTraits
 *  > struct factory_maker
 *  {
 *      template <typename Product>
 *      struct factory
 *      {
 *	    typedef factory<Manufacturer, Suppliers, SourceTraits, Product> type;
 *      };
 *  };
 *  @endcode
 *
 *  @section mirror_factory_generator_usage Usage
 *
 *  The basic usage of the factory generator utility should be obvious from the above;
 *  It is necessary to implement the @c Manufacturer and the @c Suppliers
 *  templates (and possibly also the @c SourceTraits) and then use either the
 *  @c mirror::factory template directly or the @c mirror::factory_maker 's factory
 *  nested template to create an instantiation of a factory constructing instances
 *  of a @c Product type:
 *
 *  @code
 *  // use the factory directly ...
 *  mirror::factory<my_manuf, my_suppl, my_traits, my_product_1> f1;
 *  my_product_1 x1(f1());
 *  my_product_1* px1(f1.new_());
 *
 *  // ...
 *  // or use the factory_maker
 *  typedef mirror::factory_maker<my_manuf, my_suppl, my_traits> my_fact_maker;
 *  my_fact_maker::factory<my_product_1>::type f1;
 *  my_fact_maker::factory<my_product_2>::type f2;
 *  my_fact_maker::factory<my_product_3>::type f2;
 *  //
 *  my_product_1 x1(f1());
 *  my_product_1* px1(f1.new_());
 *  my_product_2 x2(f2());
 *  my_product_3* px3(f3.new_());
 *  @endcode
 *
 *  @subsection mirror_factory_generator_tutorials Tutorials and other resources
 *
 *  Here follows a list of references to other pages dealing with the factory
 *  generator utility in depth and also tutorials showing how to write
 *  the plugins (the Managers, Manufacturers and Suppliers) for the factory
 *  generator:
 *
 *  - @subpage mirror_fact_gen_in_depth
 *  - @subpage mirror_sql_fact_gen_tutorial
 *
 *  @section mirror_factory_generator_existing_templates Existing Manufacturers and Suppliers
 *
 *  The Mirror library provides several working sample implementations
 *  of the @c Manufacturer and @c Suppliers templates.
 *  The following example shows the usage of the @c wx_gui_factory template
 *  with the factory generator utility in a simple wxWidgets-based application.
 *  The generated factory creates a wxDialog containing all necessary widgets
 *  for the selection of the constructor to be used and for the input of all
 *  parameters required by the selected constructor. Screenshots of dialogs
 *  generated by this implementation can be found
 *  @link mirror_wx_gui_fact_examples here@endlink.
 */

MIRROR_NAMESPACE_END

#endif // DOCUMENTATION_ONLY
#endif //include guard

