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 
40 template <class T, class Derived>
41 class TypeSafe
42 {
43 public:
44  using ValueType = T;
45 
49  TypeSafe() = default;
50 
54  explicit TypeSafe(T t)
55  : m_t(t)
56  {
57  }
58 
62  explicit operator T() const
63  {
64  return m_t;
65  }
66  T get() const
67  {
68  return m_t;
69  }
70 
74  friend bool operator==(const Derived& a, const Derived& b)
75  {
76  return a.m_t == b.m_t;
77  }
78  friend bool operator!=(const Derived& a, const Derived& b)
79  {
80  return !(a == b);
81  }
82 
86  friend std::ostream& operator<<(std::ostream& os, const Derived& ts)
87  {
88  return (os << ts.m_t);
89  }
90 
95  template <class IOContext>
96  void serialize(IOContext& io) const
97  {
98  mio::serialize(io, T(*this));
99  }
100 
105  template <class IOContext>
106  static IOResult<Derived> deserialize(IOContext& io)
107  {
108  BOOST_OUTCOME_TRY(auto&& t, mio::deserialize(io, Tag<T>{}));
109  return success(Derived(t));
110  }
111 
112 private:
113  T m_t;
114 };
115 
120 template <class TS>
122 {
123 public:
125  {
126  return static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() + 1};
127  }
128  TS operator++(int)
129  {
130  auto tmp = static_cast<TS&>(*this);
131  static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() + 1};
132  return tmp;
133  }
135  {
136  return static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() - 1};
137  }
138  TS operator--(int)
139  {
140  auto tmp = static_cast<TS&>(*this);
141  static_cast<TS&>(*this) = TS{static_cast<const TS&>(*this).get() - 1};
142  return tmp;
143  }
144 };
145 
150 template <class TS>
152 {
153 public:
154  TS operator+(const TS& other) const
155  {
156  return TS{static_cast<const TS&>(*this).get() + other.get()};
157  }
158  TS& operator+=(const TS& other)
159  {
160  return static_cast<TS&>(*this) = (*this + other);
161  }
162  TS operator-(const TS& other) const
163  {
164  return TS{static_cast<const TS&>(*this).get() - other.get()};
165  }
166  TS& operator-=(const TS& other)
167  {
168  return static_cast<TS&>(*this) = (*this - other);
169  }
170 };
171 
177 template <class TS, class S> //S can't default to TS::ValueType because TS is imcomplete
179 {
180 public:
181  TS operator*(const S& other) const
182  {
183  return TS{static_cast<const TS&>(*this).get() * other};
184  }
185  TS& operator*=(const S& other)
186  {
187  return static_cast<TS&>(*this) = (*this * other);
188  }
189  TS operator/(const S& other) const
190  {
191  return TS{static_cast<const TS&>(*this).get() / other};
192  }
193  TS& operator/=(const S& other)
194  {
195  return static_cast<TS&>(*this) = (*this / other);
196  }
197 };
198 
203 template <class TS>
205 {
206 public:
207  bool operator<(const TS& other) const
208  {
209  return static_cast<const TS&>(*this).get() < static_cast<const TS&>(other).get();
210  }
211  bool operator<=(const TS& other) const
212  {
213  return static_cast<const TS&>(*this).get() <= static_cast<const TS&>(other).get();
214  }
215  bool operator>(const TS& other) const
216  {
217  return static_cast<const TS&>(*this).get() > static_cast<const TS&>(other).get();
218  }
219  bool operator>=(const TS& other) const
220  {
221  return static_cast<const TS&>(*this).get() >= static_cast<const TS&>(other).get();
222  }
223 };
224 
228 #define DECL_TYPESAFE(T, Name) \
229  struct Name : public ::mio::TypeSafe<T, Name> { \
230  using TypeSafe<T, Name>::TypeSafe; \
231  }
232 
233 } // namespace mio
234 
235 #endif // MIO_UTILS_TYPE_SAFE_H
base class to add default operator +, +=, -, -= to a class derived from TypeSafe.
Definition: type_safe.h:152
TS & operator-=(const TS &other)
Definition: type_safe.h:166
TS & operator+=(const TS &other)
Definition: type_safe.h:158
TS operator+(const TS &other) const
Definition: type_safe.h:154
TS operator-(const TS &other) const
Definition: type_safe.h:162
base class to add operator <, <=, >, >= to a class derived from TypeSafe.
Definition: type_safe.h:205
bool operator>=(const TS &other) const
Definition: type_safe.h:219
bool operator<(const TS &other) const
Definition: type_safe.h:207
bool operator>(const TS &other) const
Definition: type_safe.h:215
bool operator<=(const TS &other) const
Definition: type_safe.h:211
base class to add operator ++, – (pre- and post-) to a class derived from TypeSafe.
Definition: type_safe.h:122
TS & operator--()
Definition: type_safe.h:134
TS operator++(int)
Definition: type_safe.h:128
TS operator--(int)
Definition: type_safe.h:138
TS & operator++()
Definition: type_safe.h:124
base class to add operator *, *=, /, /= with a scalar to a class derived from TypeSafe.
Definition: type_safe.h:179
TS & operator/=(const S &other)
Definition: type_safe.h:193
TS operator/(const S &other) const
Definition: type_safe.h:189
TS & operator*=(const S &other)
Definition: type_safe.h:185
TS operator*(const S &other) const
Definition: type_safe.h:181
typesafe wrapper around any type to make function arguments, tuple elements, etc.
Definition: type_safe.h:42
TypeSafe(T t)
value constructor.
Definition: type_safe.h:54
static IOResult< Derived > deserialize(IOContext &io)
deserialize an object of this class.
Definition: type_safe.h:106
TypeSafe()=default
default constructor.
friend std::ostream & operator<<(std::ostream &os, const Derived &ts)
stream operators.
Definition: type_safe.h:86
void serialize(IOContext &io) const
serialize this.
Definition: type_safe.h:96
T ValueType
Definition: type_safe.h:44
friend bool operator!=(const Derived &a, const Derived &b)
Definition: type_safe.h:78
T m_t
Definition: type_safe.h:113
T get() const
Definition: type_safe.h:66
friend bool operator==(const Derived &a, const Derived &b)
equality operators.
Definition: type_safe.h:74
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:860
void serialize(IOContext &io, const T &t)
Save data that describes an object in a format determined by the given context.
Definition: io.h:836
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
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:294
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:353