first example of automatic algorithm assembling
- add "Forges" tools, to wrap several operator with deferred instanciation. - add t-forge-algo to show how to enumerate several algorithms instances from a common grammar and several alternative operators. - add several missing className().
This commit is contained in:
parent
eba2e14950
commit
30c99f290f
14 changed files with 407 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
# ignore object and archive files
|
# ignore object and archive files
|
||||||
*.[oa]
|
*.[oa]
|
||||||
|
tags
|
||||||
|
|
||||||
# ignore auto-saved files
|
# ignore auto-saved files
|
||||||
*~
|
*~
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,8 @@
|
||||||
#include "other/external_eo"
|
#include "other/external_eo"
|
||||||
#include "eoCounter.h"
|
#include "eoCounter.h"
|
||||||
|
|
||||||
|
#include "eoForge.h"
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// to be continued ...
|
// to be continued ...
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@
|
||||||
|
|
||||||
@ingroup Selectors
|
@ingroup Selectors
|
||||||
*/
|
*/
|
||||||
template <class EOT> class eoDetTournamentSelect: public eoSelectOne<EOT>
|
template <class EOT>
|
||||||
|
class eoDetTournamentSelect: public eoSelectOne<EOT>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* (Default) Constructor -
|
/* (Default) Constructor -
|
||||||
|
|
@ -66,6 +67,8 @@ template <class EOT> class eoDetTournamentSelect: public eoSelectOne<EOT>
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned tSize;
|
unsigned tSize;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoDetTournamentSelect";}
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
201
eo/src/eoForge.h
Normal file
201
eo/src/eoForge.h
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
version 2 of the License.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
© 2020 Thales group
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Johann Dreo <johann.dreo@thalesgroup.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _eoForge_H_
|
||||||
|
#define _eoForge_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
#include <any>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
/** Interface for a "Forge": a class that can defer instanciation of EO's operator.
|
||||||
|
*
|
||||||
|
* This interface only declares an `instanciate` method,
|
||||||
|
* in order to be able to make containers of factories (@see eoForgeOperator).
|
||||||
|
*
|
||||||
|
* @ingroup Core
|
||||||
|
* @defgroup Forge Wrap and defer operators' instanciations.
|
||||||
|
* @ingroup Forge
|
||||||
|
*/
|
||||||
|
template<class Itf>
|
||||||
|
class eoForgeInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Itf& instanciate() = 0;
|
||||||
|
virtual ~eoForgeInterface() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** This "Forge" can defer the instanciation of an EO's operator.
|
||||||
|
*
|
||||||
|
* It allows to decouple the constructor's parameters setup from its actual call.
|
||||||
|
* You can declare a parametrized operator at a given time,
|
||||||
|
* then actually instanciate it (with the given interface) at another time.
|
||||||
|
*
|
||||||
|
* This allows for creating containers of pre-parametrized operators (@see eoForgeMap or @see eoForgeVector).
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
eoForgeOperator<eoselect<EOT>,eoRankMuSelect<EOT>> forge(mu);
|
||||||
|
// ^ desired ^ to-be-instanciated ^ operator's
|
||||||
|
// interface operator parameters
|
||||||
|
|
||||||
|
// Actual instanciation:
|
||||||
|
eoSelect<EOT>& select = forge.instanciate();
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @ingroup Forge
|
||||||
|
*/
|
||||||
|
template<class Itf, class Op, typename... Args>
|
||||||
|
class eoForgeOperator : public eoForgeInterface<Itf>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
eoForgeOperator(Args&&... args) :
|
||||||
|
_args(std::forward<Args>(args)...)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Itf& instanciate()
|
||||||
|
{
|
||||||
|
return *(constructor(_args));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~eoForgeOperator() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::tuple<Args...> _args;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <int... Idx>
|
||||||
|
struct index {};
|
||||||
|
|
||||||
|
template <int N, int... Idx>
|
||||||
|
struct gen_seq : gen_seq<N - 1, N - 1, Idx...> {};
|
||||||
|
|
||||||
|
template <int... Idx>
|
||||||
|
struct gen_seq<0, Idx...> : index<Idx...> {};
|
||||||
|
|
||||||
|
template <typename... Ts, int... Idx>
|
||||||
|
Op* constructor(std::tuple<Ts...>& args, index<Idx...>)
|
||||||
|
{
|
||||||
|
Op* p_op = new Op(std::get<Idx>(args)...);
|
||||||
|
return p_op;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
Op* constructor(std::tuple<Ts...>& args)
|
||||||
|
{
|
||||||
|
return constructor(args, gen_seq<sizeof...(Ts)>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A map holding an operator with deferred instanciation at a given key.
|
||||||
|
*
|
||||||
|
* @note You can actually store several instances of the same class,
|
||||||
|
* with different parametrization (or not).
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
eoForgeMap<eoSelect<EOT>> named_factories;
|
||||||
|
|
||||||
|
// Capture constructor's parameters and defer instanciation.
|
||||||
|
named_factories.add<eoRankMuSelect<EOT>>("RMS", 1);
|
||||||
|
named_factories.setup<eoRankMuSelect<EOT>>("RMS", 5); // Edit
|
||||||
|
|
||||||
|
// Actually instanciate.
|
||||||
|
eoSelect<EOT>& op = named_factories.instanciate("RMS");
|
||||||
|
|
||||||
|
// Call.
|
||||||
|
op();
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @ingroup Forge
|
||||||
|
*/
|
||||||
|
template<class Itf>
|
||||||
|
class eoForgeMap : public std::map<std::string, std::shared_ptr<eoForgeInterface<Itf>> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<class Op, typename... Args>
|
||||||
|
void setup(std::string key, Args&&... args)
|
||||||
|
{
|
||||||
|
auto opf = std::make_shared< eoForgeOperator<Itf,Op,Args...> >(std::forward<Args>(args)...);
|
||||||
|
(*this)[key] = opf;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Op, typename... Args>
|
||||||
|
void add(std::string key, Args&&... args)
|
||||||
|
{
|
||||||
|
setup<Op>(key, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
Itf& instanciate(std::string key)
|
||||||
|
{
|
||||||
|
return this->at(key)->instanciate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A vector holding an operator with deferred instanciation at a given index.
|
||||||
|
*
|
||||||
|
* @note You can actually store several instances of the same class,
|
||||||
|
* with different parametrization (or not).
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
eoForgeVector<eoSelect<EOT>> named_factories;
|
||||||
|
|
||||||
|
// Capture constructor's parameters and defer instanciation.
|
||||||
|
named_factories.add<eoRankMuSelect<EOT>>(1);
|
||||||
|
named_factories.setup<eoRankMuSelect<EOT>>(0, 5); // Edit
|
||||||
|
|
||||||
|
// Actually instanciate.
|
||||||
|
eoSelect<EOT>& op = named_factories.instanciate("RMS");
|
||||||
|
|
||||||
|
// Call.
|
||||||
|
op();
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @ingroup Forge
|
||||||
|
*/
|
||||||
|
template<class Itf>
|
||||||
|
class eoForgeVector : public std::vector<std::shared_ptr<eoForgeInterface<Itf>> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<class Op, typename... Args>
|
||||||
|
void add(Args&&... args)
|
||||||
|
{
|
||||||
|
auto opf = std::make_shared< eoForgeOperator<Itf,Op,Args...> >(std::forward<Args>(args)...);
|
||||||
|
this->push_back(opf);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Op, typename... Args>
|
||||||
|
void setup(size_t index, Args&&... args)
|
||||||
|
{
|
||||||
|
auto opf = std::make_shared< eoForgeOperator<Itf,Op,Args...> >(std::forward<Args>(args)...);
|
||||||
|
this->at(index) = opf;
|
||||||
|
}
|
||||||
|
|
||||||
|
Itf& instanciate(size_t index)
|
||||||
|
{
|
||||||
|
return this->at(index)->instanciate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _eoForge_H_
|
||||||
|
|
||||||
|
|
@ -59,6 +59,8 @@ public :
|
||||||
struct unary_function_tag {};
|
struct unary_function_tag {};
|
||||||
/// tag to identify a binary function in compile time function selection @see functor_category
|
/// tag to identify a binary function in compile time function selection @see functor_category
|
||||||
struct binary_function_tag {};
|
struct binary_function_tag {};
|
||||||
|
|
||||||
|
virtual std::string className() const { return "unknown";}
|
||||||
};
|
};
|
||||||
/** @example t-eoFunctor.cpp
|
/** @example t-eoFunctor.cpp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ class eoPlusReplacement : public eoMergeReduce<EOT>
|
||||||
private :
|
private :
|
||||||
eoPlus<EOT> plus;
|
eoPlus<EOT> plus;
|
||||||
eoTruncate<EOT> truncate;
|
eoTruncate<EOT> truncate;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoPlusReplacement";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -103,6 +105,8 @@ class eoCommaReplacement : public eoMergeReduce<EOT>
|
||||||
private :
|
private :
|
||||||
eoNoElitism<EOT> no_elite;
|
eoNoElitism<EOT> no_elite;
|
||||||
eoTruncate<EOT> truncate;
|
eoTruncate<EOT> truncate;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoCommaReplacement";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@
|
||||||
|
|
||||||
@ingroup Selectors
|
@ingroup Selectors
|
||||||
*/
|
*/
|
||||||
template <class EOT> class eoProportionalSelect: public eoSelectOne<EOT>
|
template <class EOT>
|
||||||
|
class eoProportionalSelect: public eoSelectOne<EOT>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Sanity check
|
/// Sanity check
|
||||||
|
|
@ -80,6 +81,8 @@ private :
|
||||||
|
|
||||||
typedef std::vector<typename EOT::Fitness> FitVec;
|
typedef std::vector<typename EOT::Fitness> FitVec;
|
||||||
FitVec cumulative;
|
FitVec cumulative;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoProportionalSelect";}
|
||||||
};
|
};
|
||||||
/** @example t-eoRoulette.cpp
|
/** @example t-eoRoulette.cpp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ class eoSSGAWorseReplacement : public eoReduceMerge<EOT>
|
||||||
private :
|
private :
|
||||||
eoLinearTruncate<EOT> truncate;
|
eoLinearTruncate<EOT> truncate;
|
||||||
eoPlus<EOT> plus;
|
eoPlus<EOT> plus;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoSSGAWorseReplacement";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -101,6 +103,8 @@ class eoSSGADetTournamentReplacement : public eoReduceMerge<EOT>
|
||||||
private :
|
private :
|
||||||
eoDetTournamentTruncate<EOT> truncate;
|
eoDetTournamentTruncate<EOT> truncate;
|
||||||
eoPlus<EOT> plus;
|
eoPlus<EOT> plus;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoSSGADetTournamentReplacement";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** SSGA stochastic tournament replacement. Is an eoReduceMerge.
|
/** SSGA stochastic tournament replacement. Is an eoReduceMerge.
|
||||||
|
|
@ -118,6 +122,8 @@ class eoSSGAStochTournamentReplacement : public eoReduceMerge<EOT>
|
||||||
private :
|
private :
|
||||||
eoStochTournamentTruncate<EOT> truncate;
|
eoStochTournamentTruncate<EOT> truncate;
|
||||||
eoPlus<EOT> plus;
|
eoPlus<EOT> plus;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoSSGAStochTournamentReplacement";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,8 @@ class eoGenerationalReplacement : public eoReplacement<EOT>
|
||||||
{
|
{
|
||||||
_parents.swap(_offspring);
|
_parents.swap(_offspring);
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoGenerationalReplacement ";}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -123,6 +125,8 @@ public :
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
eoReplacement<EOT> & replace;
|
eoReplacement<EOT> & replace;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoWeakElitistReplacement ";}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@ private:
|
||||||
bool ordered;
|
bool ordered;
|
||||||
unsigned current;
|
unsigned current;
|
||||||
std::vector<const EOT*> eoPters;
|
std::vector<const EOT*> eoPters;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoSequentialSelect";}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@
|
||||||
|
|
||||||
@ingroup Selectors
|
@ingroup Selectors
|
||||||
*/
|
*/
|
||||||
template <class EOT> class eoStochTournamentSelect: public eoSelectOne<EOT>
|
template <class EOT>
|
||||||
|
class eoStochTournamentSelect: public eoSelectOne<EOT>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -62,6 +63,8 @@ template <class EOT> class eoStochTournamentSelect: public eoSelectOne<EOT>
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double Trate;
|
double Trate;
|
||||||
|
public:
|
||||||
|
virtual std::string className() const {return "eoStochTournamentSelect";}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ set (TEST_LIST
|
||||||
t-eoParser
|
t-eoParser
|
||||||
t-eoPartiallyMappedXover
|
t-eoPartiallyMappedXover
|
||||||
t-eoEvalCmd
|
t-eoEvalCmd
|
||||||
|
t-operator-forge
|
||||||
|
t-forge-algo
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
110
eo/test/t-forge-algo.cpp
Normal file
110
eo/test/t-forge-algo.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
#include <ga.h>
|
||||||
|
#include "../../problems/eval/oneMaxEval.h"
|
||||||
|
|
||||||
|
int main(int /*argc*/, char** /*argv*/)
|
||||||
|
{
|
||||||
|
size_t dim = 500;
|
||||||
|
size_t pop_size = 10;
|
||||||
|
|
||||||
|
eo::log << eo::setlevel(eo::warnings);
|
||||||
|
|
||||||
|
using EOT = eoBit<double>;
|
||||||
|
|
||||||
|
oneMaxEval<EOT> eval;
|
||||||
|
|
||||||
|
eoBooleanGenerator gen(0.5);
|
||||||
|
eoInitFixedLength<EOT> init(dim, gen);
|
||||||
|
|
||||||
|
eoForgeVector< eoContinue<EOT> > continuators;
|
||||||
|
continuators.add< eoSteadyFitContinue<EOT> >(10,10);
|
||||||
|
continuators.add< eoGenContinue<EOT> >(100);
|
||||||
|
|
||||||
|
eoForgeVector< eoQuadOp<EOT> > crossovers;
|
||||||
|
crossovers.add< eo1PtBitXover<EOT> >();
|
||||||
|
crossovers.add< eoUBitXover<EOT> >(0.5); // preference over 1
|
||||||
|
crossovers.add< eoNPtsBitXover<EOT> >(2); // nb of points
|
||||||
|
|
||||||
|
eoForgeVector< eoMonOp<EOT> > mutations;
|
||||||
|
mutations.add< eoBitMutation<EOT> >(0.01); // proba of flipping one bit
|
||||||
|
mutations.add< eoDetBitFlip<EOT> >(1); // mutate k bits
|
||||||
|
|
||||||
|
eoForgeVector< eoSelectOne<EOT> > selectors;
|
||||||
|
selectors.add< eoDetTournamentSelect<EOT> >(pop_size/2);
|
||||||
|
selectors.add< eoStochTournamentSelect<EOT> >(0.5);
|
||||||
|
selectors.add< eoSequentialSelect<EOT> >();
|
||||||
|
selectors.add< eoProportionalSelect<EOT> >();
|
||||||
|
|
||||||
|
eoForgeVector< eoReplacement<EOT> > replacors;
|
||||||
|
replacors.add< eoCommaReplacement<EOT> >();
|
||||||
|
replacors.add< eoPlusReplacement<EOT> >();
|
||||||
|
replacors.add< eoSSGAWorseReplacement<EOT> >();
|
||||||
|
replacors.add< eoSSGADetTournamentReplacement<EOT> >(pop_size/2);
|
||||||
|
replacors.add< eoSSGAStochTournamentReplacement<EOT> >(0.51);
|
||||||
|
|
||||||
|
std::clog << continuators.size() * crossovers.size() * mutations.size() * selectors.size() * replacors.size()
|
||||||
|
<< " algorithm instances to test." << std::endl;
|
||||||
|
|
||||||
|
EOT best_sol;
|
||||||
|
std::string best_algo = "";
|
||||||
|
|
||||||
|
for(auto& forge_cont : continuators) {
|
||||||
|
auto& continuator = forge_cont->instanciate();
|
||||||
|
|
||||||
|
for(auto& forge_cross : crossovers) {
|
||||||
|
auto& crossover = forge_cross->instanciate();
|
||||||
|
|
||||||
|
for(auto& forge_mut : mutations ) {
|
||||||
|
auto& mutation = forge_mut->instanciate();
|
||||||
|
|
||||||
|
for(auto& forge_sel : selectors) {
|
||||||
|
auto& selector = forge_sel->instanciate();
|
||||||
|
|
||||||
|
for(auto& forge_rep : replacors) {
|
||||||
|
auto& replacor = forge_rep->instanciate();
|
||||||
|
|
||||||
|
std::ostringstream algo_name;
|
||||||
|
algo_name << continuator.className() << " + "
|
||||||
|
<< crossover.className() << " + "
|
||||||
|
<< mutation.className() << " + "
|
||||||
|
<< selector.className() << " + "
|
||||||
|
<< replacor.className();
|
||||||
|
|
||||||
|
std::clog << "ALGO: " << algo_name.str();
|
||||||
|
std::clog.flush();
|
||||||
|
|
||||||
|
eoSequentialOp<EOT> variator;
|
||||||
|
variator.add(crossover, 1.0);
|
||||||
|
variator.add(mutation, 1.0);
|
||||||
|
|
||||||
|
eoGeneralBreeder<EOT> breeder(selector, variator, 1.0);
|
||||||
|
|
||||||
|
eoEasyEA<EOT> algo(continuator, eval, breeder, replacor);
|
||||||
|
|
||||||
|
eoPop<EOT> pop;
|
||||||
|
pop.append(pop_size, init);
|
||||||
|
apply(eval,pop);
|
||||||
|
|
||||||
|
algo(pop);
|
||||||
|
|
||||||
|
std::clog << " = " << pop.best_element().fitness() << std::endl;
|
||||||
|
|
||||||
|
if(best_sol.invalid()) {
|
||||||
|
best_sol = pop.best_element();
|
||||||
|
best_algo = algo_name.str();
|
||||||
|
} else if(pop.best_element().fitness() > best_sol.fitness()) {
|
||||||
|
best_sol = pop.best_element();
|
||||||
|
best_algo = algo_name.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "Best algo: " << best_algo << ", with " << best_sol << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
61
eo/test/t-operator-forge.cpp
Normal file
61
eo/test/t-operator-forge.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
struct OpInterface
|
||||||
|
{
|
||||||
|
std::string _name;
|
||||||
|
OpInterface(std::string name) : _name(name) {}
|
||||||
|
virtual void operator()() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpA : public OpInterface
|
||||||
|
{
|
||||||
|
OpA(std::string name) : OpInterface(name) {}
|
||||||
|
void operator()(){std::cout << _name << std::endl;}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpB : public OpInterface
|
||||||
|
{
|
||||||
|
OpB(std::string name, std::string suffix) : OpInterface(name+suffix) {}
|
||||||
|
void operator()(){std::cout << _name << std::endl;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int /*argc*/, char** /*argv*/)
|
||||||
|
{
|
||||||
|
// Forge container using names.
|
||||||
|
eoForgeMap<OpInterface> named_factories;
|
||||||
|
|
||||||
|
// Capture constructor's parameters and defer instanciation.
|
||||||
|
named_factories.add<OpA>("OpA", "I'm A");
|
||||||
|
named_factories.setup<OpA>("OpA", "I'm actually A"); // Edit
|
||||||
|
named_factories.add<OpB>("OpB1", "I'm B", " prime");
|
||||||
|
named_factories.add<OpB>("OpB2", "I'm a B", " junior");
|
||||||
|
|
||||||
|
// Actually instanciante.
|
||||||
|
OpInterface& opa = named_factories.instanciate("OpA");
|
||||||
|
OpInterface& opb1 = named_factories.instanciate("OpB1");
|
||||||
|
|
||||||
|
// Call.
|
||||||
|
opa();
|
||||||
|
opb1();
|
||||||
|
|
||||||
|
// Instanciate and call.
|
||||||
|
named_factories.instanciate("OpB2")();
|
||||||
|
|
||||||
|
|
||||||
|
// Forge container using indices.
|
||||||
|
eoForgeVector<OpInterface> indexed_factories;
|
||||||
|
|
||||||
|
// Capture constructor's parameters and defer instanciation.
|
||||||
|
indexed_factories.add<OpA>("I'm A");
|
||||||
|
indexed_factories.setup<OpA>(0, "I'm actually A"); // Edit
|
||||||
|
indexed_factories.add<OpB>("I'm B", " prime");
|
||||||
|
indexed_factories.add<OpB>("I'm a B", " junior");
|
||||||
|
|
||||||
|
// Actually instanciante and call.
|
||||||
|
indexed_factories.instanciate(0)();
|
||||||
|
indexed_factories.instanciate(1)();
|
||||||
|
indexed_factories.instanciate(2)();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue