LibrePCB Developers Documentation
ratio.h
Go to the documentation of this file.
1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIBREPCB_CORE_RATIO_H
21 #define LIBREPCB_CORE_RATIO_H
22 
23 /*******************************************************************************
24  * Includes
25  ******************************************************************************/
26 #include "../exceptions.h"
27 #include "../qtcompat.h"
28 
29 #include <type_safe/constrained_type.hpp>
30 
31 #include <QtCore>
32 
33 /*******************************************************************************
34  * Namespace / Forward Declarations
35  ******************************************************************************/
36 namespace librepcb {
37 
38 /*******************************************************************************
39  * Class Ratio
40  ******************************************************************************/
41 
45 class Ratio {
46  Q_DECLARE_TR_FUNCTIONS(Ratio)
47 
48 public:
49  // Constructors / Destructor
50 
54  constexpr Ratio() noexcept : Ratio(0) {}
55 
61  constexpr Ratio(const Ratio& ratio) noexcept : mPpm(ratio.mPpm) {}
62 
68  constexpr explicit Ratio(qint32 ppm) noexcept : mPpm(ppm) {}
69 
73  ~Ratio() = default;
74 
75  // Setters
76 
82  void setRatioPpm(qint32 ppm) noexcept { mPpm = ppm; }
83 
89  void setRatioPercent(int percent) noexcept { mPpm = percent * 1e4; }
90 
99  void setRatioPercent(qreal percent) noexcept { mPpm = percent * 1e4; }
100 
112  void setRatioNormalized(qreal normalized) noexcept {
113  mPpm = normalized * 1e6;
114  }
115 
126  void setRatioNormalized(const QString& normalized) {
127  mPpm = normalizedStringToPpm(normalized);
128  }
129 
130  // Conversions
131 
137  qint32 toPpm() const noexcept { return mPpm; }
138 
144  qreal toPercent() const noexcept { return (qreal)mPpm / 1e4; }
145 
151  qreal toNormalized() const noexcept { return (qreal)mPpm / 1e6; }
152 
160  QString toNormalizedString() const noexcept;
161 
162  // Static Methods
163 
171  static Ratio fromPercent(int percent) noexcept;
172 
180  static Ratio fromPercent(qreal percent) noexcept;
181 
189  static Ratio fromNormalized(qreal normalized) noexcept;
190 
208  static Ratio fromNormalized(const QString& normalized);
209 
210  // Operators
211  Ratio& operator=(const Ratio& rhs) {
212  mPpm = rhs.mPpm;
213  return *this;
214  }
215  Ratio& operator+=(const Ratio& rhs) {
216  mPpm += rhs.mPpm;
217  return *this;
218  }
219  Ratio& operator-=(const Ratio& rhs) {
220  mPpm -= rhs.mPpm;
221  return *this;
222  }
223  Ratio& operator*=(const Ratio& rhs) {
224  mPpm *= rhs.mPpm;
225  return *this;
226  }
227  Ratio& operator*=(qint32 rhs) {
228  mPpm *= rhs;
229  return *this;
230  }
231  Ratio& operator/=(const Ratio& rhs) {
232  mPpm /= rhs.mPpm;
233  return *this;
234  }
235  Ratio& operator/=(qint32 rhs) {
236  mPpm /= rhs;
237  return *this;
238  }
239  Ratio operator+(const Ratio& rhs) const { return Ratio(mPpm + rhs.mPpm); }
240  Ratio operator-() const { return Ratio(-mPpm); }
241  Ratio operator-(const Ratio& rhs) const { return Ratio(mPpm - rhs.mPpm); }
242  Ratio operator*(const Ratio& rhs) const { return Ratio(mPpm * rhs.mPpm); }
243  Ratio operator*(qint32 rhs) const { return Ratio(mPpm * rhs); }
244  Ratio operator/(const Ratio& rhs) const { return Ratio(mPpm / rhs.mPpm); }
245  Ratio operator/(qint32 rhs) const { return Ratio(mPpm / rhs); }
246  Ratio operator%(const Ratio& rhs) const { return Ratio(mPpm % rhs.mPpm); }
247  constexpr bool operator>(const Ratio& rhs) const { return mPpm > rhs.mPpm; }
248  constexpr bool operator>(qint32 rhs) const { return mPpm > rhs; }
249  constexpr bool operator<(const Ratio& rhs) const { return mPpm < rhs.mPpm; }
250  constexpr bool operator<(qint32 rhs) const { return mPpm < rhs; }
251  constexpr bool operator>=(const Ratio& rhs) const { return mPpm >= rhs.mPpm; }
252  constexpr bool operator>=(qint32 rhs) const { return mPpm >= rhs; }
253  constexpr bool operator<=(const Ratio& rhs) const { return mPpm <= rhs.mPpm; }
254  constexpr bool operator<=(qint32 rhs) const { return mPpm <= rhs; }
255  constexpr bool operator==(const Ratio& rhs) const { return mPpm == rhs.mPpm; }
256  constexpr bool operator==(qint32 rhs) const { return mPpm == rhs; }
257  constexpr bool operator!=(const Ratio& rhs) const { return mPpm != rhs.mPpm; }
258  constexpr bool operator!=(qint32 rhs) const { return mPpm != rhs; }
259  explicit operator bool() const { return mPpm != 0; }
260 
261 private:
262  // Private Static Functions
263 
277  static qint32 normalizedStringToPpm(const QString& normalized);
278 
279  // Private Member Variables
280  qint32 mPpm;
281 };
282 
283 /*******************************************************************************
284  * Non-Member Functions
285  ******************************************************************************/
286 
287 inline QDataStream& operator<<(QDataStream& stream, const Ratio& ratio) {
288  stream << ratio.toNormalizedString();
289  return stream;
290 }
291 
292 inline QDebug operator<<(QDebug stream, const Ratio& ratio) {
293  stream << QString("Ratio(%1%%°)").arg(ratio.toPercent());
294  return stream;
295 }
296 
297 inline QtCompat::Hash qHash(const Ratio& key,
298  QtCompat::Hash seed = 0) noexcept {
299  return ::qHash(key.toPpm(), seed);
300 }
301 
302 /*******************************************************************************
303  * Class UnsignedRatio
304  ******************************************************************************/
305 
307  template <typename Value, typename Predicate>
308  static constexpr auto verify(Value&& val, const Predicate& p) ->
309  typename std::decay<Value>::type {
310  return p(val) ? std::forward<Value>(val)
311  : (throw RuntimeError(__FILE__, __LINE__,
312  Ratio::tr("Value must be >= 0!")),
313  std::forward<Value>(val));
314  }
315 };
316 
318  constexpr bool operator()(const Ratio& r) const noexcept { return r >= 0; }
319 };
320 
328 using UnsignedRatio =
329  type_safe::constrained_type<Ratio, UnsignedRatioConstraint,
331 
332 inline QDataStream& operator<<(QDataStream& stream,
333  const UnsignedRatio& ratio) {
334  stream << ratio->toNormalizedString();
335  return stream;
336 }
337 
338 inline QDebug operator<<(QDebug stream, const UnsignedRatio& ratio) {
339  stream << QString("UnsignedRatio(%1%%)").arg(ratio->toPercent());
340  return stream;
341 }
342 
344  QtCompat::Hash seed = 0) noexcept {
345  return ::qHash(key->toPpm(), seed);
346 }
347 
348 /*******************************************************************************
349  * Class UnsignedLimitedRatio
350  ******************************************************************************/
351 
353  template <typename Value, typename Predicate>
354  static constexpr auto verify(Value&& val, const Predicate& p) ->
355  typename std::decay<Value>::type {
356  return p(val) ? std::forward<Value>(val)
357  : (throw RuntimeError(__FILE__, __LINE__,
358  Ratio::tr("Value must be 0..1!")),
359  std::forward<Value>(val));
360  }
361 };
362 
364  constexpr bool operator()(const Ratio& r) const noexcept {
365  return (r >= 0) && (r <= Ratio::fromPercent(100));
366  }
367 };
368 
376 using UnsignedLimitedRatio =
377  type_safe::constrained_type<Ratio, UnsignedLimitedRatioConstraint,
379 
380 inline QDataStream& operator<<(QDataStream& stream,
381  const UnsignedLimitedRatio& ratio) {
382  stream << ratio->toNormalizedString();
383  return stream;
384 }
385 
386 inline QDebug operator<<(QDebug stream, const UnsignedLimitedRatio& ratio) {
387  stream << QString("UnsignedLimitedRatio(%1%%)").arg(ratio->toPercent());
388  return stream;
389 }
390 
392  QtCompat::Hash seed = 0) noexcept {
393  return ::qHash(key->toPpm(), seed);
394 }
395 
396 /*******************************************************************************
397  * End of File
398  ******************************************************************************/
399 
400 } // namespace librepcb
401 
402 #endif
Ratio operator*(const Ratio &rhs) const
Definition: ratio.h:242
QtCompat::Hash qHash(const AttributeKey &key, QtCompat::Hash seed=0) noexcept
Definition: attributekey.h:119
~Ratio()=default
Destructor.
constexpr bool operator==(qint32 rhs) const
Definition: ratio.h:256
void setRatioNormalized(qreal normalized) noexcept
Set the ratio as a normalized number.
Definition: ratio.h:112
QDataStream & operator<<(QDataStream &stream, const AttributeKey &obj)
Definition: attributekey.h:109
Ratio operator%(const Ratio &rhs) const
Definition: ratio.h:246
Ratio operator/(const Ratio &rhs) const
Definition: ratio.h:244
constexpr bool operator==(const Ratio &rhs) const
Definition: ratio.h:255
constexpr bool operator!=(const Ratio &rhs) const
Definition: ratio.h:257
Ratio & operator*=(const Ratio &rhs)
Definition: ratio.h:223
static Ratio fromNormalized(qreal normalized) noexcept
Get a Ratio object with a specific ratio.
Definition: ratio.cpp:57
void setRatioPercent(qreal percent) noexcept
Set the ratio in percent.
Definition: ratio.h:99
Definition: occmodel.cpp:77
static constexpr auto verify(Value &&val, const Predicate &p) -> typename std::decay< Value >::type
Definition: ratio.h:308
qreal toPercent() const noexcept
Get the ratio in percent.
Definition: ratio.h:144
constexpr bool operator>=(qint32 rhs) const
Definition: ratio.h:252
constexpr bool operator>(const Ratio &rhs) const
Definition: ratio.h:247
QtCompat::Hash qHash(const UnsignedLimitedRatio &key, QtCompat::Hash seed=0) noexcept
Definition: ratio.h:391
Ratio operator-(const Ratio &rhs) const
Definition: ratio.h:241
constexpr bool operator<=(qint32 rhs) const
Definition: ratio.h:254
Ratio & operator=(const Ratio &rhs)
Definition: ratio.h:211
constexpr bool operator>=(const Ratio &rhs) const
Definition: ratio.h:251
type_safe::constrained_type< Ratio, UnsignedRatioConstraint, UnsignedRatioVerifier > UnsignedRatio
Definition: ratio.h:330
qint32 toPpm() const noexcept
Get the ratio in PPM.
Definition: ratio.h:137
constexpr bool operator()(const Ratio &r) const noexcept
Definition: ratio.h:364
Ratio operator*(qint32 rhs) const
Definition: ratio.h:243
Ratio & operator/=(qint32 rhs)
Definition: ratio.h:235
Ratio & operator-=(const Ratio &rhs)
Definition: ratio.h:219
Ratio operator/(qint32 rhs) const
Definition: ratio.h:245
Ratio operator-() const
Definition: ratio.h:240
static qint32 normalizedStringToPpm(const QString &normalized)
Convert a normalized ratio from a QString to an integer (in PPM)
Definition: ratio.cpp:71
Definition: ratio.h:317
constexpr Ratio(const Ratio &ratio) noexcept
Copy Constructor.
Definition: ratio.h:61
The RuntimeError class.
Definition: exceptions.h:216
Ratio operator+(const Ratio &rhs) const
Definition: ratio.h:239
constexpr Ratio(qint32 ppm) noexcept
Constructor with a ratio in PPM.
Definition: ratio.h:68
QString toNormalizedString() const noexcept
Get the ratio as a normalized QString.
Definition: ratio.cpp:39
constexpr Ratio() noexcept
Default Constructor.
Definition: ratio.h:54
static Ratio fromPercent(int percent) noexcept
Get a Ratio object with a specific ratio.
Definition: ratio.cpp:45
constexpr bool operator()(const Ratio &r) const noexcept
Definition: ratio.h:318
uint Hash
Return type of Qt&#39;s qHash() function.
Definition: qtcompat.h:58
qreal toNormalized() const noexcept
Get the ratio as a normalized number.
Definition: ratio.h:151
void setRatioPercent(int percent) noexcept
Set the ratio in percent.
Definition: ratio.h:89
type_safe::constrained_type< Ratio, UnsignedLimitedRatioConstraint, UnsignedLimitedRatioVerifier > UnsignedLimitedRatio
Definition: ratio.h:378
The Ratio class is used to represent a ratio number (e.g. 13.37%)
Definition: ratio.h:45
static constexpr auto verify(Value &&val, const Predicate &p) -> typename std::decay< Value >::type
Definition: ratio.h:354
Definition: ratio.h:306
constexpr bool operator<=(const Ratio &rhs) const
Definition: ratio.h:253
constexpr bool operator<(const Ratio &rhs) const
Definition: ratio.h:249
constexpr bool operator<(qint32 rhs) const
Definition: ratio.h:250
qint32 mPpm
the ratio in PPM
Definition: ratio.h:280
Ratio & operator*=(qint32 rhs)
Definition: ratio.h:227
Ratio & operator+=(const Ratio &rhs)
Definition: ratio.h:215
void setRatioPpm(qint32 ppm) noexcept
Set the ratio in PPM.
Definition: ratio.h:82
void setRatioNormalized(const QString &normalized)
Set the ratio as a normalized number, represented in a QString.
Definition: ratio.h:126
constexpr bool operator>(qint32 rhs) const
Definition: ratio.h:248
constexpr bool operator!=(qint32 rhs) const
Definition: ratio.h:258
Ratio & operator/=(const Ratio &rhs)
Definition: ratio.h:231