MySQL 9.6.0
Source Code Documentation
tsid.h
Go to the documentation of this file.
1// Copyright (c) 2025, Oracle and/or its affiliates.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License, version 2.0,
5// as published by the Free Software Foundation.
6//
7// This program is designed to work with certain software (including
8// but not limited to OpenSSL) that is licensed under separate terms,
9// as designated in a particular file or component or in included license
10// documentation. The authors of MySQL hereby grant you an additional
11// permission to link the program and your derivative works with the
12// separately licensed software that they have either included with
13// the program or referenced in the documentation.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License, version 2.0, for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
24#ifndef MYSQL_GTIDS_TSID_H
25#define MYSQL_GTIDS_TSID_H
26
27/// @file
28/// Experimental API header
29
30#include <concepts> // derived_from
31#include <cstddef> // size_t
32#include <string_view> // hash
33#include "mysql/gtids/tag.h" // Tag
34#include "mysql/meta/not_decayed.h" // Not_decayed
35#include "mysql/strconv/strconv.h" // Is_string_target
36#include "mysql/utils/return_status.h" // Return_status
37#include "mysql/uuids/uuid.h" // Uuid
38
39/// @addtogroup GroupLibsMysqlGtids
40/// @{
41
42namespace mysql::gtids {
43
44namespace detail {
45/// Top of the hierarchy
46class Tsid_base {};
47} // namespace detail
48
49template <class Test>
50concept Is_tsid = std::derived_from<Test, detail::Tsid_base>;
51
52namespace detail {
53/// Common interface, parameterized by tag type
54template <class Self_tp, Is_tag Tag_tp>
55class Tsid_interface : public Tsid_base {
56 public:
57 using Tag_t = Tag_tp;
58
59 // "nolint": Problem not worth fixing, and workaround too intrusive.
60 // NOLINTBEGIN(bugprone-crtp-constructor-accessibility)
61 Tsid_interface() = default;
63 const Is_tag auto &tag)
64 : m_uuid(uuid), m_tag(tag) {}
66 m_tag.clear();
67 }
68 explicit Tsid_interface(const Is_tsid auto &other)
69 : Tsid_interface(other.uuid(), other.tag()) {}
70 // NOLINTEND(bugprone-crtp-constructor-accessibility)
71
72 [[nodiscard]] const mysql::uuids::Uuid &uuid() const { return m_uuid; }
73 [[nodiscard]] mysql::uuids::Uuid &uuid() { return m_uuid; }
74
75 [[nodiscard]] const auto &tag() const { return m_tag; }
76 [[nodiscard]] auto &tag() { return m_tag; }
77
78 [[nodiscard]] auto assign(const Is_tsid auto &other) {
79 uuid().assign(other.uuid());
80 return tag().assign(other.tag());
81 }
82
83 private:
86}; // class Tsid_interface
87
88} // namespace detail
89
90class Tsid : public detail::Tsid_interface<Tsid, Tag> {
92
93 public:
94 Tsid() = default;
95
96 template <class... Args_t>
97 requires mysql::meta::Not_decayed<Tsid, Args_t...>
98 explicit Tsid(Args_t &&...args) : Base_t(std::forward<Args_t>(args)...) {}
99};
100
101class Tsid_trivial : public detail::Tsid_interface<Tsid_trivial, Tag_trivial> {
103
104 public:
105 Tsid_trivial() = default;
106
107 template <class... Args_t>
108 requires mysql::meta::Not_decayed<Tsid_trivial, Args_t...>
109 explicit Tsid_trivial(Args_t &&...args)
110 : Base_t(std::forward<Args_t>(args)...) {}
111};
112
113bool operator==(const Is_tsid auto &tsid1, const Is_tsid auto &tsid2) {
114 return tsid1.uuid() == tsid2.uuid() && tsid1.tag() == tsid2.tag();
115}
116
117bool operator!=(const Is_tsid auto &tsid1, const Is_tsid auto &tsid2) {
118 return !(tsid1 == tsid2);
119}
120
121auto operator<=>(const Is_tsid auto &tsid1, const Is_tsid auto &tsid2) {
122 auto uuid_cmp = tsid1.uuid() <=> tsid2.uuid();
123 if (uuid_cmp != 0) return uuid_cmp;
124 return tsid1.tag() <=> tsid2.tag();
125}
126
127} // namespace mysql::gtids
128
129/// Define std::hash<Tsid>.
130///
131// The recommended way to do this is to use a syntax that places the namespace
132// as a name qualifier, like `struct std::hash<Gtid_t>`, rather than enclose
133// the entire struct in a namespace block.
134//
135// However, gcc 11.4.0 on ARM has a bug that makes it produce "error:
136// redefinition of 'struct std::hash<_Tp>'" when using that syntax. See
137// https://godbolt.org/z/xo1v8rf6n vs https://godbolt.org/z/GzvrMese1 .
138//
139// Todo: Switch to the recommended syntax once we drop support for compilers
140// having this bug.
141//
142// clang-tidy warns when not using the recommended syntax
143// NOLINTBEGIN(cert-dcl58-cpp)
144namespace std {
145template <mysql::gtids::Is_tsid Tsid_t>
146struct hash<Tsid_t> {
147 std::size_t operator()(const Tsid_t &tsid) const {
148 return std::hash(tsid.uuid()) ^ std::hash(tsid.tag());
149 }
150};
151} // namespace std
152// NOLINTEND(cert-dcl58-cpp)
153
154// addtogroup GroupLibsMysqlGtids
155/// @}
156
157#endif // ifndef MYSQL_GTIDS_TSID_H
Definition: tsid.h:101
Tsid_trivial(Args_t &&...args)
Definition: tsid.h:109
Definition: tsid.h:90
Tsid(Args_t &&...args)
Definition: tsid.h:98
Top of the hierarchy.
Definition: tsid.h:46
Common interface, parameterized by tag type.
Definition: tsid.h:55
mysql::uuids::Uuid & uuid()
Definition: tsid.h:73
Tsid_interface(const mysql::uuids::Uuid &uuid)
Definition: tsid.h:65
const auto & tag() const
Definition: tsid.h:75
mysql::uuids::Uuid m_uuid
Definition: tsid.h:84
auto & tag()
Definition: tsid.h:76
const mysql::uuids::Uuid & uuid() const
Definition: tsid.h:72
Tag_tp Tag_t
Definition: tsid.h:57
Tag_t m_tag
Definition: tsid.h:85
Tsid_interface(const mysql::uuids::Uuid &uuid, const Is_tag auto &tag)
Definition: tsid.h:62
auto assign(const Is_tsid auto &other)
Definition: tsid.h:78
Tsid_interface(const Is_tsid auto &other)
Definition: tsid.h:68
Holds data for a UUID.
Definition: uuid.h:49
void assign(const Uuid &other)
Copy other to this.
Definition: uuid.h:68
True if Test is one of the tag classes.
Definition: tag.h:192
Definition: tsid.h:50
false if Args is exactly one type, say A, and std::decay_t<A> equals Type.
Definition: not_decayed.h:84
Experimental API header.
Experimental API header.
Definition: fts0fts.cc:236
Definition: gtid.h:45
auto operator<=>(const Is_gtid auto &gtid1, const Is_gtid auto &gtid2)
Definition: gtid.h:332
bool operator!=(const Is_gtid auto &gtid1, const Is_gtid auto &gtid2)
Definition: gtid.h:328
bool operator==(const Is_gtid auto &gtid1, const Is_gtid auto &gtid2)
Definition: gtid.h:323
Define std::hash<Gtid>.
Definition: gtid.h:355
Experimental API header.
Experimental API header.
std::size_t operator()(const Tsid_t &tsid) const
Definition: tsid.h:147
Experimental API header.