type_safe.h Source File

CPP API: type_safe.h Source File
type_safe.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Daniel Abele
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MIO_UTILS_TYPE_SAFE_H
21 #define MIO_UTILS_TYPE_SAFE_H
22 
23 #include "memilio/io/io.h"
24 #include <ostream>
25 
26 namespace mio
27 {
28 
57 template <class T, class Derived>
58 class TypeSafe
59 {
60 public:
61  using ValueType = T;
62 
66  TypeSafe() = default;
67 
71  explicit TypeSafe(T t)
72  : m_t(t)
73  {
74  }
75 
80  explicit operator T() const
81  {
82  return m_t;
83  }
84 
89  T get() const
90  {
91  return m_t;
92  }
93 
97  friend bool operator==(const Derived& a, const Derived& b)
98  {
99  return a.m_t == b.m_t;
100  }
101  friend bool operator!=(const Derived& a, const Derived& b)
102  {
103  return !(a == b);
104  }
105 
109  friend std::ostream& operator<<(std::ostream& os, const Derived& ts)
110  {
111  return (os << ts.m_t);
112  }
113 
118  template <class IOContext>
119  void serialize(IOContext& io) const
120  {
121  mio::serialize(io, T(*this));
122  }
123 
128  template <class IOContext>
129  static IOResult<Derived> deserialize(IOContext& io)
130  {
131  BOOST_OUTCOME_TRY(auto&& t, mio::deserialize(io, Tag<T>{}));
132  return success(Derived(t));
133  }
134 
135 private:
136  T m_t;
137 };
138 
143 template <class TS>
145 {
146 public:
148  {
149  return static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() + 1};
150  }
151  TS operator++(int)
152  {
153  auto tmp = static_cast<TS&>(*this);
154  static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() + 1};
155  return tmp;
156  }
158  {
159  return static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() - 1};
160  }
161  TS operator--(int)
162  {
163  auto tmp = static_cast<TS&>(*this);
164  static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() - 1};
165  return tmp;
166  }
167 };
168 
173 template <class TS>
175 {
176 public:
177  TS operator+(const TS& other) const
178  {
179  return TS{static_cast<const TS&>(*this).get() + other.get()};
180  }
181  TS& operator+=(const TS& other)
182  {
183  return static_cast<TS&>(*this) = (*this + other);
184  }
185  TS operator-(const TS& other) const
186  {
187  return TS{static_cast<const TS&>(*this).get() - other.get()};
188  }
189  TS& operator-=(const TS& other)
190  {
191  return static_cast<TS&>(*this) = (*this - other);
192  }
193 };
194 
200 template <class TS, class S> //S can't default to TS::ValueType because TS is imcomplete
202 {
203 public:
204  TS operator*(const S& other) const
205  {
206  return TS{static_cast<const TS&>(*this).get() * other};
207  }
208  TS& operator*=(const S& other)
209  {
210  return static_cast<TS&>(*this) = (*this * other);
211  }
212  TS operator/(const S& other) const
213  {
214  return TS{static_cast<const TS&>(*this).get() / other};
215  }
216  TS& operator/=(const S& other)
217  {
218  return static_cast<TS&>(*this) = (*this / other);
219  }
220 };
221 
226 template <class TS>
228 {
229 public:
230  bool operator<(const TS& other) const
231  {
232  return static_cast<const TS&>(*this).get() < static_cast<const TS&>(other).get();
233  }
234  bool operator<=(const TS& other) const
235  {
236  return static_cast<const TS&>(*this).get() <= static_cast<const TS&>(other).get();
237  }
238  bool operator>(const TS& other) const
239  {
240  return static_cast<const TS&>(*this).get() > static_cast<const TS&>(other).get();
241  }
242  bool operator>=(const TS& other) const
243  {
244  return static_cast<const TS&>(*this).get() >= static_cast<const TS&>(other).get();
245  }
246 };
247 
253 #define DECL_TYPESAFE(T, Name) \
254  struct Name : public ::mio::TypeSafe<T, Name> { \
255  using TypeSafe<T, Name>::TypeSafe; \
256  }
257 
258 } // namespace mio
259 
260 #endif // MIO_UTILS_TYPE_SAFE_H
base class to add default operator +, +=, -, -= to a class derived from TypeSafe.
Definition: type_safe.h:175
TS & operator-=(const TS &other)
Definition: type_safe.h:189
TS & operator+=(const TS &other)
Definition: type_safe.h:181
TS operator+(const TS &other) const
Definition: type_safe.h:177
TS operator-(const TS &other) const
Definition: type_safe.h:185
base class to add operator <, <=, >, >= to a class derived from TypeSafe.
Definition: type_safe.h:228
bool operator>=(const TS &other) const
Definition: type_safe.h:242
bool operator<(const TS &other) const
Definition: type_safe.h:230
bool operator>(const TS &other) const
Definition: type_safe.h:238
bool operator<=(const TS &other) const
Definition: type_safe.h:234
base class to add operator ++, – (pre- and post-) to a class derived from TypeSafe.
Definition: type_safe.h:145
TS & operator--()
Definition: type_safe.h:157
TS operator++(int)
Definition: type_safe.h:151
TS operator--(int)
Definition: type_safe.h:161
TS & operator++()
Definition: type_safe.h:147
base class to add operator *, *=, /, /= with a scalar to a class derived from TypeSafe.
Definition: type_safe.h:202
TS & operator/=(const S &other)
Definition: type_safe.h:216
TS operator/(const S &other) const
Definition: type_safe.h:212
TS & operator*=(const S &other)
Definition: type_safe.h:208
TS operator*(const S &other) const
Definition: type_safe.h:204
Typesafe wrapper around any type to make function arguments, tuple elements, etc.
Definition: type_safe.h:59
TypeSafe(T t)
value constructor.
Definition: type_safe.h:71
static IOResult< Derived > deserialize(IOContext &io)
deserialize an object of this class.
Definition: type_safe.h:129
TypeSafe()=default
default constructor.
friend std::ostream & operator<<(std::ostream &os, const Derived &ts)
stream operators.
Definition: type_safe.h:109
void serialize(IOContext &io) const
serialize this.
Definition: type_safe.h:119
T ValueType
Definition: type_safe.h:61
friend bool operator!=(const Derived &a, const Derived &b)
Definition: type_safe.h:101
T m_t
Definition: type_safe.h:136
T get() const
Returns the underlying value.
Definition: type_safe.h:89
friend bool operator==(const Derived &a, const Derived &b)
equality operators.
Definition: type_safe.h:97
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
IOResult< T > deserialize(IOContext &io, Tag< T > tag)
Restores an object from the data stored in an IO context.
Definition: io.h:861
void serialize(IOContext &io, const T &t)
Save data that describes an object in a format determined by the given context.
Definition: io.h:837
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:408
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:360
constexpr std::tuple_element< I, std::tuple< Index< CategoryTags >... > >::type & get(Index< CategoryTags... > &i) noexcept
Retrieves the Index (by reference) at the Ith position of a MultiIndex.
Definition: index.h:304
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:354