EHM DAL 0.2.3
Data abstraction layer for Eastside Hockey Manager
Loading...
Searching...
No Matches
data_type.h
1#pragma once
2
3// Qt headers
4#include <QDataStream>
5#include <QLocale>
6#include <QVariant>
7#include <type_traits>
8
9namespace ehm_dal::data_types {
10template<class T>
11concept Number = std::is_integral<T>::value || std::is_floating_point<T>::value;
12
16template<Number T>
18{
19public:
20 DataType(const T value = 0);
21 // NOTE making DataType virtual in any manner results in vtable corruption
22 //virtual ~DataType() = default;
23
24 // Get data
29 QVariant data(const qint32 role = Qt::DisplayRole) const;
33 inline T value() const { return value_; }
34
35 // Get data - decimals
36 // TODO <float> results in inaccurate decimal values (see e.g. Continent::RegionalStrength)
41 QVariant accurateDecimal(const qint32 role = Qt::DisplayRole) const;
46 QVariant roundedDecimal(const qint32 role = Qt::DisplayRole) const;
50 double toDouble() const;
54 float toFloat() const;
55
56 // Operator overloading: Comparators
57 inline auto operator<=>(const DataType &rhs) const { return value() <=> rhs.value(); }
58 inline bool operator==(const DataType &rhs) const { return value() == rhs.value(); }
59 inline auto operator<=>(const qint32 &rhs) const { return value() <=> rhs; }
60 inline bool operator==(const qint32 &rhs) const { return value() == rhs; }
61
62 // Set data
63 Q_DECL_DEPRECATED void set(const QVariant &value, const qint32 role = Qt::EditRole);
64 // BUG making setData() a virtual function appears to corrupt the vtable
70 void setData(const QVariant &value, const qint32 role = Qt::EditRole);
75 inline void setValue(const T value) { value_ = value; }
76
77private:
78 T value_;
79
80 // File i/o
81 friend QDataStream &operator>>(QDataStream &in, DataType<T> &data)
82 {
83 in.readRawData(reinterpret_cast<char *>(&data.value_), sizeof(T));
84 return in;
85 }
86 friend QDataStream &operator<<(QDataStream &out, const DataType<T> &data)
87 {
88 out.writeRawData(reinterpret_cast<const char *>(&data.value_), sizeof(T));
89 return out;
90 }
91};
92
93/* ================== */
94/* Data Type */
95/* ================== */
96
97template<Number T>
98DataType<T>::DataType(const T value)
99 : value_(value)
100{}
101
102/* ================= */
103/* Get Data */
104/* ================= */
105
106template<Number T>
107QVariant DataType<T>::data(const qint32 role) const
108{
109 switch (role) {
110 case Qt::DisplayRole:
111 case Qt::EditRole:
112 return value_;
113 default:
114 return QVariant();
115 }
116}
117
118/* ============================ */
119/* Get Data - Decimals */
120/* ============================ */
121
122template<Number T>
123QVariant DataType<T>::accurateDecimal(const qint32 role) const
124{
125 if (role == Qt::DisplayRole || role == Qt::EditRole)
126 return QLocale().toString(value_);
127
128 return QVariant();
129}
130
131template<Number T>
132QVariant DataType<T>::roundedDecimal(const qint32 role) const
133{
134 if (role != Qt::DisplayRole && role != Qt::EditRole)
135 return QVariant();
136
137 if constexpr (std::is_floating_point_v<T>)
138 return QLocale().toString(value_, 'g', 8);
139
140 return QString::number(0.0);
141}
142
143template<Number T>
145{
146 return static_cast<double>(value_);
147}
148
149template<Number T>
151{
152 return static_cast<float>(value_);
153}
154
155/* ================= */
156/* Set Data */
157/* ================= */
158
159// TODO deprecate this function in favour of setData()
160template<Number T>
161void DataType<T>::set(const QVariant &value, const qint32 role)
162{
163 setData(value, role);
164}
165
166template<Number T>
167void DataType<T>::setData(const QVariant &value, const qint32 role)
168{
169 if (role != Qt::EditRole)
170 return;
171
172 if constexpr (std::is_floating_point_v<T>)
173 setValue(static_cast<T>(value.toDouble()));
174 else if constexpr (std::is_unsigned_v<T>)
175 setValue(static_cast<T>(value.toUInt()));
176 else
177 setValue(static_cast<T>(value.toInt()));
178}
179
180} // namespace ehm_dal::data_types
The DataType class is a template class for all C++ integral and floating point data types.
Definition: data_type.h:18
double toDouble() const
Returns the value as a double.
Definition: data_type.h:144
QVariant accurateDecimal(const qint32 role=Qt::DisplayRole) const
Returns the decimal value to as many decimal places as possible.
Definition: data_type.h:123
float toFloat() const
Returns the value as a float.
Definition: data_type.h:150
QVariant roundedDecimal(const qint32 role=Qt::DisplayRole) const
Returns the decimal value rounded to 8 decimal places. This is useful when converting a double to a f...
Definition: data_type.h:132
QVariant data(const qint32 role=Qt::DisplayRole) const
Returns the data stored under the given role for the item.
Definition: data_type.h:107
T value() const
Returns the raw value which can otherwise be accessed via QVariant data(const qint32 role).
Definition: data_type.h:33
void setValue(const T value)
Sets the value to value
Definition: data_type.h:75
void setData(const QVariant &value, const qint32 role=Qt::EditRole)
Sets the role data for the item at to value.
Definition: data_type.h:167
Definition: data_type.h:11
namespace ehm_dal::data_types
Definition: attribute.h:6