Qx v0.7
Qt Extensions Library
Loading...
Searching...
No Matches
qx-abstracterror.h
Go to the documentation of this file.
1#ifndef QX_ABSTRACTERROR_H
2#define QX_ABSTRACTERROR_H
3
4// Shared Lib Support
5#include "qx/core/qx_core_export.h"
6
7// Standard Library Includes
8#include <array>
9#include <concepts>
10
11// Qt Includes
12#include <QString>
13#include <QHash>
14#include <QSet>
15
16// Intra-component Includes
17#include "qx/core/qx-global.h"
18
19// Extra-component Includes
20#include "qx/utility/qx-stringliteral.h"
21
22using namespace Qt::Literals::StringLiterals;
23
24namespace Qx
25{
26
27class QX_CORE_EXPORT IError
28{
29 friend class Error;
30//-Class Variables----------------------------------------------------------------------------------------------------------
31private:
32 static inline const QString T_CODE_DUPE = u"Error type code %1 is already claimed by %2!"_s;
33 static inline const QString T_NAME_DUPE = u"Error type name %1 is already claimed!"_s;
34 static inline const QString T_CODE_RESERVED = u"Error type code %1 is reserved!"_s;
35 static inline constinit QHash<quint16, const QString*> codeRegistry;
36 static constexpr std::array<QStringView, 10> RESERVED_NAMES{
37 u"Qx::InternalError",
38 u"Qx::GenericError",
39 u"Qx::IoOpReport",
40 u"Qx::SystemError",
41 u"Qx::DownloadManagerReport",
42 u"Qx::DownloadOpReport",
43 u"Qx::JsonError",
44 u"QJsonParseError",
45 u"Qx::SqlError",
46 u"Qx::SqlSchemaReport",
47 };
48 // TODO: If this becomes sufficiently large, move to a constexpr set (hopefully available in std by that time)
49
50//-Class Functions----------------------------------------------------------------------------------------------------------
51private:
52 static QSet<QString>& nameRegistry(); // RAII
53
54protected: // Implementation detail
56 static bool registerType(quint16 tc, const QString& tn);
58
59//-Constructor----------------------------------------------------------------------------------------------------------
60protected:
61 IError() = default;
62
63//-Instance Functions------------------------------------------------------------------------------------------------------
64protected:
65 virtual quint32 deriveValue() const;
66 virtual Severity deriveSeverity() const;
67 virtual QString deriveCaption() const;
68 virtual QString derivePrimary() const;
69 virtual QString deriveSecondary() const;
70 virtual QString deriveDetails() const;
71
72 /* TODO: Consider changing deriveSeverity to be a fixed function that always returns a protected member variable
73 * that descendants modify instead. Its less clean, but would allow for base class withSeverity() and setSeverity()
74 * methods such that the severity of any error can always be manipulated (which is somewhat common to all potential
75 * error type). Of course this would also require use of CRTP to allow for the functions to return the correct type.
76 * This could also be done for isValid() where an underlying value is always checked, though some error types
77 * might not quite operate that way (e.g. IoOpReport).
78 */
79
80//-Operators-------------------------------------------------------------------------------------------------------
81public:
82 bool operator==(const IError& other) const = default;
83 bool operator!=(const IError& other) const = default;
84};
85
86template<CStringLiteral EName, quint16 ECode>
87class AbstractError : protected IError
88{
89friend class Error;
90//-Class Variables----------------------------------------------------------------------------------------------------------
91public:
92 static constexpr quint16 TYPE_CODE = ECode;
93 static constexpr QLatin1StringView TYPE_NAME{EName};
94
95private:
96 static const bool REGISTER;
97
98//-Constructor-------------------------------------------------------------------------------------------------------------
99protected:
100 AbstractError() = default;
101
102//-Class Functions----------------------------------------------------------------------------------------------------------
103private:
104 using IError::registerType;
105
106//-Operators-------------------------------------------------------------------------------------------------------
107public:
108 bool operator==(const AbstractError& other) const = default;
109 bool operator!=(const AbstractError& other) const = default;
110 explicit operator bool() const { return deriveValue() > 0; };
111};
112
113/* TODO: Get string of the type automatically when it becomes
114 * more feasible. std::source_location is a good candidate once support
115 * for it is more widespread, though since it mainly focuses of function
116 * names and not classes, it alone might not be enough
117 */
118
119//-Namespace Concepts-------------------------------------------------------------------------------------------------------
120
121template<class E>
122concept error_type = requires(E type) {
123 // IIFE that ensures E is a specialization of AbstractError
124 []<CStringLiteral Y, quint16 Z>(AbstractError<Y, Z>&){}(type);
125};
126
127/* Define error type registrar variable. This must be done out of line to ensure that only
128 * one instance of the variable exists per-error-type across an entire program. If the variable
129 * is defined inline, multiple versions of it can exist in parallel when linking via shared-libraries,
130 * if those libraries are used by multiple targets in the same project. This would cause an error type
131 * to call registerType() multiple times.
132 */
134template<CStringLiteral EName, quint16 ECode>
135const bool AbstractError<EName, ECode>::REGISTER = registerType(TYPE_CODE, TYPE_NAME);
137
138template<class A>
141 !std::move_constructible<A> &&
142 !std::copy_constructible<A>;
143
144template<class Able, class Ater>
145concept error_adaptation = error_adapter<Ater> && std::constructible_from<Ater, const Able&>;
146
147}
148
149//-Macros----------------------------------------------------------------------------------------------------------
150#define QX_ERROR_TYPE(Type, Name, Code) \
151 Type final : public Qx::AbstractError<Name, Code>
152
153#endif // QX_ABSTRACTERROR_H
The AbstractError template class completes the Error interface and acts as the base class from which ...
Definition qx-abstracterror.h:88
static constexpr QLatin1StringView TYPE_NAME
Definition qx-abstracterror.h:93
bool operator==(const AbstractError &other) const =default
static constexpr quint16 TYPE_CODE
Definition qx-abstracterror.h:92
bool operator!=(const AbstractError &other) const =default
bool operator!=(const IError &other) const =default
virtual QString deriveCaption() const
Definition qx-abstracterror.cpp:102
virtual quint32 deriveValue() const
Definition qx-abstracterror.cpp:78
IError()=default
virtual QString deriveSecondary() const
Definition qx-abstracterror.cpp:124
bool operator==(const IError &other) const =default
virtual QString derivePrimary() const
Definition qx-abstracterror.cpp:113
virtual Severity deriveSeverity() const
Definition qx-abstracterror.cpp:87
virtual QString deriveDetails() const
Definition qx-abstracterror.cpp:135
Specifies that two types form a Qx error adaptation.
Definition qx-abstracterror.h:145
Specifies that a type is a Qx error adapter.
Definition qx-abstracterror.h:139
Specifies that a type is a Qx error type.
Definition qx-abstracterror.h:122
The Qx namespace is the main namespace through which all non-global functionality of the Qx library i...
Definition qx-abstracterror.cpp:13
Severity
Definition qx-global.h:11
CStringLiteral acts like a typedef/alias for a StringLiteral that uses char as its storage type.
Definition qx-stringliteral.h:194