-
Notifications
You must be signed in to change notification settings - Fork 0
/
qtwitch_global.h
195 lines (173 loc) · 5.14 KB
/
qtwitch_global.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
* Copyright © 2019 Andrew Penkrat <contact.aldrog@gmail.com>
*
* This file is part of QTwitch.
*
* QTwitch is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QTwitch is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with QTwitch. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef QTWITCH_GLOBAL_H
#define QTWITCH_GLOBAL_H
#include <QtCore/qglobal.h>
#include <QMetaType>
#include <memory>
#if defined(QTWITCH_LIBRARY)
# define QTWITCHSHARED_EXPORT Q_DECL_EXPORT
#else
# define QTWITCHSHARED_EXPORT Q_DECL_IMPORT
#endif
Q_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)
Q_DECLARE_SMART_POINTER_METATYPE(std::unique_ptr)
// Any value between 201104 and 201402 is considered c++14 for compatibility with older compilers
// For c++11 or earlier define make_unique
#if __cplusplus <= 201103L
namespace std {
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
#endif
#if __cplusplus > 201402L // c++17
#include <optional>
#include <string_view>
#elif __cplusplus <= 201402L // c++14 or earlier
// Make use of std::experimental::optional if it's available
#if __has_include(<experimental/optional>)
#include <experimental/optional>
namespace std {
template<typename T>
class optional : public std::experimental::optional<T> {
public:
using std::experimental::optional<T>::optional;
void reset() {
*this = std::experimental::nullopt;
}
};
}
#else
namespace std {
// Partial inefficient implementation of std::optional
template<typename T>
class optional
{
T val;
bool hasVal;
public:
optional() //-V730
: hasVal(false)
{}
optional(T val_)
: val(std::move(val_)), hasVal(true)
{}
optional(const optional &) = default;
optional(optional &&) noexcept = default;
optional &operator= (const optional &) = default;
optional &operator= (optional &&) noexcept = default;
const T& operator* () const {
return val;
}
T& operator* () {
return val;
}
operator bool() const {
return hasVal;
}
void reset() {
hasVal = false;
}
};
}
#endif
namespace std {
// The same goes about string_view
class string_view
{
const char *viewStart;
size_t viewSize;
public:
constexpr string_view() noexcept
: viewStart(nullptr), viewSize(0)
{}
constexpr string_view(const string_view&) noexcept = default;
constexpr string_view(const char *start_, size_t size_)
: viewStart(start_), viewSize(size_)
{}
template<size_t N>
constexpr string_view(const char (&s)[N])
: viewStart(&s[0]), viewSize(N-1)
{}
size_t size() const { return viewSize; }
const char *data() const { return viewStart; }
bool empty() const { return viewSize == 0; }
string_view
substr(size_t __pos, size_t __n = -1) const
{
const size_t __rlen = std::min(__n, viewSize - __pos);
return string_view{viewStart + __pos, __rlen};
}
int
compare(string_view __str) const noexcept
{
const size_t __rlen = std::min(this->viewSize, __str.viewSize);
int __ret = char_traits<char>::compare(this->viewStart, __str.viewStart, __rlen);
if (__ret == 0) {
const ptrdiff_t __diff = this->viewSize - __str.viewSize;
if (__diff > std::numeric_limits<int>::max())
return std::numeric_limits<int>::max();
if (__diff < std::numeric_limits<int>::min())
return std::numeric_limits<int>::min();
__ret = static_cast<int>(__diff);
}
return __ret;
}
int
compare(size_t __pos1, size_t __n1, string_view __str) const
{ return this->substr(__pos1, __n1).compare(__str); }
int
compare(size_t __pos1, size_t __n1,
string_view __str, size_t __pos2, size_t __n2) const
{
return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
}
int
compare(size_t __pos1, size_t __n1,
const char* __str, size_t __n2) const noexcept(false)
{
return this->substr(__pos1, __n1)
.compare(string_view(__str, __n2));
}
size_t
find(char __c, size_t __pos = 0) const noexcept
{
return std::find(viewStart + __pos, viewStart + viewSize, __c) - viewStart;
}
void
remove_prefix(size_t __n) noexcept
{
__glibcxx_assert(this->_M_len >= __n);
viewStart += __n;
viewSize -= __n;
}
void
remove_suffix(size_t __n) noexcept
{ viewSize -= __n; }
};
inline bool
operator==(string_view __x,
string_view __y) noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
}
#endif
#endif // QTWITCH_GLOBAL_H