source: finroc_plugins_data_ports/numeric/tNumber.h @ 179:34ddda735cf1

17.03
Last change on this file since 179:34ddda735cf1 was 179:34ddda735cf1, checked in by Max Reichardt <max.reichardt@…>, 20 months ago

Fixes == operator of tNumber for 32 bit float values

File size: 6.4 KB
Line 
1//
2// You received this file as part of Finroc
3// A framework for intelligent robot control
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    plugins/data_ports/numeric/tNumber.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2012-11-14
27 *
28 * \brief   Contains tNumber
29 *
30 * \b tNumber
31 *
32 * Type used in backend of all numeric ports.
33 * Can store integer as well as floating point values.
34 *
35 */
36//----------------------------------------------------------------------
37#ifndef __plugins__data_ports__numeric__tNumber_h__
38#define __plugins__data_ports__numeric__tNumber_h__
39
40//----------------------------------------------------------------------
41// External includes (system with <>, local with "")
42//----------------------------------------------------------------------
43#include "rrlib/rtti/rtti.h"
44
45//----------------------------------------------------------------------
46// Internal includes with ""
47//----------------------------------------------------------------------
48
49//----------------------------------------------------------------------
50// Namespace declaration
51//----------------------------------------------------------------------
52namespace finroc
53{
54namespace data_ports
55{
56namespace numeric
57{
58
59//----------------------------------------------------------------------
60// Forward declarations / typedefs / enums
61//----------------------------------------------------------------------
62
63//----------------------------------------------------------------------
64// Class declaration
65//----------------------------------------------------------------------
66//! Numeric value
67/*!
68 * Type used in backend of all numeric ports.
69 * Can store integer as well as floating point values.
70 */
71class tNumber
72{
73//----------------------------------------------------------------------
74// Public methods and typedefs
75//----------------------------------------------------------------------
76public:
77
78  /*! Type of value stored in union */
79  enum class tType : long int
80  {
81    INT64, FLOAT, DOUBLE
82  };
83
84  inline tNumber() :
85    integer_value(0),
86    number_type(tType::INT64)
87  {}
88
89  /*! constructor for all integral types. */
90  template<typename T>
91  inline tNumber(T value, typename std::enable_if<std::is_integral<T>::value, void*>::type unused = nullptr) :
92    integer_value(value),
93    number_type(tType::INT64)
94  {}
95
96  inline tNumber(double value) :
97    double_value(value),
98    number_type(tType::DOUBLE)
99  {}
100
101  inline tNumber(float value) :
102    float_value(value),
103    number_type(tType::FLOAT)
104  {}
105
106  /*!
107   * \return What kind of value is stored in this object?
108   */
109  inline tType GetNumberType() const
110  {
111    return number_type;
112  }
113
114  // All kinds of variations of setters
115  template<typename T>
116  inline void SetValue(T value, typename std::enable_if<std::is_integral<T>::value, void*>::type unused = nullptr)
117  {
118    this->integer_value = value;
119    number_type = tType::INT64;
120  }
121
122  inline void SetValue(float value)
123  {
124    this->float_value = value;
125    number_type = tType::FLOAT;
126  }
127
128  inline void SetValue(double value)
129  {
130    this->double_value = value;
131    number_type = tType::DOUBLE;
132  }
133
134  // returns raw numeric value
135  template <typename T>
136  T Value() const
137  {
138    switch (number_type)
139    {
140    case tType::INT64:
141      return static_cast<T>(integer_value);
142    case tType::DOUBLE:
143      return static_cast<T>(double_value);
144    case tType::FLOAT:
145      return static_cast<T>(float_value);
146    default:
147      assert(false && "Not a tNumber at this memory address");
148      return 0;
149    }
150  }
151
152  bool operator==(const tNumber& other) const
153  {
154    static_assert(sizeof(integer_value) == sizeof(double_value), "Implementation needs to be improved for this case");
155    return number_type == other.number_type && (number_type == tType::FLOAT ? (float_value == other.float_value) : (integer_value == other.integer_value));
156  }
157
158  bool operator!=(const tNumber& other) const
159  {
160    return !operator==(other);
161  }
162
163  bool operator<(const tNumber& other) const;
164
165  template <typename T>
166  explicit operator T() const
167  {
168    return Value<T>();
169  }
170
171//----------------------------------------------------------------------
172// Private fields and methods
173//----------------------------------------------------------------------
174private:
175
176  friend rrlib::serialization::tOutputStream& operator << (rrlib::serialization::tOutputStream& stream, const tNumber& number);
177  friend rrlib::serialization::tInputStream& operator >> (rrlib::serialization::tInputStream& stream, tNumber& number);
178
179  /*! Current numeric value */
180  union
181  {
182    int64_t integer_value;
183    double double_value;
184    float float_value;
185  };
186
187  /*!
188   * Determines what kind of value is stored in this object
189   * (and which value of the above union is used)
190   */
191  tType number_type;
192
193};
194
195rrlib::serialization::tOutputStream& operator << (rrlib::serialization::tOutputStream& stream, const tNumber& number);
196rrlib::serialization::tInputStream& operator >> (rrlib::serialization::tInputStream& stream, tNumber& number);
197rrlib::serialization::tStringOutputStream &operator << (rrlib::serialization::tStringOutputStream& stream, const tNumber& number);
198rrlib::serialization::tStringInputStream &operator >> (rrlib::serialization::tStringInputStream& stream, tNumber& number);
199std::ostream &operator << (std::ostream &stream, const tNumber& number);
200
201//----------------------------------------------------------------------
202// End of namespace declaration
203//----------------------------------------------------------------------
204}
205}
206}
207
208extern template struct rrlib::rtti::detail::tDataTypeInfo<finroc::data_ports::numeric::tNumber>;
209extern template struct rrlib::rtti::detail::tDataTypeInfo<std::vector<finroc::data_ports::numeric::tNumber>>;
210
211#endif
Note: See TracBrowser for help on using the repository browser.