1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/***********************************************/
/**
* @file loopLoop.h
*
* @brief Loop over nested loops.
*
* @author Matthias Ellmer
* @author Sebastian Strasser
* @date 2017-07-10
*
*/
/***********************************************/
#ifndef __GROOPS_LOOPLOOP__
#define __GROOPS_LOOPLOOP__
// Latex documentation
#ifdef DOCSTRING_Loop
static const char *docstringLoopLoop = R"(
\subsection{Loop}\label{loopType:loop}
Loop over nested loops. First \config{loop} is outermost loop, every subsequent \config{loop} is one level below the previous \config{loop}.
)";
#endif
/***********************************************/
#include "base/import.h"
#include "classes/loop/loop.h"
/***** CLASS ***********************************/
/** @brief Loop over nested loops.
* @ingroup loopGroup
* @see Loop */
class LoopLoop : public Loop
{
std::vector<Config> loopConfigs;
std::vector<LoopPtr> loops;
std::string nameIndex;
public:
LoopLoop(Config &config);
UInt count() const override;
Bool iteration(VariableList &varList) override;
};
/***********************************************/
/***** Inlines *********************************/
/***********************************************/
inline LoopLoop::LoopLoop(Config &config)
{
try
{
readConfigLater(config, "loop", loops, loopConfigs, Config::MUSTSET, "", "subloop");
readConfig(config, "variableLoopIndex", nameIndex, Config::OPTIONAL, "", "variable with index of current iteration (starts with zero)");
readConfigCondition(config);
if(isCreateSchema(config))
return;
loops.resize(loopConfigs.size());
}
catch(std::exception &e)
{
GROOPS_RETHROW(e)
}
}
/***********************************************/
inline UInt LoopLoop::count() const
{
UInt count = 1;
for(auto loop : loops)
if(loop)
count *= loop->count();
return std::max(index(), count);
}
/***********************************************/
inline Bool LoopLoop::iteration(VariableList &varList)
{
try
{
std::function<Bool(UInt)> initLoop = [&](UInt i) -> Bool
{
loopConfigs.at(i).read(loops.at(i), varList);
while(loops.at(i)->iteration(varList))
if((i+1 >= loops.size()) || initLoop(i+1))
return TRUE;
return FALSE;
};
if(index() == 0)
{
if(!initLoop(0))
return FALSE;
if(!nameIndex.empty())
varList.setVariable(nameIndex, index());
return checkCondition(varList);
}
for(UInt i=loops.size(); i-->0;)
while(loops.at(i)->iteration(varList))
if((i+1 >= loops.size()) || initLoop(i+1))
{
if(!nameIndex.empty())
varList.setVariable(nameIndex, index());
return checkCondition(varList);
}
return FALSE;
}
catch(std::exception &e)
{
GROOPS_RETHROW(e)
}
}
/***********************************************/
#endif
|