File: loopManualTable.h

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (135 lines) | stat: -rw-r--r-- 4,263 bytes parent folder | download | duplicates (2)
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
125
126
127
128
129
130
131
132
133
134
135
/***********************************************/
/**
* @file loopManualTable.h
*
* @brief Loop over rows of a table containing strings.
*
* @author Sebastian Strasser
* @date 2017-02-20
*
*/
/***********************************************/

#ifndef __GROOPS_LOOPMANUALTABLE__
#define __GROOPS_LOOPMANUALTABLE__

// Latex documentation
#ifdef DOCSTRING_Loop
static const char *docstringLoopManualTable = R"(
\subsection{ManualTable}
Loop over rows of a table containing strings.
The table can be defined \config{rowWise} or \config{columnWise}.
Each row/column must have the same number of cells.
)";
#endif

/***********************************************/

#include "base/import.h"
#include "inputOutput/logging.h"
#include "classes/loop/loop.h"

/***** CLASS ***********************************/

/** @brief Loop over rows of a table containing strings.
* @ingroup loopGroup
* @see Loop */
class LoopManualTable : public Loop
{
public:
  class CellVector
  {
  public:
    std::vector<std::string> cells;
  };

private:
  std::vector<CellVector>  rows;
  std::vector<std::string> nameString;
  std::string              nameIndex, nameCount;

public:
  LoopManualTable(Config &config);

  UInt count() const override {return rows.size();}
  Bool iteration(VariableList &varList) override;
};

/***********************************************/
/***** Inlines *********************************/
/***********************************************/

template<> Bool readConfig(Config &config, const std::string &name, LoopManualTable::CellVector &var, Config::Appearance mustSet, const std::string &defaultValue, const std::string &annotation)
{
  if(!readConfigSequence(config, name, mustSet, defaultValue, annotation))
    return FALSE;
  readConfig(config, "cell", var.cells, Config::MUSTSET, "", "explicit list of cells in row/column");
  endSequence(config);
  return TRUE;
}

/***********************************************/

inline LoopManualTable::LoopManualTable(Config &config)
{
  try
  {
    std::vector<CellVector> columns;

    std::string choice;
    if(readConfigChoice(config, "table", choice, Config::MUSTSET, "", "define table by rows/columns"))
    {
      if(readConfigChoiceElement(config, "rowWise",    choice, "define table by rows"))
        readConfig(config, "row",    rows,    Config::MUSTSET, "", "define table by rows");
      if(readConfigChoiceElement(config, "columnWise", choice, "define table by columns"))
        readConfig(config, "column", columns, Config::MUSTSET, "", "define table by columns");
      endChoice(config);
    }
    readConfig(config, "variableLoopString", nameString, Config::MUSTSET,  "loopString", "1. variable name for the 1. column, next variable name for the 2. column, ... ");
    readConfig(config, "variableLoopIndex",  nameIndex,  Config::OPTIONAL, "",           "variable with index of current iteration (starts with zero)");
    readConfig(config, "variableLoopCount",  nameCount,  Config::OPTIONAL, "",           "variable with total number of iterations");
    readConfigCondition(config);
    if(isCreateSchema(config)) return;

    // transpose columns
    for(UInt i=0; i<columns.size(); i++)
      for(UInt k=0; k<columns.at(i).cells.size(); k++)
      {
        rows.resize(k+1);
        rows.at(k).cells.push_back(columns.at(i).cells.at(k));
      }

    if(rows.size() > 1)
    {
      if(nameString.size() > rows.at(0).cells.size())
        throw(Exception("More variables than columns in the table"));
      for(UInt i=1; i<rows.size(); i++)
        if(rows.at(i).cells.size() != rows.at(0).cells.size())
          throw(Exception("Varying number of columns in the table"));
     }
   }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/

inline Bool LoopManualTable::iteration(VariableList &varList)
{
  if(index() >= count())
    return FALSE;

  for(UInt i=0; i<nameString.size(); i++)
    if(!nameString.at(i).empty())
      varList.setVariable(nameString.at(i), rows.at(index()).cells.at(i));
  if(!nameIndex.empty()) varList.setVariable(nameIndex, index());
  if(!nameCount.empty()) varList.setVariable(nameCount, count());

  return checkCondition(varList);
}

/***********************************************/

#endif