Langmuir
Simulation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
variable.h
Go to the documentation of this file.
1 #ifndef VARIABLE_H
2 #define VARIABLE_H
3 
4 #include <QTextStream>
5 #include <QDateTime>
6 #include <QObject>
7 #include <QDebug>
8 #include <limits>
9 #include <ostream>
10 
11 namespace LangmuirCore
12 {
13 
14 // output QDateTime as qint64 mSecsSinceEpoch
15 // must be declared before template functions
16 inline QTextStream& operator<<(QTextStream& stream, const QDateTime& datetime);
17 
19 /*
20  The class is a template so that it may point to arbitray data types. In order to
21  add a new data type you must implement the following, with \b 'T' replaced by your
22  new type:
23  - template <> inline void Variable<T>::convert(const QString& token, T& result)
24  - inline QTextStream& operator<<(QTextStream& stream, const T& variable)
25  */
26 class Variable : public QObject
27 {
28  Q_OBJECT
29 public:
32  {
33  Constant = 1
34  };
35  Q_FLAGS(ModeFlag)
36  Q_DECLARE_FLAGS(VariableMode, VariableModeFlag)
37 
39  Variable(
40  const QString &key,
41  VariableMode mode = 0,
42  QObject *parent = 0);
43 
45 
49  virtual void read(const QString& token) = 0;
50 
52  virtual QString key() const = 0;
53 
55  virtual QString value() const = 0;
56 
58  virtual QString keyValue() const = 0;
59 
61  bool isConstant() const;
62 
64  const VariableMode& mode() const;
65 
67  friend QTextStream& operator<<(QTextStream& stream, const Variable &variable);
68 
70  friend QDebug operator<<(QDebug dbg, const Variable &variable);
71 
73  friend std::ostream& operator<<(std::ostream &stream, Variable &variable);
74 
75 protected:
76 
78  QString m_key;
79 
81  VariableMode m_mode;
82 
84  virtual void write(QTextStream& stream) const = 0;
85 
86 };
87 Q_DECLARE_OPERATORS_FOR_FLAGS(Variable::VariableMode)
88 
90 template <class T>
91 class TypedVariable : public Variable
92 {
93 public:
94 
96 
103  const QString& key,
104  T &value,
105  VariableMode mode = 0,
106  QObject *parent = 0);
107 
109  virtual void read(const QString& token);
110 
112  virtual QString key() const;
113 
115  virtual QString value() const;
116 
118  virtual QString keyValue() const;
119 
121 
126  static void convert(const QString& token, T& result);
127 
128 protected:
131 
133  virtual void write(QTextStream& stream) const;
134 };
135 
138  const QString &key,
139  VariableMode mode,
140  QObject *parent)
141  : QObject(parent),
142  m_key(key),
143  m_mode(mode)
144 {
145 }
146 
148 template <class T> inline QString TypedVariable<T>::key() const
149 {
150  return m_key;
151 }
152 
154 template <class T> inline QString TypedVariable<T>::value() const
155 {
156  QString result; QTextStream stream(&result);
157  stream << m_value;
158  stream.flush();
159  return result;
160 }
161 
163 template <> inline QString TypedVariable<float>::value() const
164 {
165  QString result; QTextStream stream(&result);
166  stream << qSetRealNumberPrecision(std::numeric_limits<float>::digits10)
167  << scientific
168  << m_value;
169  stream.flush();
170  return result;
171 }
172 
174 template <> inline QString TypedVariable<qreal>::value() const
175 {
176  QString result; QTextStream stream(&result);
177  stream << qSetRealNumberPrecision(std::numeric_limits<qreal>::digits10)
178  << scientific
179  << m_value;
180  stream.flush();
181  return result;
182 }
183 
185 template <> inline QString TypedVariable<bool>::value() const
186 {
187  QString result; QTextStream stream(&result);
188  if (m_value == true) { stream << "True"; }
189  else { stream << "False"; }
190  stream.flush();
191  return result;
192 }
193 
195 template <class T> inline QString TypedVariable<T>::keyValue() const
196 {
197  QString result; QTextStream stream(&result);
198  stream << left
199  << qSetFieldWidth(30)
200  << key();
201  QString theValue = value();
202  if (theValue.startsWith('-'))
203  {
204  stream << qSetFieldWidth(2)
205  << '='
206  << qSetFieldWidth(0)
207  << theValue;
208  }
209  else
210  {
211  stream << qSetFieldWidth(3)
212  << '='
213  << qSetFieldWidth(0)
214  << theValue;
215  }
216  stream.flush();
217  return result;
218 }
219 
221 template <> inline QString TypedVariable<QString>::keyValue() const
222 {
223  QString result; QTextStream stream(&result);
224  stream << left
225  << qSetFieldWidth(30)
226  << key();
227  if (m_value.isEmpty())
228  {
229  stream << qSetFieldWidth(0)
230  << '=';
231  }
232  else
233  {
234  stream << qSetFieldWidth(3)
235  << '='
236  << qSetFieldWidth(0)
237  << value();
238  }
239  stream.flush();
240  return result;
241 }
242 
244 inline bool Variable::isConstant() const
245 {
246  return m_mode.testFlag(Constant);
247 }
248 
250 inline const Variable::VariableMode& Variable::mode() const
251 {
252  return m_mode;
253 }
254 
256 template <class T> inline TypedVariable<T>::TypedVariable(
257  const QString& key,
258  T &value,
259  VariableMode mode,
260  QObject *parent)
261  : Variable(key,mode,parent),
262  m_value(value)
263 {
264 }
265 
267 template <class T> inline void TypedVariable<T>::read(const QString& token)
268 {
269  if (m_mode.testFlag(Constant))
270  {
271  qDebug("langmuir: ignoring constant; key: %s, token: %s",
272  qPrintable(m_key),qPrintable(token));
273  return;
274  }
275  convert(token,m_value);
276 }
277 
279 template <class T> inline void TypedVariable<T>::write(QTextStream& stream) const
280 {
281  stream << keyValue();
282 }
283 
285 inline QTextStream& operator<<(QTextStream& stream, const Variable& variable)
286 {
287  variable.write(stream);
288  return stream;
289 }
290 
292 inline QDebug operator<<(QDebug dbg, const Variable &variable)
293 {
294  QString string; QTextStream stream(&string);
295  stream << variable;
296  stream.flush();
297  dbg.nospace() << qPrintable(string);
298  return dbg.space();
299 }
300 
302 inline std::ostream& operator<<(std::ostream &stream, Variable &variable)
303 {
304  stream << variable.keyValue().toStdString();
305  return stream;
306 }
307 
309 template <> inline void TypedVariable<QString>::convert(const QString& token, QString& result)
310 {
311  result = token.trimmed();
312 }
313 
315 template <> inline void TypedVariable<qreal>::convert(const QString& token, qreal& result)
316 {
317  bool ok = false;
318  result = token.toDouble(&ok);
319  if (!ok) qFatal("langmuir: can not convert to double: %s", qPrintable(token));
320 }
321 
323 template <> inline void TypedVariable<float>::convert(const QString& token, float& result)
324 {
325  bool ok = false;
326  result = token.toFloat(&ok);
327  if (!ok) qFatal("langmuir: can not convert to double: %s", qPrintable(token));
328 }
329 
331 template <> inline void TypedVariable<bool>::convert(const QString& token, bool& result)
332 {
333  QString lower = token.trimmed().toLower();
334  if (lower == "false")
335  {
336  result = false;
337  }
338  else if (lower == "true")
339  {
340  result = true;
341  }
342  else
343  {
344  bool ok = false;
345  result = token.toInt(&ok);
346  if (!ok) qFatal("langmuir: can not convert to bool: %s", qPrintable(token));
347  }
348 }
349 
351 template <> inline void TypedVariable<qint32>::convert(const QString& token, qint32& result)
352 {
353  bool ok = false;
354  result = token.toInt(&ok);
355  if (!ok) qFatal("langmuir: can not convert to int: %s", qPrintable(token));
356 }
357 
359 template <> inline void TypedVariable<quint32>::convert(const QString& token, quint32& result)
360 {
361  bool ok = false;
362  result = token.toUInt(&ok);
363  if (!ok) qFatal("langmuir: can not convert to unsigned int: %s", qPrintable(token));
364 }
365 
367 template <> inline void TypedVariable<qint64>::convert(const QString& token, qint64& result)
368 {
369  bool ok = false;
370  result = token.toLongLong(&ok);
371  if (!ok) qFatal("langmuir: can not convert to long long int: %s", qPrintable(token));
372 }
373 
375 template <> inline void TypedVariable<quint64>::convert(const QString& token, quint64& result)
376 {
377  bool ok = false;
378  result = token.toULongLong(&ok);
379  if (!ok) qFatal("langmuir: can not convert to unsigned long long int: %s", qPrintable(token));
380 }
381 
383 template <> inline void TypedVariable<QDateTime>::convert(const QString& token, QDateTime& result)
384 {
385  bool ok = false;
386  qint64 msecSinceEpoch = token.toLongLong(&ok);
387  if (!ok) qFatal("langmuir: can not convert to QDateTime (expecting long long int): %s", qPrintable(token));
388  result = QDateTime::fromMSecsSinceEpoch(msecSinceEpoch);
389 }
390 
392 inline QTextStream& operator<<(QTextStream& stream, const QDateTime& datetime)
393 {
394  stream << datetime.toMSecsSinceEpoch();
395  return stream;
396 }
397 
398 }
399 
400 #endif // VARIABLE_H
const VariableMode & mode() const
Get this variable's mode flags.
Definition: variable.h:250
virtual void write(QTextStream &stream) const
Write 'key = value' to a stream.
Definition: variable.h:279
virtual QString key() const =0
Get this variable's key (name)
QTextStream & operator<<(QTextStream &stream, const Agent::Type e)
Output Agent type enum to stream.
Definition: agent.h:172
static void convert(const QString &token, T &result)
A template function for converting a QString to some type T.
virtual QString value() const =0
Get this variable's value as a QString.
A template class to map between variable names (keys) and locations (references)
Definition: variable.h:91
A class to map between variable names (keys) and locations (references)
Definition: variable.h:26
VariableMode m_mode
The mode flags for this variable.
Definition: variable.h:81
Variable(const QString &key, VariableMode mode=0, QObject *parent=0)
Create a Variable, see Variable::Variable for description.
Definition: variable.h:137
virtual QString keyValue() const
Get this variable's key and value in the form 'key = value'.
Definition: variable.h:195
virtual void read(const QString &token)
Cast the value stored in string to the correct type and store it in the correct location.
Definition: variable.h:267
TypedVariable(const QString &key, T &value, VariableMode mode=0, QObject *parent=0)
Create a new variable.
Definition: variable.h:256
T & m_value
Reference to the object being tracked.
Definition: variable.h:130
virtual QString value() const
Get this variable's value as a QString.
Definition: variable.h:154
When constant, a variable's read / convert function does nothing.
Definition: variable.h:33
Definition: agent.h:12
virtual QString keyValue() const =0
Get this variable's key and value in the form 'key = value'.
virtual QString key() const
Get this variable's key (name)
Definition: variable.h:148
bool isConstant() const
True if the Variable::Constant mode flag was set.
Definition: variable.h:244
virtual void read(const QString &token)=0
Cast the value stored in string to the correct type and store it in the correct location.
VariableModeFlag
A Flag to alter the behavoir of certain variable member functions.
Definition: variable.h:31
virtual void write(QTextStream &stream) const =0
Write 'key = value' to a stream.
QString m_key
The name of this variable.
Definition: variable.h:78