GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/task/multi-bound.cpp Lines: 109 158 69.0 %
Date: 2023-03-13 12:09:37 Branches: 67 223 30.0 %

Line Branch Exec Source
1
/*
2
 * Copyright 2010,
3
 * François Bleibel,
4
 * Olivier Stasse,
5
 *
6
 * CNRS/AIST
7
 *
8
 */
9
10
#include <sot/core/multi-bound.hh>
11
//#define VP_DEBUG_MODE 25
12
#include <sot/core/debug.hh>
13
14
using namespace dynamicgraph::sot;
15
16
1589
MultiBound::MultiBound(const double x)
17
    : mode(MODE_SINGLE),
18
      boundSingle(x),
19
      boundSup(0),
20
      boundInf(0),
21
      boundSupSetup(false),
22
1589
      boundInfSetup(false) {}
23
24
1
MultiBound::MultiBound(const double xi, const double xs)
25
    : mode(MODE_DOUBLE),
26
      boundSingle(0),
27
      boundSup(xs),
28
      boundInf(xi),
29
      boundSupSetup(true),
30
1
      boundInfSetup(true) {}
31
32
2
MultiBound::MultiBound(const double x, const MultiBound::SupInfType bound)
33
    : mode(MODE_DOUBLE),
34
      boundSingle(0),
35
2
      boundSup((bound == BOUND_SUP) ? x : 0),
36
2
      boundInf((bound == BOUND_INF) ? x : 0),
37
2
      boundSupSetup(bound == BOUND_SUP),
38

4
      boundInfSetup(bound == BOUND_INF) {}
39
40
MultiBound::MultiBound(const MultiBound &clone)
41
    : mode(clone.mode),
42
      boundSingle(clone.boundSingle),
43
      boundSup(clone.boundSup),
44
      boundInf(clone.boundInf),
45
      boundSupSetup(clone.boundSupSetup),
46
      boundInfSetup(clone.boundInfSetup) {}
47
48
MultiBound::MultiBoundModeType MultiBound::getMode(void) const { return mode; }
49
1500
double MultiBound::getSingleBound(void) const {
50
1500
  if (MODE_SINGLE != mode) {
51
    SOT_THROW ExceptionTask(ExceptionTask::BOUND_TYPE,
52
                            "Accessing single bound of a non-single type.");
53
  }
54
1500
  return boundSingle;
55
}
56
double MultiBound::getDoubleBound(const MultiBound::SupInfType bound) const {
57
  if (MODE_DOUBLE != mode) {
58
    SOT_THROW ExceptionTask(ExceptionTask::BOUND_TYPE,
59
                            "Accessing double bound of a non-double type.");
60
  }
61
  switch (bound) {
62
    case BOUND_SUP: {
63
      if (!boundSupSetup) {
64
        SOT_THROW ExceptionTask(ExceptionTask::BOUND_TYPE,
65
                                "Accessing un-setup sup bound.");
66
      }
67
      return boundSup;
68
    }
69
    case BOUND_INF: {
70
      if (!boundInfSetup) {
71
        SOT_THROW ExceptionTask(ExceptionTask::BOUND_TYPE,
72
                                "Accessing un-setup inf bound");
73
      }
74
      return boundInf;
75
    }
76
  }
77
  return 0;
78
}
79
bool MultiBound::getDoubleBoundSetup(const MultiBound::SupInfType bound) const {
80
  if (MODE_DOUBLE != mode) {
81
    SOT_THROW ExceptionTask(ExceptionTask::BOUND_TYPE,
82
                            "Accessing double bound of a non-double type.");
83
  }
84
  switch (bound) {
85
    case BOUND_SUP:
86
      return boundSupSetup;
87
    case BOUND_INF:
88
      return boundInfSetup;
89
  }
90
  return false;
91
}
92
8
void MultiBound::setDoubleBound(SupInfType boundType, double boundValue) {
93
8
  if (MODE_DOUBLE != mode) {
94
2
    mode = MODE_DOUBLE;
95
2
    boundSupSetup = false;
96
2
    boundInfSetup = false;
97
  }
98
8
  switch (boundType) {
99
4
    case BOUND_INF:
100
4
      boundInfSetup = true;
101
4
      boundInf = boundValue;
102
4
      break;
103
4
    case BOUND_SUP:
104
4
      boundSupSetup = true;
105
4
      boundSup = boundValue;
106
4
      break;
107
  }
108
8
}
109
4
void MultiBound::unsetDoubleBound(SupInfType boundType) {
110
4
  if (MODE_DOUBLE != mode) {
111
1
    mode = MODE_DOUBLE;
112
1
    boundSupSetup = false;
113
1
    boundInfSetup = false;
114
  } else {
115
3
    switch (boundType) {
116
1
      case BOUND_INF:
117
1
        boundInfSetup = false;
118
1
        break;
119
2
      case BOUND_SUP:
120
2
        boundSupSetup = false;
121
2
        break;
122
    }
123
  }
124
4
}
125
2
void MultiBound::setSingleBound(double boundValue) {
126
2
  mode = MODE_SINGLE;
127
2
  boundSingle = boundValue;
128
2
}
129
130
7
inline static void SOT_MULTI_BOUND_CHECK_C(std::istream &is, char check,
131
                                           VectorMultiBound &v) {
132
  char c;
133
7
  is.get(c);
134
7
  if (c != check) {
135
    v.resize(0);
136
    sotERROR << "Error while parsing vector multi-bound. Waiting for a '"
137
             << check << "'. Get '" << c << "' instead. " << std::endl;
138
    SOT_THROW ExceptionTask(ExceptionTask::PARSER_MULTI_BOUND,
139
                            "Error parsing vector multi-bound.");
140
  }
141
7
}
142
143
namespace dynamicgraph {
144
namespace sot {
145
146
44
std::ostream &operator<<(std::ostream &os, const MultiBound &m) {
147
44
  switch (m.mode) {
148
29
    case MultiBound::MODE_SINGLE: {
149
29
      os << m.boundSingle;
150
29
      break;
151
    }
152
15
    case MultiBound::MODE_DOUBLE: {
153
15
      os << "(";
154
15
      if (m.boundInfSetup)
155
10
        os << m.boundInf;
156
      else
157
5
        os << "--";
158
15
      os << ",";
159
15
      if (m.boundSupSetup)
160
10
        os << m.boundSup;
161
      else
162
5
        os << "--";
163
15
      os << ")";
164
15
      break;
165
    }
166
  }
167
44
  return os;
168
}
169
170
8
std::istream &operator>>(std::istream &is, MultiBound &m) {
171
  sotDEBUGIN(15);
172
  char c;
173
  double val;
174
8
  is.get(c);
175
8
  if (c == '(') {
176
    sotDEBUG(15) << "Double" << std::endl;
177
    char c2[3];
178
6
    is.get(c2, 3);
179

6
    if (std::string(c2, 2) != "--") {
180
4
      is.putback(c2[1]);
181
4
      is.putback(c2[0]);
182
      //{char strbuf[256]; is.getline(strbuf,256); sotDEBUG(1) <<
183
      //"#"<<strbuf<<"#"<<std::endl;}
184
4
      is >> val;
185
      sotDEBUG(15) << "First val = " << val << std::endl;
186
4
      m.setDoubleBound(MultiBound::BOUND_INF, val);
187
    } else {
188
2
      m.unsetDoubleBound(MultiBound::BOUND_INF);
189
    }
190
6
    is.get(c);
191
6
    if (c != ',') {
192
      sotERROR << "Error while parsing multi-bound. Waiting for a ','. Get '"
193
               << c << "' instead. " << std::endl;
194
      SOT_THROW ExceptionTask(
195
          ExceptionTask::PARSER_MULTI_BOUND,
196
          "Error parsing multi-bound, while waiting for a ','.");
197
    }
198
199
6
    is.get(c2, 3);
200

6
    if (std::string(c2, 2) != "--") {
201
4
      is.putback(c2[1]);
202
4
      is.putback(c2[0]);
203
4
      is >> val;
204
      sotDEBUG(15) << "Second val = " << val << std::endl;
205
4
      m.setDoubleBound(MultiBound::BOUND_SUP, val);
206
    } else {
207
2
      m.unsetDoubleBound(MultiBound::BOUND_SUP);
208
    }
209
6
    is.get(c);
210
6
    if (c != ')') {
211
      sotERROR << "Error while parsing multi-bound. Waiting for a ')'. Get '"
212
               << c << "' instead. " << std::endl;
213
      SOT_THROW ExceptionTask(
214
          ExceptionTask::PARSER_MULTI_BOUND,
215
          "Error parsing multi-bound, while waiting for a ')'.");
216
    }
217
  } else {
218
    sotDEBUG(15) << "Single ('" << c << "')" << std::endl;
219
2
    is.putback(c);
220
2
    is >> val;
221
2
    m.setSingleBound(val);
222
  }
223
224
  sotDEBUGOUT(15);
225
8
  return is;
226
}
227
228
5
std::ostream &operator<<(std::ostream &os, const VectorMultiBound &v) {
229
5
  os << "[" << v.size() << "](";
230
33
  for (VectorMultiBound::const_iterator iter = v.begin(); iter != v.end();
231
28
       ++iter) {
232

28
    if (iter != v.begin()) os << ",";
233
28
    os << (*iter);
234
  }
235
5
  return os << ")";
236
}
237
238
1
std::istream &operator>>(std::istream &is, VectorMultiBound &v) {
239
  unsigned int vali;
240
241
  /* Read the vector size. */
242
1
  SOT_MULTI_BOUND_CHECK_C(is, '[', v);
243
1
  is >> vali;
244
1
  v.resize(vali);
245
1
  SOT_MULTI_BOUND_CHECK_C(is, ']', v);
246
247
  /* Loop for the vals. */
248
1
  SOT_MULTI_BOUND_CHECK_C(is, '(', v);
249
5
  for (unsigned int i = 0; i < vali; ++i) {
250
4
    is >> v[i];
251
4
    if (i != vali - 1) {
252
3
      SOT_MULTI_BOUND_CHECK_C(is, ',', v);
253
    } else {
254
1
      SOT_MULTI_BOUND_CHECK_C(is, ')', v);
255
    }
256
  }
257
258
1
  return is;
259
}
260
261
} /* namespace sot */
262
} /* namespace dynamicgraph */