Krita Source Code Documentation
Loading...
Searching...
No Matches
propagate_const.h
Go to the documentation of this file.
1/*
2
3Copyright (c) 2014-2018 Jonathan B. Coe
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of
6this software and associated documentation files (the "Software"), to deal in
7the Software without restriction, including without limitation the rights to
8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9the Software, and to permit persons to whom the Software is furnished to do so,
10subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22*/
23
24#ifndef JBCOE_PROPAGATE_CONST_INCLUDED
25#define JBCOE_PROPAGATE_CONST_INCLUDED
26
27#include <functional>
28#include <memory>
29#include <type_traits>
30#include <utility>
31
32#ifndef _MSC_VER
33#define PROPAGATE_CONST_CONSTEXPR constexpr
34#else
35#if _MSC_VER <= 1900 // MSVS 2015 and earlier
36#define PROPAGATE_CONST_CONSTEXPR
37#define PROPAGATE_CONST_HAS_NO_EXPRESSION_SFINAE
38#else
39#define PROPAGATE_CONST_CONSTEXPR constexpr
40#endif
41#endif
42
43namespace std {
44namespace experimental {
45inline namespace fundamentals_v2 {
46template <class T>
48 public:
49 using element_type = typename std::pointer_traits<T>::element_type;
50
51 private:
52 template <class U>
54 return u;
55 }
56
57 template <class U>
59 return get_pointer(u.get());
60 }
61
62 template <class U>
63 static const element_type* get_pointer(const U* u) {
64 return u;
65 }
66
67 template <class U>
68 static const element_type* get_pointer(const U& u) {
69 return get_pointer(u.get());
70 }
71
72 template <class U>
73 struct is_propagate_const : false_type {};
74
75 template <class U>
76 struct is_propagate_const<propagate_const<U>> : true_type {};
77
78 public:
79 // [propagate_const.ctor], constructors
81
83
85
86#ifdef PROPAGATE_CONST_HAS_NO_EXPRESSION_SFINAE
87 //
88 // Make converting constructors explicit as we cannot use SFINAE to check.
89 //
90 template <class U, class = enable_if_t<is_constructible<T, U&&>::value>>
92 : t_(std::move(pu.t_))
93 {
94 }
95
96 template <class U,
97 class = enable_if_t<is_constructible<T, U&&>::value &&
98 !is_propagate_const<decay_t<U>>::value>>
100 : t_(std::forward<U>(u))
101 {
102 }
103#else
104 //
105 // Use SFINAE to check if converting constructor should be explicit.
106 //
107 template <class U, enable_if_t<!is_convertible<U&&, T>::value &&
108 is_constructible<T, U&&>::value,
109 bool> = true>
112
113 template <class U, enable_if_t<is_convertible<U&&, T>::value &&
114 is_constructible<T, U&&>::value,
115 bool> = false>
117
118 template <class U, enable_if_t<!is_convertible<U&&, T>::value &&
119 is_constructible<T, U&&>::value &&
120 !is_propagate_const<decay_t<U>>::value,
121 bool> = true>
122 explicit PROPAGATE_CONST_CONSTEXPR propagate_const(U&& u) : t_(std::forward<U>(u)) {}
123
124 template <class U, enable_if_t<is_convertible<U&&, T>::value &&
125 is_constructible<T, U&&>::value &&
126 !is_propagate_const<decay_t<U>>::value,
127 bool> = false>
129#endif
130
131 // [propagate_const.assignment], assignment
133
135
136 template <class U>
138 t_ = std::move(pu.t_);
139 return *this;
140 }
141
142 template <class U,
143 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
145 t_ = std::move(u);
146 return *this;
147 }
148
149 // [propagate_const.const_observers], const observers
150 explicit PROPAGATE_CONST_CONSTEXPR operator bool() const { return get() != nullptr; }
152
153 template <class T_ = T, class U = enable_if_t<is_convertible<
154 const T_, const element_type*>::value>>
155 PROPAGATE_CONST_CONSTEXPR operator const element_type*() const // Not always defined
156 {
157 return get();
158 }
159
161
163
164 // [propagate_const.non_const_observers], non-const observers
166
167 template <class T_ = T,
168 class U = enable_if_t<is_convertible<T_, element_type*>::value>>
169 PROPAGATE_CONST_CONSTEXPR operator element_type*() // Not always defined
170 {
171 return get();
172 }
173
175
177
178 // [propagate_const.modifiers], modifiers
180 noexcept(swap(declval<T&>(), declval<T&>()))) {
181 swap(t_, pt.t_);
182 }
183
184 private:
185 T t_;
186
187 friend struct std::hash<propagate_const<T>>;
188 friend struct std::equal_to<propagate_const<T>>;
189 friend struct std::not_equal_to<propagate_const<T>>;
190 friend struct std::greater<propagate_const<T>>;
191 friend struct std::less<propagate_const<T>>;
192 friend struct std::greater_equal<propagate_const<T>>;
193 friend struct std::less_equal<propagate_const<T>>;
194
195 // [propagate_const.relational], relational operators
196 friend PROPAGATE_CONST_CONSTEXPR bool operator==(const propagate_const& pt, nullptr_t) {
197 return pt.t_ == nullptr;
198 }
199
200 friend PROPAGATE_CONST_CONSTEXPR bool operator==(nullptr_t, const propagate_const& pu) {
201 return nullptr == pu.t_;
202 }
203
204 friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const propagate_const& pt, nullptr_t) {
205 return pt.t_ != nullptr;
206 }
207
208 friend PROPAGATE_CONST_CONSTEXPR bool operator!=(nullptr_t, const propagate_const& pu) {
209 return nullptr != pu.t_;
210 }
211
212 template <class U>
214 const propagate_const<U>& pu) {
215 return pt.t_ == pu.t_;
216 }
217
218 template <class U>
220 const propagate_const<U>& pu) {
221 return pt.t_ != pu.t_;
222 }
223
224 template <class U>
226 const propagate_const<U>& pu) {
227 return pt.t_ < pu.t_;
228 }
229
230 template <class U>
232 const propagate_const<U>& pu) {
233 return pt.t_ > pu.t_;
234 }
235
236 template <class U>
238 const propagate_const<U>& pu) {
239 return pt.t_ <= pu.t_;
240 }
241
242 template <class U>
244 const propagate_const<U>& pu) {
245 return pt.t_ >= pu.t_;
246 }
247
248 template <class U,
249 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
250 friend PROPAGATE_CONST_CONSTEXPR bool operator==(const propagate_const& pt, const U& u) {
251 return pt.t_ == u;
252 }
253
254 template <class U,
255 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
256 friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const propagate_const& pt, const U& u) {
257 return pt.t_ != u;
258 }
259
260 template <class U,
261 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
262 friend PROPAGATE_CONST_CONSTEXPR bool operator<(const propagate_const& pt, const U& u) {
263 return pt.t_ < u;
264 }
265
266 template <class U,
267 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
268 friend PROPAGATE_CONST_CONSTEXPR bool operator>(const propagate_const& pt, const U& u) {
269 return pt.t_ > u;
270 }
271
272 template <class U,
273 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
274 friend PROPAGATE_CONST_CONSTEXPR bool operator<=(const propagate_const& pt, const U& u) {
275 return pt.t_ <= u;
276 }
277
278 template <class U,
279 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
280 friend PROPAGATE_CONST_CONSTEXPR bool operator>=(const propagate_const& pt, const U& u) {
281 return pt.t_ >= u;
282 }
283
284 template <class U,
285 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
286 friend PROPAGATE_CONST_CONSTEXPR bool operator==(const U& u, const propagate_const& pu) {
287 return u == pu.t_;
288 }
289
290 template <class U,
291 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
292 friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const U& u, const propagate_const& pu) {
293 return u != pu.t_;
294 }
295
296 template <class U,
297 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
298 friend PROPAGATE_CONST_CONSTEXPR bool operator<(const U& u, const propagate_const& pu) {
299 return u < pu.t_;
300 }
301
302 template <class U,
303 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
304 friend PROPAGATE_CONST_CONSTEXPR bool operator>(const U& u, const propagate_const& pu) {
305 return u > pu.t_;
306 }
307
308 template <class U,
309 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
310 friend PROPAGATE_CONST_CONSTEXPR bool operator<=(const U& u, const propagate_const& pu) {
311 return u <= pu.t_;
312 }
313
314 template <class U,
315 class = enable_if_t<!is_propagate_const<decay_t<U>>::value>>
316 friend PROPAGATE_CONST_CONSTEXPR bool operator>=(const U& u, const propagate_const& pu) {
317 return u >= pu.t_;
318 }
319};
320
321
322// [propagate_const.algorithms], specialized algorithms
323template <class T>
325 noexcept(swap(declval<T&>(), declval<T&>())))
326{
327 swap(pt.underlying_ptr(), pu.underlying_ptr());
328}
329
330} // end namespace fundamentals_v2
331} // end namespace experimental
332
333// [propagate_const.hash], hash support
334template <class T>
335struct hash<experimental::fundamentals_v2::propagate_const<T>> {
336 typedef size_t result_type;
338
341 return std::hash<T>()(pc.t_);
342 }
343};
344
345// [propagate_const.comparison_function_objects], comparison function objects
346template <class T>
347struct equal_to<experimental::fundamentals_v2::propagate_const<T>> {
351
355 return std::equal_to<T>()(pc1.t_, pc2.t_);
356 }
357};
358
359template <class T>
360struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>> {
364
368 return std::not_equal_to<T>()(pc1.t_, pc2.t_);
369 }
370};
371
372template <class T>
373struct less<experimental::fundamentals_v2::propagate_const<T>> {
377
381 return std::less<T>()(pc1.t_, pc2.t_);
382 }
383};
384
385template <class T>
386struct greater<experimental::fundamentals_v2::propagate_const<T>> {
390
394 return std::greater<T>()(pc1.t_, pc2.t_);
395 }
396};
397
398template <class T>
399struct less_equal<experimental::fundamentals_v2::propagate_const<T>> {
403
407 return std::less_equal<T>()(pc1.t_, pc2.t_);
408 }
409};
410
411template <class T>
412struct greater_equal<experimental::fundamentals_v2::propagate_const<T>> {
416
420 return std::greater_equal<T>()(pc1.t_, pc2.t_);
421 }
422};
423
424} // end namespace std
425
426#undef PROPAGATE_CONST_CONSTEXPR
427#endif // JBCOE_PROPAGATE_CONST_INCLUDED
float value(const T *src, size_t ch)
const Params2D p
qreal u
friend PROPAGATE_CONST_CONSTEXPR bool operator<(const propagate_const &pt, const propagate_const< U > &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator<=(const propagate_const &pt, const U &u)
friend PROPAGATE_CONST_CONSTEXPR bool operator<(const U &u, const propagate_const &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator>=(const propagate_const &pt, const U &u)
friend PROPAGATE_CONST_CONSTEXPR bool operator==(const propagate_const &pt, const U &u)
PROPAGATE_CONST_CONSTEXPR const element_type & operator*() const
static const element_type * get_pointer(const U *u)
friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const propagate_const &pt, const U &u)
PROPAGATE_CONST_CONSTEXPR void swap(propagate_const &pt) noexcept(noexcept(swap(declval< T & >(), declval< T & >())))
PROPAGATE_CONST_CONSTEXPR element_type * get()
friend PROPAGATE_CONST_CONSTEXPR bool operator==(const U &u, const propagate_const &pu)
PROPAGATE_CONST_CONSTEXPR propagate_const()=default
friend PROPAGATE_CONST_CONSTEXPR bool operator>(const propagate_const &pt, const propagate_const< U > &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator==(const propagate_const &pt, nullptr_t)
friend PROPAGATE_CONST_CONSTEXPR bool operator>(const propagate_const &pt, const U &u)
PROPAGATE_CONST_CONSTEXPR const element_type * get() const
propagate_const & operator=(const propagate_const &p)=delete
propagate_const(const propagate_const &p)=delete
static const element_type * get_pointer(const U &u)
friend PROPAGATE_CONST_CONSTEXPR bool operator<=(const propagate_const &pt, const propagate_const< U > &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const propagate_const &pt, const propagate_const< U > &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator<(const propagate_const &pt, const U &u)
PROPAGATE_CONST_CONSTEXPR propagate_const & operator=(U &&u)
friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const U &u, const propagate_const &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator==(nullptr_t, const propagate_const &pu)
PROPAGATE_CONST_CONSTEXPR const element_type * operator->() const
friend PROPAGATE_CONST_CONSTEXPR bool operator!=(nullptr_t, const propagate_const &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator<=(const U &u, const propagate_const &pu)
PROPAGATE_CONST_CONSTEXPR element_type * operator->()
friend PROPAGATE_CONST_CONSTEXPR bool operator!=(const propagate_const &pt, nullptr_t)
PROPAGATE_CONST_CONSTEXPR propagate_const(propagate_const< U > &&pu)
PROPAGATE_CONST_CONSTEXPR propagate_const & operator=(propagate_const< U > &&pu)
typename std::pointer_traits< T >::element_type element_type
PROPAGATE_CONST_CONSTEXPR propagate_const(propagate_const &&p)=default
PROPAGATE_CONST_CONSTEXPR element_type & operator*()
friend PROPAGATE_CONST_CONSTEXPR bool operator>=(const propagate_const &pt, const propagate_const< U > &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator==(const propagate_const &pt, const propagate_const< U > &pu)
PROPAGATE_CONST_CONSTEXPR propagate_const & operator=(propagate_const &&p)=default
friend PROPAGATE_CONST_CONSTEXPR bool operator>=(const U &u, const propagate_const &pu)
friend PROPAGATE_CONST_CONSTEXPR bool operator>(const U &u, const propagate_const &pu)
PROPAGATE_CONST_CONSTEXPR void swap(propagate_const< T > &pt, propagate_const< T > &pu) noexcept(noexcept(swap(declval< T & >(), declval< T & >())))
#define PROPAGATE_CONST_CONSTEXPR
experimental::fundamentals_v2::propagate_const< T > second_argument_type
experimental::fundamentals_v2::propagate_const< T > first_argument_type
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc1, const experimental::fundamentals_v2::propagate_const< T > &pc2) const
experimental::fundamentals_v2::propagate_const< T > first_argument_type
experimental::fundamentals_v2::propagate_const< T > second_argument_type
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc1, const experimental::fundamentals_v2::propagate_const< T > &pc2) const
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc1, const experimental::fundamentals_v2::propagate_const< T > &pc2) const
experimental::fundamentals_v2::propagate_const< T > second_argument_type
experimental::fundamentals_v2::propagate_const< T > first_argument_type
experimental::fundamentals_v2::propagate_const< T > argument_type
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc) const
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc1, const experimental::fundamentals_v2::propagate_const< T > &pc2) const
experimental::fundamentals_v2::propagate_const< T > second_argument_type
experimental::fundamentals_v2::propagate_const< T > first_argument_type
experimental::fundamentals_v2::propagate_const< T > second_argument_type
experimental::fundamentals_v2::propagate_const< T > first_argument_type
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc1, const experimental::fundamentals_v2::propagate_const< T > &pc2) const
bool operator()(const experimental::fundamentals_v2::propagate_const< T > &pc1, const experimental::fundamentals_v2::propagate_const< T > &pc2) const
experimental::fundamentals_v2::propagate_const< T > second_argument_type
experimental::fundamentals_v2::propagate_const< T > first_argument_type