Zrythm v2.0.0-alpha.1
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
uuid_identifiable_object.h
1// SPDX-FileCopyrightText: © 2024-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "utils/icloneable.h"
7#include "utils/uuid_identifiable.h"
8
9#include <QUuid>
10
11#include <boost/describe/class.hpp>
12#include <fmt/format.h>
13#include <nlohmann/json_fwd.hpp>
14#include <type_safe/strong_typedef.hpp>
15
16namespace zrythm::utils
17{
40template <typename Derived>
41class UuidIdentifiableObject : public UuidIdentifiableBase
42{
43public:
45 using uuid_base_type = Derived;
46
47 struct Uuid final
48 : type_safe::strong_typedef<Uuid, QUuid>,
49 type_safe::strong_typedef_op::equality_comparison<Uuid>,
50 type_safe::strong_typedef_op::relational_comparison<Uuid>
51 {
52 using UuidTag = void; // used by the fmt formatter below
53 using type_safe::strong_typedef<Uuid, QUuid>::strong_typedef;
54
55 explicit Uuid () = default;
56
57 static_assert (utils::StrongTypedef<Uuid>);
58 // static_assert (type_safe::is_strong_typedef<Uuid>::value);
59 // static_assert (std::is_same_v<type_safe::underlying_type<Uuid>, QUuid>);
60
64 bool is_null () const { return type_safe::get (*this).isNull (); }
65
66 void set_null () { type_safe::get (*this) = QUuid (); }
67
68 // Used by boost hash
69 friend std::size_t hash_value (const Uuid &p) { return p.hash (); }
70
71 std::size_t hash () const { return qHash (type_safe::get (*this)); }
72 };
73 static_assert (std::regular<Uuid>);
74 static_assert (sizeof (Uuid) == sizeof (QUuid));
75
76 explicit UuidIdentifiableObject (QObject * parent = nullptr)
77 : UuidIdentifiableBase (QUuid::createUuid (), parent)
78 {
79 }
80 UuidIdentifiableObject (const Uuid &id, QObject * parent = nullptr)
81 : UuidIdentifiableBase (type_safe::get (id), parent)
82 {
83 }
84
85 Q_DISABLE_COPY_MOVE (UuidIdentifiableObject)
86 ~UuidIdentifiableObject () override = default;
87
88 auto get_uuid () const { return Uuid (raw_uuid ()); }
89
90 friend void init_from (
91 UuidIdentifiableObject &obj,
92 const UuidIdentifiableObject &other,
93 utils::ObjectCloneType clone_type)
94 {
96 {
97 obj.set_raw_uuid (QUuid::createUuid ());
98 }
99 else
100 {
101 obj.set_raw_uuid (other.raw_uuid ());
102 }
103 }
104
105 friend void to_json (nlohmann::json &j, const UuidIdentifiableObject &obj)
106 {
107 to_json (j, static_cast<const UuidIdentifiableBase &> (obj));
108 }
109 friend void from_json (const nlohmann::json &j, UuidIdentifiableObject &obj)
110 {
111 from_json (j, static_cast<UuidIdentifiableBase &> (obj));
112 }
113
114 friend bool operator== (
115 const UuidIdentifiableObject &lhs,
116 const UuidIdentifiableObject &rhs)
117 {
118 return static_cast<const UuidIdentifiableBase &> (lhs)
119 == static_cast<const UuidIdentifiableBase &> (rhs);
120 }
121
122 BOOST_DESCRIBE_CLASS (UuidIdentifiableObject, (UuidIdentifiableBase), (), (), ())
123};
124
139template <typename T>
140concept UuidIdentifiable = requires {
141 typename T::uuid_base_type;
142 typename T::Uuid;
143};
144
145// specialization for std::hash and boost::hash
146#define DEFINE_UUID_HASH_SPECIALIZATION(UuidType) \
147 namespace std \
148 { \
149 template <> struct hash<UuidType> \
150 { \
151 size_t operator() (const UuidType &uuid) const { return uuid.hash (); } \
152 }; \
153 }
154
155} // namespace zrythm::utils
156
157// Concept to detect UuidIdentifiableObject::Uuid types
158template <typename T>
159concept UuidType = requires (T t) {
160 typename T::UuidTag;
161 { type_safe::get (t) } -> std::convertible_to<QUuid>;
162};
163
164// Formatter for any UUID type from UuidIdentifiableObject
165template <UuidType T>
166struct fmt::formatter<T> : fmt::formatter<std::string_view>
167{
168 template <typename FormatContext>
169 auto format (const T &uuid, FormatContext &ctx) const
170 {
171 return fmt::formatter<std::string_view>{}.format (
172 type_safe::get (uuid).toString (QUuid::WithoutBraces).toUtf8 (), ctx);
173 }
174};
Concept: T has a UUID identity from a UuidIdentifiableObject hierarchy.
String utilities.
@ NewIdentity
Creates a separately identified object.
Definition icloneable.h:30
bool is_null() const
Checks if the UUID is null.