alpar@267: /* -*- C++ -*-
alpar@267: *
alpar@267: * This file is a part of LEMON, a generic C++ optimization library
alpar@267: *
alpar@267: * Copyright (C) 2003-2008
alpar@267: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@267: * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@267: *
alpar@267: * Permission to use, modify and distribute this software is granted
alpar@267: * provided that this copyright notice appears in all copies. For
alpar@267: * precise terms see the accompanying LICENSE file.
alpar@267: *
alpar@267: * This software is provided "AS IS" with no warranty of any kind,
alpar@267: * express or implied, and with no claim as to its suitability for any
alpar@267: * purpose.
alpar@267: *
alpar@267: */
alpar@267:
alpar@267: /*!
alpar@267:
alpar@267: \page named-param Named Parameters
alpar@267:
alpar@267: \section named-func-param Named Function Parameters
alpar@267:
alpar@267: C++ makes it possible to use default parameter values when calling a
alpar@267: function. In such a case we do not have to give value for parameters,
alpar@267: the program will use the default ones. Unfortunately sometimes this
alpar@267: is not enough. If we do not want to give values for all the
alpar@267: parameters, only for some of them we come across problems, because an
alpar@267: arbitrary set of parameters cannot be omitted. On the other hand
alpar@267: parameters have a fixed order in the head of the function. C++ can
alpar@267: apply the default values only in the back of the order, if we do not
alpar@267: give other value for them. So we can not give the function for
alpar@267: example the value of the first, and the third parameter, expecting
alpar@267: that the program will aplly the default value for the second
alpar@267: parameter. However sometimes we would like to use some functinos
alpar@267: exactly in this way. With a crafty trick and with some little
alpar@267: inconvenience this is possible. We have implemented this little trick
alpar@267: as an example below.
alpar@267:
alpar@267: \code
alpar@267: class namedFn
alpar@267: {
alpar@267: int _id;
alpar@267: double _val;
alpar@267: int _dim;
alpar@267:
alpar@267: public:
alpar@267: namedFn() : _id(0), _val(1), _dim(2) {}
alpar@267: namedFn& id(int p) { _id = p ; return *this; }
alpar@267: namedFn& val(double p) { _val = p ; return *this; }
alpar@267: namedFn& dim(int p) { _dim = p ; return *this; }
alpar@267:
alpar@267: run() {
alpar@267: printf("Here is the function itself.");
alpar@267: }
alpar@267: };
alpar@267: \endcode
alpar@267:
alpar@267:
alpar@267: The usage is the following.
alpar@267:
alpar@267: We have to define a class, let's call it \c namedFn. Let us assume that
alpar@267: we would like to use a parameter, called \c X. In the \c namedFn class we
alpar@267: have to define an \c _X attribute, and a function \c X. The function
alpar@267: expects a parameter with the type of \c _X, and sets the value of
alpar@267: \c _X. After setting the value the function returns the class itself. The
alpar@267: class also have to have a function, called for example run(), we have
alpar@267: to implement here the original function itself. The constructor of the
alpar@267: class have to give all the attributes like \c _X the default values of
alpar@267: them.
alpar@267:
alpar@267: If we instantiate this class, the default values will be set for the
alpar@267: attributes (originally the parameters), initially. If we call function
alpar@267: \c X, we get a class with the modified parameter value of
alpar@267: \c X. Therefore we can modify any parameter-value, independently from the
alpar@267: order. To run the algorithm we have to call the run() function at the
alpar@267: end of the row.
alpar@267:
alpar@267: Example:
alpar@267: \code
alpar@267: namedFn().id(3).val(2).run();
alpar@267: \endcode
alpar@267:
alpar@267: \note Although it is a class, namedFn is used pretty much like as it were
alpar@267: a function. That it why it is called namedFn and not \c NamedFn.
alpar@267:
alpar@267: \note In fact, the final .run() could be made unnecessary if the
alpar@267: actual function code were put in the destructor instead. This however would make
alpar@267: hard to implement functions with return values, and would also make the
alpar@267: implementation of \ref named-templ-func-param "named template parameters"
alpar@267: very problematic. Therefore, by convention, .run() must be used
alpar@267: to explicitly execute function having named parameters in Lemon.
alpar@267:
alpar@267:
alpar@267: \section traits-classes Traits Classes
alpar@267:
alpar@267: The procedure above can also be applied when defining classes. In this
alpar@267: case the type of the attributes can be changed. Initially we have to
alpar@267: define a class with the default attribute types. This is the so called
alpar@267: Traits Class. Later on the types of these attributes can be changed,
alpar@267: as described below. In our software \ref lemon::DijkstraDefaultTraits is an
alpar@267: example of how a traits class looks like.
alpar@267:
alpar@267: \section named-templ-param Named Class Template Parameters
alpar@267:
alpar@267: If we would like to change the type of an attribute in a class that
alpar@267: was instantiated by using a traits class as a template parameter, and
alpar@267: the class contains named parameters, we do not have to reinstantiate
alpar@267: the class with new traits class. Instead of that, adaptor classes can
alpar@267: be used like in the following cases.
alpar@267:
alpar@267: \code
alpar@267: Dijkstra<>::SetPredNodeMap >::Create
alpar@267: \endcode
alpar@267:
alpar@267: It can also be used in conjunction with other named template
alpar@267: parameters in arbitrary order.
alpar@267:
alpar@267: \code
alpar@267: Dijkstra<>::SetDistMap::SetPredMap >::Create
alpar@267: \endcode
alpar@267:
alpar@267: The result will be an instantiated Dijkstra class, in which the
alpar@267: DistMap and the PredMap is modified.
alpar@267:
alpar@267: \section named-templ-func-param Named Function Template Parameters
alpar@267:
alpar@267: If the class has so called wizard functions, the new class with the
alpar@267: modified tpye of attributes can be returned by the appropriate wizard
alpar@267: function. The usage of these wizard functions is the following:
alpar@267:
alpar@267: */