Add sub-controls for Hack array compat runtime checks
[hiphop-php.git] / hphp / runtime / base / comparisons.h
blobfd4e5768f50f21a2a1c4771ac497e271fe1096ca
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_COMPARISONS_H_
18 #define incl_HPHP_COMPARISONS_H_
20 #include "hphp/runtime/base/builtin-functions.h"
21 #include "hphp/runtime/base/tv-comparisons.h"
22 #include "hphp/runtime/base/type-variant.h"
24 namespace HPHP {
26 namespace detail {
28 ALWAYS_INLINE void hackArrCompatCheck(const Array& arr) {
29 if (UNLIKELY(checkHACCompare() && !arr.isNull())) {
30 raiseHackArrCompatArrMixedCmp();
36 ///////////////////////////////////////////////////////////////////////////////
37 // Variant
39 bool same(const Variant& v1, bool v2);
40 bool same(const Variant& v1, int64_t v2);
41 inline bool same(const Variant& v1, int v2) { return same(v1, (int64_t)v2); }
42 bool same(const Variant& v1, double v2);
43 bool same(const Variant& v1, const StringData* v2);
44 bool same(const Variant& v1, const String& v2);
45 bool same(const Variant& v1, const char* v2) = delete;
46 bool same(const Variant& v1, const Array& v2);
47 bool same(const Variant& v1, const Object& v2);
48 bool same(const Variant& v1, const Resource& v2);
49 inline bool same(const Variant& v1, const Variant& v2) {
50 return tvSame(*v1.asTypedValue(), *v2.asTypedValue());
53 inline bool equal(const Variant& v1, bool v2) {
54 return cellEqual(*v1.asCell(), v2);
56 inline bool equal(const Variant& v1, int v2) {
57 return cellEqual(*v1.asCell(), v2);
59 inline bool equal(const Variant& v1, int64_t v2) {
60 return cellEqual(*v1.asCell(), v2);
62 inline bool equal(const Variant& v1, double v2) {
63 return cellEqual(*v1.asCell(), v2);
65 inline bool equal(const Variant& v1, const StringData* v2) {
66 return cellEqual(*v1.asCell(), v2);
68 inline bool equal(const Variant& v1, const String& v2) {
69 if (!v2.get()) return cellEqual(*v1.asCell(), false);
70 return cellEqual(*v1.asCell(), v2.get());
72 inline bool equal(const Variant& v1, const char* v2) = delete;
73 inline bool equal(const Variant& v1, const Array& v2) {
74 if (!v2.get()) return cellEqual(*v1.asCell(), false);
75 return cellEqual(*v1.asCell(), v2.get());
77 inline bool equal(const Variant& v1, const Object& v2) {
78 if (!v2.get()) return cellEqual(*v1.asCell(), false);
79 return cellEqual(*v1.asCell(), v2.get());
81 inline bool equal(const Variant& v1, const Resource& v2) {
82 if (!v2) return cellEqual(*v1.asCell(), false);
83 return cellEqual(*v1.asCell(), deref<ResourceData>(v2));
85 inline bool equal(const Variant& v1, const Variant& v2) {
86 return tvEqual(*v1.asTypedValue(), *v2.asTypedValue());
89 inline bool less(const Variant& v1, bool v2) {
90 return cellLess(*v1.asCell(), v2);
92 inline bool less(const Variant& v1, int v2) {
93 return cellLess(*v1.asCell(), v2);
95 inline bool less(const Variant& v1, int64_t v2) {
96 return cellLess(*v1.asCell(), v2);
98 inline bool less(const Variant& v1, double v2) {
99 return cellLess(*v1.asCell(), v2);
101 inline bool less(const Variant& v1, const StringData* v2) {
102 return cellLess(*v1.asCell(), v2);
104 inline bool less(const Variant& v1, const String& v2) {
105 if (!v2.get()) return cellLess(*v1.asCell(), false);
106 return cellLess(*v1.asCell(), v2.get());
108 inline bool less(const Variant& v1, const char* v2) = delete;
109 inline bool less(const Variant& v1, const Array& v2) {
110 if (!v2.get()) return cellLess(*v1.asCell(), false);
111 return cellLess(*v1.asCell(), v2.get());
113 inline bool less(const Variant& v1, const Object& v2) {
114 if (!v2.get()) return cellLess(*v1.asCell(), false);
115 return cellLess(*v1.asCell(), v2.get());
117 inline bool less(const Variant& v1, const Resource& v2) {
118 if (!v2) return cellLess(*v1.asCell(), false);
119 return cellLess(*v1.asCell(), deref<ResourceData>(v2));
121 inline bool less(const Variant& v1, const Variant& v2) {
122 return tvLess(*v1.asTypedValue(), *v2.asTypedValue());
125 inline bool more(const Variant& v1, bool v2) {
126 return cellGreater(*v1.asCell(), v2);
128 inline bool more(const Variant& v1, int v2) {
129 return cellGreater(*v1.asCell(), v2);
131 inline bool more(const Variant& v1, int64_t v2) {
132 return cellGreater(*v1.asCell(), v2);
134 inline bool more(const Variant& v1, double v2) {
135 return cellGreater(*v1.asCell(), v2);
137 inline bool more(const Variant& v1, const StringData* v2) {
138 return cellGreater(*v1.asCell(), v2);
140 inline bool more(const Variant& v1, const String& v2) {
141 if (!v2.get()) return cellGreater(*v1.asCell(), false);
142 return cellGreater(*v1.asCell(), v2.get());
144 inline bool more(const Variant& v1, const char* v2) = delete;
145 inline bool more(const Variant& v1, const Array& v2) {
146 if (!v2.get()) return cellGreater(*v1.asCell(), false);
147 return cellGreater(*v1.asCell(), v2.get());
149 inline bool more(const Variant& v1, const Object& v2) {
150 if (!v2.get()) return cellGreater(*v1.asCell(), false);
151 return cellGreater(*v1.asCell(), v2.get());
153 inline bool more(const Variant& v1, const Resource& v2) {
154 if (!v2) return cellGreater(*v1.asCell(), false);
155 return cellGreater(*v1.asCell(), deref<ResourceData>(v2));
157 inline bool more(const Variant& v1, const Variant& v2) {
158 return tvGreater(*v1.asTypedValue(), *v2.asTypedValue());
161 inline int64_t compare(const Variant& v1, const Variant& v2) {
162 return tvCompare(*v1.asTypedValue(), *v2.asTypedValue());
165 ///////////////////////////////////////////////////////////////////////////////
166 // bool
168 inline bool same(bool v1, bool v2) = delete;
169 inline bool same(bool v1, int v2) = delete;
170 inline bool same(bool v1, int64_t v2) = delete;
171 inline bool same(bool v1, double v2) = delete;
172 inline bool same(bool /*v1*/, const StringData* /*v2*/) {
173 return false;
175 inline bool same(bool /*v1*/, const String& /*v2*/) {
176 return false;
178 inline bool same(bool v1, const char* v2) = delete;
179 inline bool same(bool /*v1*/, const Array& /*v2*/) {
180 return false;
182 inline bool same(bool /*v1*/, const Object& /*v2*/) {
183 return false;
185 inline bool same(bool /*v1*/, const Resource& /*v2*/) {
186 return false;
188 inline bool same(bool v1, const Variant& v2) { return same(v2, v1); }
190 inline bool equal(bool v1, bool v2) { return v1 == v2; }
191 inline bool equal(bool v1, int v2) { return v1 == (v2 != 0); }
192 inline bool equal(bool v1, int64_t v2) { return v1 == (v2 != 0); }
193 inline bool equal(bool v1, double v2) { return v1 == (v2 != 0.0); }
194 inline bool equal(bool v1, const StringData *v2) {
195 return v1 == (v2 ? v2->toBoolean() : false);
197 inline bool equal(bool v1, const String& v2) { return v1 == v2.toBoolean(); }
198 inline bool equal(bool v1, const char* v2) = delete;
199 inline bool equal(bool v1, const Array& v2) {
200 if (LIKELY(v2.isPHPArray())) return v1 == v2.toBoolean();
201 return false;
203 inline bool equal(bool v1, const Object& v2) { return v1 == v2.toBoolean(); }
204 inline bool equal(bool v1, const Resource& v2) { return v1 == v2.toBoolean(); }
205 inline bool equal(bool v1, const Variant& v2) { return equal(v2, v1); }
207 inline bool less(bool v1, bool v2) { return (v1?1:0) < (v2?1:0); }
208 inline bool less(bool v1, int v2) { return less(v1,(v2 != 0)); }
209 inline bool less(bool v1, int64_t v2) { return less(v1,(v2 != 0)); }
210 inline bool less(bool v1, double v2) { return less(v1,(v2 != 0.0)); }
211 inline bool less(bool v1, const StringData *v2) {
212 return less(v1, (v2 ? v2->toBoolean() : false));
214 inline bool less(bool v1, const String& v2) { return less(v1,v2.toBoolean()); }
215 inline bool less(bool v1, const char* v2) = delete;
216 inline bool less(bool v1, const Array& v2) {
217 if (LIKELY(v2.isPHPArray())) {
218 detail::hackArrCompatCheck(v2);
219 return less(v1, v2.toBoolean());
221 if (v2.isVecArray()) throw_vec_compare_exception();
222 if (v2.isDict()) throw_dict_compare_exception();
223 assert(v2.isKeyset());
224 throw_keyset_compare_exception();
226 inline bool less(bool v1, const Object& v2) { return less(v1,v2.toBoolean()); }
227 inline bool less(bool v1, const Resource& v2) {
228 return less(v1,v2.toBoolean());
230 inline bool less(bool v1, const Variant& v2) { return more(v2,v1); }
232 inline bool more(bool v1, bool v2) { return (v1?1:0) > (v2?1:0); }
233 inline bool more(bool v1, int v2) { return more(v1,(v2 != 0)); }
234 inline bool more(bool v1, int64_t v2) { return more(v1,(v2 != 0)); }
235 inline bool more(bool v1, double v2) { return more(v1,(v2 != 0.0)); }
236 inline bool more(bool v1, const StringData *v2) {
237 return more(v1, (v2 ? v2->toBoolean() : false));
239 inline bool more(bool v1, const String& v2) { return more(v1,v2.toBoolean()); }
240 inline bool more(bool v1, const char* v2) = delete;
241 inline bool more(bool v1, const Array& v2) {
242 if (LIKELY(v2.isPHPArray())) {
243 detail::hackArrCompatCheck(v2);
244 return more(v1, v2.toBoolean());
246 if (v2.isVecArray()) throw_vec_compare_exception();
247 if (v2.isDict()) throw_dict_compare_exception();
248 assert(v2.isKeyset());
249 throw_keyset_compare_exception();
251 inline bool more(bool v1, const Object& v2) { return more(v1,v2.toBoolean()); }
252 inline bool more(bool v1, const Resource& v2) {
253 return more(v1,v2.toBoolean());
255 inline bool more(bool v1, const Variant& v2) { return less(v2,v1); }
257 inline int64_t compare(bool v1, bool v2) { return v1 - v2; }
259 ///////////////////////////////////////////////////////////////////////////////
260 // int
262 inline bool same(int v1, bool v2) = delete;
263 inline bool same(int v1, int v2) = delete;
264 inline bool same(int v1, int64_t v2) = delete;
265 inline bool same(int v1, double v2) = delete;
266 inline bool same(int /*v1*/, const StringData* /*v2*/) {
267 return false;
269 inline bool same(int /*v1*/, const String& /*v2*/) {
270 return false;
272 inline bool same(int v1, const char* v2) = delete;
273 inline bool same(int /*v1*/, const Array& /*v2*/) {
274 return false;
276 inline bool same(int /*v1*/, const Object& /*v2*/) {
277 return false;
279 inline bool same(int /*v1*/, const Resource& /*v2*/) {
280 return false;
282 inline bool same(int v1, const Variant& v2) { return same(v2, v1); }
284 inline bool equal(int v1, bool v2) { return equal(v2, v1); }
285 inline bool equal(int v1, int v2) { return v1 == v2; }
286 inline bool equal(int v1, int64_t v2) { return v1 == v2; }
287 inline bool equal(int v1, double v2) { return (double)v1 == v2; }
288 bool equal(int v1, const StringData *v2);
289 inline bool equal(int v1, const String& v2) { return equal(v1, v2.get()); }
290 inline bool equal(int v1, const char* v2) = delete;
291 inline bool equal(int /*v1*/, const Array& /*v2*/) {
292 return false;
294 inline bool equal(int v1, const Object& v2) {
295 return v2->isCollection() ? false : equal(v1, v2.toInt64());
297 inline bool equal(int v1, const Resource& v2) {
298 return equal(v1, v2.toInt64());
300 inline bool equal(int v1, const Variant& v2) { return equal(v2, v1); }
302 inline bool less(int v1, bool v2) { return more(v2, v1); }
303 inline bool less(int v1, int v2) { return v1 < v2; }
304 inline bool less(int v1, int64_t v2) { return v1 < v2; }
305 inline bool less(int v1, double v2) { return v1 < v2; }
306 bool less(int v1, const StringData *v2);
307 inline bool less(int v1, const String& v2) { return less(v1, v2.get()); }
308 inline bool less(int v1, const char* v2) = delete;
309 inline bool less(int /*v1*/, const Array& v2) {
310 if (LIKELY(v2.isPHPArray())) {
311 detail::hackArrCompatCheck(v2);
312 return true;
314 if (v2.isVecArray()) throw_vec_compare_exception();
315 if (v2.isDict()) throw_dict_compare_exception();
316 assert(v2.isKeyset());
317 throw_keyset_compare_exception();
319 inline bool less(int v1, const Object& v2) {
320 return less(v1, v2.toInt64ForCompare());
322 inline bool less(int v1, const Resource& v2) { return less(v1, v2.toInt64()); }
323 inline bool less(int v1, const Variant& v2) { return more(v2, v1); }
325 inline bool more(int v1, bool v2) { return less(v2, v1); }
326 inline bool more(int v1, int v2) { return v1 > v2; }
327 inline bool more(int v1, int64_t v2) { return v1 > v2; }
328 inline bool more(int v1, double v2) { return v1 > v2; }
329 bool more(int v1, const StringData *v2);
330 inline bool more(int v1, const String& v2) { return more(v1, v2.get()); }
331 inline bool more(int v1, const char* v2) = delete;
332 inline bool more(int /*v1*/, const Array& v2) {
333 if (LIKELY(v2.isPHPArray())) {
334 detail::hackArrCompatCheck(v2);
335 return false;
337 if (v2.isVecArray()) throw_vec_compare_exception();
338 if (v2.isDict()) throw_dict_compare_exception();
339 assert(v2.isKeyset());
340 throw_keyset_compare_exception();
342 inline bool more(int v1, const Object& v2) {
343 return more(v1, v2.toInt64ForCompare());
345 inline bool more(int v1, const Resource& v2) { return more(v1, v2.toInt64()); }
346 inline bool more(int v1, const Variant& v2) { return less(v2, v1); }
348 inline int64_t compare(int v1, int v2) {
349 return (v1 < v2) ? -1 : ((v1 > v2) ? 1 : 0);
352 ///////////////////////////////////////////////////////////////////////////////
353 // int64
355 inline bool same(int64_t v1, bool v2) = delete;
356 inline bool same(int64_t v1, int v2) = delete;
357 inline bool same(int64_t v1, int64_t v2) = delete;
358 inline bool same(int64_t v1, double v2) = delete;
359 inline bool same(int64_t /*v1*/, const StringData* /*v2*/) {
360 return false;
362 inline bool same(int64_t /*v1*/, const String& /*v2*/) {
363 return false;
365 inline bool same(int64_t v1, const char* v2) = delete;
366 inline bool same(int64_t /*v1*/, const Array& /*v2*/) {
367 return false;
369 inline bool same(int64_t /*v1*/, const Object& /*v2*/) {
370 return false;
372 inline bool same(int64_t /*v1*/, const Resource& /*v2*/) {
373 return false;
375 inline bool same(int64_t v1, const Variant& v2) { return same(v2, v1); }
377 inline bool equal(int64_t v1, bool v2) { return equal(v2, v1); }
378 inline bool equal(int64_t v1, int v2) { return equal(v2, v1); }
379 inline bool equal(int64_t v1, int64_t v2) { return v1 == v2; }
380 inline bool equal(int64_t v1, double v2) { return (double)v1 == v2; }
381 bool equal(int64_t v1, const StringData *v2);
382 inline bool equal(int64_t v1, const String& v2) { return equal(v1, v2.get()); }
383 inline bool equal(int64_t v1, const char* v2) = delete;
384 inline bool equal(int64_t /*v1*/, const Array& /*v2*/) {
385 return false;
387 inline bool equal(int64_t v1, const Object& v2) {
388 return v2->isCollection() ? false : equal(v1, v2.toInt64());
390 inline bool equal(int64_t v1, const Resource& v2) {
391 return equal(v1, v2.toInt64());
393 inline bool equal(int64_t v1, const Variant& v2) {
394 return equal(v2, v1);
397 inline bool nequal(int64_t v1, const StringData* v2) {
398 return !equal(v1, v2);
401 inline bool less(int64_t v1, bool v2) { return more(v2, v1); }
402 inline bool less(int64_t v1, int v2) { return more(v2, v1); }
403 inline bool less(int64_t v1, int64_t v2) { return v1 < v2; }
404 inline bool less(int64_t v1, double v2) { return v1 < v2; }
405 bool less(int64_t v1, const StringData *v2);
406 inline bool less(int64_t v1, const String& v2) { return less(v1, v2.get()); }
407 inline bool less(int64_t v1, const char* v2) = delete;
408 inline bool less(int64_t /*v1*/, const Array& v2) {
409 if (LIKELY(v2.isPHPArray())) {
410 detail::hackArrCompatCheck(v2);
411 return true;
413 if (v2.isVecArray()) throw_vec_compare_exception();
414 if (v2.isDict()) throw_dict_compare_exception();
415 assert(v2.isKeyset());
416 throw_keyset_compare_exception();
418 inline bool less(int64_t v1, const Object& v2) {
419 return less(v1, v2.toInt64ForCompare());
421 inline bool less(int64_t v1, const Resource& v2) {
422 return less(v1, v2.toInt64());
424 inline bool less(int64_t v1, const Variant& v2) {
425 return more(v2, v1);
428 bool lessEqual(int64_t v1, const StringData* v2);
430 inline bool more(int64_t v1, bool v2) { return less(v2, v1); }
431 inline bool more(int64_t v1, int v2) { return less(v2, v1); }
432 inline bool more(int64_t v1, int64_t v2) { return v1 > v2; }
433 inline bool more(int64_t v1, double v2) { return v1 > v2; }
434 bool more(int64_t v1, const StringData *v2);
435 inline bool more(int64_t v1, const String& v2) { return more(v1, v2.get()); }
436 inline bool more(int64_t v1, const char* v2) = delete;
437 inline bool more(int64_t /*v1*/, const Array& v2) {
438 if (LIKELY(v2.isPHPArray())) {
439 detail::hackArrCompatCheck(v2);
440 return false;
442 if (v2.isVecArray()) throw_vec_compare_exception();
443 if (v2.isDict()) throw_dict_compare_exception();
444 assert(v2.isKeyset());
445 throw_keyset_compare_exception();
447 inline bool more(int64_t v1, const Object& v2) {
448 return more(v1, v2.toInt64ForCompare());
450 inline bool more(int64_t v1, const Resource& v2) {
451 return more(v1, v2.toInt64());
453 inline bool more(int64_t v1, const Variant& v2) { return less(v2, v1); }
455 bool moreEqual(int64_t v1, const StringData* v2);
457 inline int64_t compare(int64_t v1, int64_t v2) {
458 return (v1 < v2) ? -1 : ((v1 > v2) ? 1 : 0);
461 ///////////////////////////////////////////////////////////////////////////////
462 // double
464 inline bool same(double v1, bool v2) = delete;
465 inline bool same(double v1, int v2) = delete;
466 inline bool same(double v1, int64_t v2) = delete;
467 inline bool same(double v1, double v2) = delete;
468 inline bool same(double /*v1*/, const StringData* /*v2*/) {
469 return false;
471 inline bool same(double /*v1*/, const String& /*v2*/) {
472 return false;
474 inline bool same(double v1, const char* v2) = delete;
475 inline bool same(double /*v1*/, const Array& /*v2*/) {
476 return false;
478 inline bool same(double /*v1*/, const Object& /*v2*/) {
479 return false;
481 inline bool same(double /*v1*/, const Resource& /*v2*/) {
482 return false;
484 inline bool same(double v1, const Variant& v2) { return same(v2, v1); }
486 inline bool equal(double v1, bool v2) { return equal(v2, v1); }
487 inline bool equal(double v1, int v2) { return equal(v2, v1); }
488 inline bool equal(double v1, int64_t v2) { return equal(v2, v1); }
489 inline bool equal(double v1, double v2) { return v1 == v2; }
490 inline bool equal(double v1, const StringData* v2) {
491 return v1 == (v2 ? v2->toDouble() : 0.0);
493 inline bool equal(double v1, const String& v2) { return v1 == v2.toDouble(); }
494 inline bool equal(double v1, const char* v2) = delete;
495 inline bool equal(double /*v1*/, const Array& /*v2*/) {
496 return false;
498 inline bool equal(double v1, const Object& v2) {
499 if (v2->isCollection()) return false;
500 return equal(v1, v2.toDouble());
502 inline bool equal(double v1, const Resource& v2) {
503 return equal(v1, v2.toDouble());
505 inline bool equal(double v1, const Variant& v2) {
506 return equal(v2, v1);
509 inline bool less(double v1, bool v2) { return more(v2, v1); }
510 inline bool less(double v1, int v2) { return more(v2, v1); }
511 inline bool less(double v1, int64_t v2) { return more(v2, v1); }
512 inline bool less(double v1, double v2) { return v1 < v2; }
513 inline bool less(double v1, const StringData *v2) {
514 return less(v1, (v2 ? v2->toDouble() : 0.0));
516 inline bool less(double v1, const String& v2) { return less(v1,v2.toDouble()); }
517 inline bool less(double v1, const char* v2) = delete;
518 inline bool less(double /*v1*/, const Array& v2) {
519 if (LIKELY(v2.isPHPArray())) {
520 detail::hackArrCompatCheck(v2);
521 return true;
523 if (v2.isVecArray()) throw_vec_compare_exception();
524 if (v2.isDict()) throw_dict_compare_exception();
525 assert(v2.isKeyset());
526 throw_keyset_compare_exception();
528 inline bool less(double v1, const Object& v2) {
529 return less(v1, v2.toDoubleForCompare());
531 inline bool less(double v1, const Resource& v2) {
532 return less(v1, v2.toDouble());
534 inline bool less(double v1, const Variant& v2) {
535 return more(v2, v1);
538 inline bool more(double v1, bool v2) { return less(v2, v1); }
539 inline bool more(double v1, int v2) { return less(v2, v1); }
540 inline bool more(double v1, int64_t v2) { return less(v2, v1); }
541 inline bool more(double v1, double v2) { return v1 > v2; }
542 inline bool more(double v1, const StringData *v2) {
543 return more(v1, (v2 ? v2->toDouble() : 0.0));
545 inline bool more(double v1, const String& v2) { return more(v1,v2.toDouble()); }
546 inline bool more(double v1, const char* v2) = delete;
547 inline bool more(double /*v1*/, const Array& v2) {
548 if (LIKELY(v2.isPHPArray())) {
549 detail::hackArrCompatCheck(v2);
550 return false;
552 if (v2.isVecArray()) throw_vec_compare_exception();
553 if (v2.isDict()) throw_dict_compare_exception();
554 assert(v2.isKeyset());
555 throw_keyset_compare_exception();
557 inline bool more(double v1, const Object& v2) {
558 return more(v1, v2.toDoubleForCompare());
560 inline bool more(double v1, const Resource& v2) {
561 return more(v1, v2.toDouble());
563 inline bool more(double v1, const Variant& v2) { return less(v2, v1); }
565 inline int64_t compare(double v1, double v2) {
566 // This ordering is required so that -1 is returned for NaNs (to match PHP7
567 // behavior).
568 return (v1 == v2) ? 0 : ((v1 > v2) ? 1 : -1);
571 ///////////////////////////////////////////////////////////////////////////////
572 // StringData *
574 inline bool same(const StringData *v1, bool v2) { return same(v2, v1); }
575 inline bool same(const StringData *v1, int v2) { return same(v2, v1); }
576 inline bool same(const StringData *v1, int64_t v2) { return same(v2, v1); }
577 inline bool same(const StringData *v1, double v2) { return same(v2, v1); }
578 inline bool same(const StringData *v1, const StringData *v2) {
579 if (v1 == v2) return true;
580 if (v1 && v2) return v1->same(v2);
581 return false;
583 inline bool same(const StringData *v1, const String& v2) {
584 return same(v1, v2.get());
586 inline bool same(const StringData *v1, const char* v2) = delete;
587 inline bool same(const StringData* /*v1*/, const Array& /*v2*/) {
588 return false;
590 inline bool same(const StringData* /*v1*/, const Object& /*v2*/) {
591 return false;
593 inline bool same(const StringData* /*v1*/, const Resource& /*v2*/) {
594 return false;
596 inline bool same(const StringData *v1, const Variant& v2) {
597 return same(v2, v1);
600 inline bool nsame(const StringData* v1, const StringData* v2) {
601 return !same(v1, v2);
604 inline bool equal(const StringData *v1, bool v2) { return equal(v2, v1); }
605 inline bool equal(const StringData *v1, int v2) { return equal(v2, v1); }
606 inline bool equal(const StringData *v1, int64_t v2) { return equal(v2, v1); }
607 inline bool equal(const StringData *v1, double v2) { return equal(v2, v1); }
608 inline bool equal(const StringData *v1, const StringData *v2) {
609 if (v1 == v2) return true;
610 if (v1 == nullptr) return v2->empty();
611 if (v2 == nullptr) return v1->empty();
612 return v1->equal(v2);
614 inline bool equal(const StringData *v1, const String& v2) {
615 return equal(v1, v2.get());
617 inline bool equal(const StringData *v1, const char* v2) = delete;
618 inline bool equal(const StringData *v1, const Array& v2) {
619 if (LIKELY(v2.isPHPArray())) {
620 if (v1 == nullptr || v2.get() == nullptr) {
621 return equal(v1 ? v1->toBoolean() : false, v2.toBoolean());
624 return false;
626 inline bool equal(const StringData *v1, const Object& v2) {
627 if (v1 == nullptr || v2.get() == nullptr) {
628 return equal(v1 ? v1->toBoolean() : false, v2.toBoolean());
630 if (v2->isCollection()) return false;
631 if (!v2->hasToString()) return false;
632 return equal(v1, v2.toString());
635 inline bool equal(const StringData *v1, const Resource& v2) {
636 if (!v1 || !v2) {
637 return equal(v1 ? v1->toBoolean() : false, v2.toBoolean());
639 return false;
641 inline bool equal(const StringData *v1, const Variant& v2) {
642 return equal(v2, v1);
645 inline bool nequal(const StringData* v1, const StringData* v2) {
646 return !equal(v1, v2);
648 inline bool nequal(const StringData* v1, int64_t v2) {
649 return !equal(v1, v2);
652 inline bool less(const StringData *v1, bool v2) { return more(v2, v1); }
653 inline bool less(const StringData *v1, int v2) { return more(v2, v1); }
654 inline bool less(const StringData *v1, int64_t v2) { return more(v2, v1); }
655 inline bool less(const StringData *v1, double v2) { return more(v2, v1); }
656 inline bool less(const StringData *v1, const StringData *v2) {
657 if (v1 == v2 || v2 == nullptr) return false;
658 if (v1 == nullptr) return !v2->empty();
659 return v1->compare(v2) < 0;
661 inline bool less(const StringData *v1, const String& v2) {
662 return less(v1, v2.get());
664 inline bool less(const StringData *v1, const char* v2) = delete;
665 inline bool less(const StringData *v1, const Array& v2) {
666 if (LIKELY(v2.isPHPArray())) {
667 detail::hackArrCompatCheck(v2);
668 if (v1 == nullptr || v2.get() == nullptr) {
669 return less(v1 ? v1->toBoolean() : false, v2.toBoolean());
671 return true;
673 if (v2.isVecArray()) throw_vec_compare_exception();
674 if (v2.isDict()) throw_dict_compare_exception();
675 assert(v2.isKeyset());
676 throw_keyset_compare_exception();
678 inline bool less(const StringData *v1, const Object& v2) {
679 if (v1 == nullptr || v2.get() == nullptr) {
680 return less(v1 ? v1->toBoolean() : false, v2.toBoolean());
682 check_collection_compare(v2.get());
683 if (!v2->hasToString()) return true;
684 return less(v1, v2.toString());
686 inline bool less(const StringData *v1, const Resource& v2) {
687 if (!v1 || !v2) {
688 return less(v1 ? v1->toBoolean() : false, v2.toBoolean());
690 return true;
692 inline bool less(const StringData *v1, const Variant& v2) {
693 return more(v2, v1);
696 inline bool lessEqual(const StringData* v1, const StringData* v2) {
697 if (v1 == v2 || v1 == nullptr) return true;
698 if (v2 == nullptr) return v1->empty();
699 return v1->compare(v2) <= 0;
701 inline bool lessEqual(const StringData* v1, int64_t v2) {
702 return moreEqual(v2, v1);
705 inline bool more(const StringData *v1, bool v2) { return less(v2, v1); }
706 inline bool more(const StringData *v1, int v2) { return less(v2, v1); }
707 inline bool more(const StringData *v1, int64_t v2) { return less(v2, v1); }
708 inline bool more(const StringData *v1, double v2) { return less(v2, v1); }
709 inline bool more(const StringData *v1, const StringData *v2) {
710 if (v1 == nullptr) return false;
711 if (v2 == nullptr) return !v1->empty();
712 return v1->compare(v2) > 0;
714 inline bool more(const StringData *v1, const String& v2) {
715 return more(v1, v2.get());
717 inline bool more(const StringData *v1, const char* v2) = delete;
718 inline bool more(const StringData *v1, const Array& v2) {
719 if (LIKELY(v2.isPHPArray())) {
720 detail::hackArrCompatCheck(v2);
721 if (v1 == nullptr || v2.get() == nullptr) {
722 return more(v1 ? v1->toBoolean() : false, v2.toBoolean());
724 return false;
726 if (v2.isVecArray()) throw_vec_compare_exception();
727 if (v2.isDict()) throw_dict_compare_exception();
728 assert(v2.isKeyset());
729 throw_keyset_compare_exception();
731 inline bool more(const StringData *v1, const Object& v2) {
732 if (v1 == nullptr || v2.get() == nullptr) {
733 return more(v1 ? v1->toBoolean() : false, v2.toBoolean());
735 check_collection_compare(v2.get());
736 if (!v2->hasToString()) return false;
737 return more(v1, v2.toString());
739 inline bool more(const StringData *v1, const Resource& v2) {
740 if (!v1 || !v2) {
741 return more(v1 ? v1->toBoolean() : false, v2.toBoolean());
743 return false;
745 inline bool more(const StringData *v1, const Variant& v2) {
746 return less(v2, v1);
749 inline bool moreEqual(const StringData* v1, const StringData* v2) {
750 return lessEqual(v2, v1);
752 inline bool moreEqual(const StringData* v1, int64_t v2) {
753 return lessEqual(v2, v1);
756 int64_t compare(const StringData* v1, int64_t v2);
757 inline int64_t compare(const StringData* v1, const StringData* v2) {
758 assert(v1);
759 assert(v2);
760 // Clamp return values to just -1, 0, 1.
761 auto cmp = v1->compare(v2);
762 return (cmp < 0) ? -1 : ((cmp > 0) ? 1 : 0);
765 ///////////////////////////////////////////////////////////////////////////////
766 // String
768 inline bool same(const String& v1, bool v2) { return same(v2, v1); }
769 inline bool same(const String& v1, int v2) { return same(v2, v1); }
770 inline bool same(const String& v1, int64_t v2) { return same(v2, v1); }
771 inline bool same(const String& v1, double v2) { return same(v2, v1); }
772 inline bool same(const String& v1, const StringData *v2) {
773 return same(v2, v1.get());
775 inline bool same(const String& v1, const String& v2) { return v1.same(v2); }
776 inline bool same(const String& v1, const char* v2) = delete;
777 inline bool same(const String& v1, const Array& v2) {
778 return same(v1.get(), v2);
780 inline bool same(const String& v1, const Object& v2) {
781 return same(v1.get(), v2);
783 inline bool same(const String& v1, const Resource& v2) {
784 return same(v1.get(), v2);
786 inline bool same(const String& v1, const Variant& v2) { return same(v2, v1); }
788 inline bool equal(const String& v1, bool v2) { return equal(v2, v1); }
789 inline bool equal(const String& v1, int v2) { return equal(v2, v1); }
790 inline bool equal(const String& v1, int64_t v2) { return equal(v2, v1); }
791 inline bool equal(const String& v1, double v2) { return equal(v2, v1); }
792 inline bool equal(const String& v1, const StringData *v2) {
793 return equal(v2, v1.get());
795 inline bool equal(const String& v1, const String& v2) { return v1.equal(v2); }
796 inline bool equal(const String& v1, const char* v2) = delete;
797 inline bool equal(const String& v1, const Array& v2) {
798 return equal(v1.get(), v2);
800 inline bool equal(const String& v1, const Object& v2) {
801 return equal(v1.get(), v2);
803 inline bool equal(const String& v1, const Resource& v2) {
804 return equal(v1.get(), v2);
806 inline bool equal(const String& v1, const Variant& v2) { return equal(v2, v1); }
808 inline bool less(const String& v1, bool v2) { return more(v2, v1); }
809 inline bool less(const String& v1, int v2) { return more(v2, v1); }
810 inline bool less(const String& v1, int64_t v2) { return more(v2, v1); }
811 inline bool less(const String& v1, double v2) { return more(v2, v1); }
812 inline bool less(const String& v1, const StringData *v2) {
813 return more(v2, v1.get());
815 inline bool less(const String& v1, const String& v2) { return v1.less(v2); }
816 inline bool less(const String& v1, const char* v2) = delete;
817 inline bool less(const String& v1, const Array& v2) {
818 return less(v1.get(), v2);
820 inline bool less(const String& v1, const Object& v2) {
821 return less(v1.get(), v2);
823 inline bool less(const String& v1, const Resource& v2) {
824 return less(v1.get(), v2);
826 inline bool less(const String& v1, const Variant& v2) { return more(v2, v1); }
828 inline bool more(const String& v1, bool v2) { return less(v2, v1); }
829 inline bool more(const String& v1, int v2) { return less(v2, v1); }
830 inline bool more(const String& v1, int64_t v2) { return less(v2, v1); }
831 inline bool more(const String& v1, double v2) { return less(v2, v1); }
832 inline bool more(const String& v1, const StringData *v2) {
833 return less(v2, v1.get());
835 inline bool more(const String& v1, const String& v2) { return v1.more(v2); }
836 inline bool more(const String& v1, const char* v2) = delete;
837 inline bool more(const String& v1, const Array& v2) {
838 return more(v1.get(), v2);
840 inline bool more(const String& v1, const Object& v2) {
841 return more(v1.get(), v2);
843 inline bool more(const String& v1, const Resource& v2) {
844 return more(v1.get(), v2);
846 inline bool more(const String& v1, const Variant& v2) { return less(v2, v1); }
848 ///////////////////////////////////////////////////////////////////////////////
849 // const char* as first arg (deprecated)
851 inline bool same(const char* v1, bool v2) = delete;
852 inline bool same(const char* v1, int v2) = delete;
853 inline bool same(const char* v1, int64_t v2) = delete;
854 inline bool same(const char* v1, double v2) = delete;
855 inline bool same(const char* v1, const StringData *v2) = delete;
856 inline bool same(const char* v1, const String& v2) = delete;
857 inline bool same(const char* v1, const char* v2) = delete;
858 inline bool same(const char* v1, const Array& v2) = delete;
859 inline bool same(const char* v1, const Object& v2) = delete;
860 inline bool same(const char* v1, const Resource& v2) = delete;
861 inline bool same(const char* v1, const Variant& v2) = delete;
863 inline bool equal(const char* v1, bool v2)= delete;
864 inline bool equal(const char* v1, int v2)= delete;
865 inline bool equal(const char* v1, int64_t v2)= delete;
866 inline bool equal(const char* v1, double v2)= delete;
867 inline bool equal(const char* v1, const StringData *v2)= delete;
868 inline bool equal(const char* v1, const String& v2)= delete;
869 inline bool equal(const char* v1, const char* v2)= delete;
870 inline bool equal(const char* v1, const Array& v2)= delete;
871 inline bool equal(const char* v1, const Object& v2)= delete;
872 inline bool equal(const char* v1, const Resource& v2)= delete;
873 inline bool equal(const char* v1, const Variant& v2)= delete;
875 inline bool less(const char* v1, bool v2) = delete;
876 inline bool less(const char* v1, int v2) = delete;
877 inline bool less(const char* v1, int64_t v2) = delete;
878 inline bool less(const char* v1, double v2) = delete;
879 inline bool less(const char* v1, const StringData *v2) = delete;
880 inline bool less(const char* v1, const String& v2) = delete;
881 inline bool less(const char* v1, const char* v2) = delete;
882 inline bool less(const char* v1, const Array& v2) = delete;
883 inline bool less(const char* v1, const Object& v2) = delete;
884 inline bool less(const char* v1, const Resource& v2) = delete;
885 inline bool less(const char* v1, const Variant& v2) = delete;
887 inline bool more(const char* v1, bool v2) = delete;
888 inline bool more(const char* v1, int v2) = delete;
889 inline bool more(const char* v1, int64_t v2) = delete;
890 inline bool more(const char* v1, double v2) = delete;
891 inline bool more(const char* v1, const StringData *v2) = delete;
892 inline bool more(const char* v1, const String& v2) = delete;
893 inline bool more(const char* v1, const char* v2) = delete;
894 inline bool more(const char* v1, const Array& v2) = delete;
895 inline bool more(const char* v1, const Object& v2) = delete;
896 inline bool more(const char* v1, const Resource& v2) = delete;
897 inline bool more(const char* v1, const Variant& v2) = delete;
899 ///////////////////////////////////////////////////////////////////////////////
900 // Array
902 inline bool same(const Array& v1, bool v2) { return same(v2, v1); }
903 inline bool same(const Array& v1, int v2) { return same(v2, v1); }
904 inline bool same(const Array& v1, int64_t v2) { return same(v2, v1); }
905 inline bool same(const Array& v1, double v2) { return same(v2, v1); }
906 inline bool same(const Array& v1, const StringData *v2) { return same(v2, v1); }
907 inline bool same(const Array& v1, const String& v2) { return same(v2, v1); }
908 inline bool same(const Array& v1, const char* v2) = delete;
909 inline bool same(const Array& v1, const Array& v2) { return v1.same(v2); }
910 inline bool same(const Array& v1, const Object& v2) { return v1.same(v2); }
911 inline bool same(const Array& /*v1*/, const Resource& /*v2*/) {
912 return false;
914 inline bool same(const Array& v1, const Variant& v2) { return same(v2, v1); }
916 inline bool equal(const Array& v1, bool v2) { return equal(v2, v1); }
917 inline bool equal(const Array& v1, int v2) { return equal(v2, v1); }
918 inline bool equal(const Array& v1, int64_t v2) { return equal(v2, v1); }
919 inline bool equal(const Array& v1, double v2) { return equal(v2, v1); }
920 inline bool equal(const Array& v1, const StringData *v2) {
921 return equal(v2, v1);
923 inline bool equal(const Array& v1, const String& v2) { return equal(v2, v1); }
924 inline bool equal(const Array& v1, const char* v2) = delete;
925 inline bool equal(const Array& v1, const Array& v2) { return v1.equal(v2); }
926 inline bool equal(const Array& v1, const Object& v2) { return v1.equal(v2); }
927 inline bool equal(const Array& /*v1*/, const Resource& /*v2*/) {
928 return false;
930 inline bool equal(const Array& v1, const Variant& v2) { return equal(v2, v1); }
932 inline bool less(const Array& v1, bool v2) { return more(v2, v1); }
933 inline bool less(const Array& v1, int v2) { return more(v2, v1); }
934 inline bool less(const Array& v1, int64_t v2) { return more(v2, v1); }
935 inline bool less(const Array& v1, double v2) { return more(v2, v1); }
936 inline bool less(const Array& v1, const StringData *v2) { return more(v2, v1); }
937 inline bool less(const Array& v1, const String& v2) { return more(v2, v1); }
938 inline bool less(const Array& v1, const char* v2) = delete;
939 inline bool less(const Array& v1, const Array& v2) { return v1.less(v2); }
940 inline bool less(const Array& v1, const Object& v2) { return v1.less(v2); }
941 inline bool less(const Array& v1, const Resource& /*v2*/) {
942 if (v1.isPHPArray()) detail::hackArrCompatCheck(v1);
943 return false;
945 inline bool less(const Array& v1, const Variant& v2) { return v1.less(v2); }
947 inline bool more(const Array& v1, bool v2) { return less(v2, v1); }
948 inline bool more(const Array& v1, int v2) { return less(v2, v1); }
949 inline bool more(const Array& v1, int64_t v2) { return less(v2, v1); }
950 inline bool more(const Array& v1, double v2) { return less(v2, v1); }
951 inline bool more(const Array& v1, const StringData *v2) { return less(v2, v1); }
952 inline bool more(const Array& v1, const String& v2) { return less(v2, v1); }
953 inline bool more(const Array& v1, const char* v2) = delete;
954 inline bool more(const Array& v1, const Array& v2) { return v1.more(v2); }
955 inline bool more(const Array& v1, const Object& v2) { return v1.more(v2); }
956 inline bool more(const Array& v1, const Resource& /*v2*/) {
957 if (v1.isPHPArray()) detail::hackArrCompatCheck(v1);
958 return true;
960 inline bool more(const Array& v1, const Variant& v2) { return v1.more(v2); }
962 ///////////////////////////////////////////////////////////////////////////////
963 // Object
965 inline bool same(const Object& v1, bool v2) { return same(v2, v1); }
966 inline bool same(const Object& v1, int v2) { return same(v2, v1); }
967 inline bool same(const Object& v1, int64_t v2) { return same(v2, v1); }
968 inline bool same(const Object& v1, double v2) { return same(v2, v1); }
969 inline bool same(const Object& v1, const StringData *v2) {
970 return same(v2, v1);
972 inline bool same(const Object& v1, const String& v2) { return same(v2, v1); }
973 inline bool same(const Object& v1, const char* v2) = delete;
974 inline bool same(const Object& v1, const Array& v2) { return same(v2, v1); }
975 inline bool same(const Object& v1, const Object& v2) { return v1.same(v2); }
976 inline bool same(const Object& /*v1*/, const Resource& /*v2*/) {
977 return false;
979 inline bool same(const Object& v1, const Variant& v2) { return same(v2, v1); }
981 inline bool equal(const Object& v1, bool v2) { return equal(v2, v1); }
982 inline bool equal(const Object& v1, int v2) { return equal(v2, v1); }
983 inline bool equal(const Object& v1, int64_t v2) { return equal(v2, v1); }
984 inline bool equal(const Object& v1, double v2) { return equal(v2, v1); }
985 inline bool equal(const Object& v1, const StringData *v2) {
986 return equal(v2, v1);
988 inline bool equal(const Object& v1, const String& v2) { return equal(v2, v1); }
989 inline bool equal(const Object& v1, const char* v2) = delete;
990 inline bool equal(const Object& v1, const Array& v2) { return equal(v2, v1); }
991 inline bool equal(const Object& v1, const Object& v2) { return v1.equal(v2); }
992 inline bool equal(const Object& /*v1*/, const Resource& /*v2*/) {
993 return false;
995 inline bool equal(const Object& v1, const Variant& v2) { return equal(v2, v1); }
997 inline bool less(const Object& v1, bool v2) { return more(v2, v1); }
998 inline bool less(const Object& v1, int v2) { return more(v2, v1); }
999 inline bool less(const Object& v1, int64_t v2) { return more(v2, v1); }
1000 inline bool less(const Object& v1, double v2) { return more(v2, v1); }
1001 inline bool less(const Object& v1, const StringData *v2) {
1002 return more(v2, v1);
1004 inline bool less(const Object& v1, const String& v2) { return more(v2, v1); }
1005 inline bool less(const Object& v1, const char* v2) = delete;
1006 inline bool less(const Object& v1, const Array& v2) { return more(v2, v1); }
1007 inline bool less(const Object& v1, const Object& v2) { return v1.less(v2); }
1008 inline bool less(const Object& /*v1*/, const Resource& /*v2*/) {
1009 return false;
1011 inline bool less(const Object& v1, const Variant& v2) {
1012 if (v2.isObject()) return v1.less(v2.toObject());
1013 return more(v2, v1);
1016 inline bool more(const Object& v1, bool v2) { return less(v2, v1); }
1017 inline bool more(const Object& v1, int v2) { return less(v2, v1); }
1018 inline bool more(const Object& v1, int64_t v2) { return less(v2, v1); }
1019 inline bool more(const Object& v1, double v2) { return less(v2, v1); }
1020 inline bool more(const Object& v1, const StringData *v2) {
1021 return less(v2, v1);
1023 inline bool more(const Object& v1, const String& v2) { return less(v2, v1); }
1024 inline bool more(const Object& v1, const char* v2) = delete;
1025 inline bool more(const Object& v1, const Array& v2) { return less(v2, v1); }
1026 inline bool more(const Object& v1, const Object& v2) { return v1.more(v2); }
1027 inline bool more(const Object& /*v1*/, const Resource& /*v2*/) {
1028 return false;
1030 inline bool more(const Object& v1, const Variant& v2) {
1031 if (v2.isObject()) return v1.more(v2.toObject());
1032 return less(v2, v1);
1035 ///////////////////////////////////////////////////////////////////////////////
1036 // ObjectData*
1038 inline bool equal(const ObjectData* v1, const ObjectData* v2) {
1039 assert(v1);
1040 assert(v2);
1041 return v1->equal(*v2);
1044 inline bool nequal(const ObjectData* v1, const ObjectData* v2) {
1045 return !equal(v1, v2);
1048 inline bool less(const ObjectData* v1, const ObjectData* v2) {
1049 assert(v1);
1050 assert(v2);
1051 return v1->less(*v2);
1054 inline bool lessEqual(const ObjectData* v1, const ObjectData* v2) {
1055 return less(v1, v2) || equal(v1, v2);
1058 inline bool more(const ObjectData* v1, const ObjectData* v2) {
1059 assert(v1);
1060 assert(v2);
1061 return v1->more(*v2);
1064 inline bool moreEqual(const ObjectData* v1, const ObjectData* v2) {
1065 return more(v1, v2) || equal(v1, v2);
1068 inline int64_t compare(const ObjectData* v1, const ObjectData* v2) {
1069 assert(v1);
1070 assert(v2);
1071 return v1->compare(*v2);
1074 ///////////////////////////////////////////////////////////////////////////////
1075 // Resource
1077 inline bool same(const Resource& v1, bool v2) { return same(v2, v1); }
1078 inline bool same(const Resource& v1, int v2) { return same(v2, v1); }
1079 inline bool same(const Resource& v1, int64_t v2) { return same(v2, v1); }
1080 inline bool same(const Resource& v1, double v2) { return same(v2, v1); }
1081 inline bool same(const Resource& v1, const StringData *v2) {
1082 return same(v2, v1);
1084 inline bool same(const Resource& v1, const String& v2) { return same(v2, v1); }
1085 inline bool same(const Resource& v1, const char* v2) = delete;
1086 inline bool same(const Resource& /*v1*/, const Array& /*v2*/) {
1087 return false;
1089 inline bool same(const Resource& /*v1*/, const Object& /*v2*/) {
1090 return false;
1092 inline bool same(const Resource& v1, const Resource& v2) { return v1.same(v2); }
1093 inline bool same(const Resource& v1, const Variant& v2) { return same(v2, v1); }
1095 inline bool equal(const Resource& v1, bool v2) { return equal(v2, v1); }
1096 inline bool equal(const Resource& v1, int v2) { return equal(v2, v1); }
1097 inline bool equal(const Resource& v1, int64_t v2) { return equal(v2, v1); }
1098 inline bool equal(const Resource& v1, double v2) { return equal(v2, v1); }
1099 inline bool equal(const Resource& v1, const StringData *v2) {
1100 return equal(v2, v1);
1102 inline bool equal(const Resource& v1, const String& v2) {
1103 return equal(v2, v1);
1105 inline bool equal(const Resource& v1, const char* v2) = delete;
1106 inline bool equal(const Resource& /*v1*/, const Array& /*v2*/) {
1107 return false;
1109 inline bool equal(const Resource& /*v1*/, const Object& /*v2*/) {
1110 return false;
1112 inline bool equal(const Resource& v1, const Resource& v2) {
1113 return v1.equal(v2);
1115 inline bool equal(const Resource& v1, const Variant& v2) {
1116 return equal(v2, v1);
1119 inline bool less(const Resource& v1, bool v2) { return more(v2, v1); }
1120 inline bool less(const Resource& v1, int v2) { return more(v2, v1); }
1121 inline bool less(const Resource& v1, int64_t v2) { return more(v2, v1); }
1122 inline bool less(const Resource& v1, double v2) { return more(v2, v1); }
1123 inline bool less(const Resource& v1, const StringData *v2) {
1124 return more(v2, v1);
1126 inline bool less(const Resource& v1, const String& v2) { return more(v2, v1); }
1127 inline bool less(const Resource& v1, const char* v2) = delete;
1128 inline bool less(const Resource& /*v1*/, const Array& v2) {
1129 if (LIKELY(v2.isPHPArray())) {
1130 detail::hackArrCompatCheck(v2);
1131 return true;
1133 if (v2.isVecArray()) throw_vec_compare_exception();
1134 if (v2.isDict()) throw_dict_compare_exception();
1135 assert(v2.isKeyset());
1136 throw_keyset_compare_exception();
1138 inline bool less(const Resource& /*v1*/, const Object& /*v2*/) {
1139 return false;
1141 inline bool less(const Resource& v1, const Resource& v2) { return v1.less(v2); }
1142 inline bool less(const Resource& v1, const Variant& v2) { return more(v2, v1); }
1144 inline bool more(const Resource& v1, bool v2) { return less(v2, v1); }
1145 inline bool more(const Resource& v1, int v2) { return less(v2, v1); }
1146 inline bool more(const Resource& v1, int64_t v2) { return less(v2, v1); }
1147 inline bool more(const Resource& v1, double v2) { return less(v2, v1); }
1148 inline bool more(const Resource& v1, const StringData *v2) {
1149 return less(v2, v1);
1151 inline bool more(const Resource& v1, const String& v2) { return less(v2, v1); }
1152 inline bool more(const Resource& v1, const char* v2) = delete;
1153 inline bool more(const Resource& /*v1*/, const Array& v2) {
1154 if (LIKELY(v2.isPHPArray())) {
1155 detail::hackArrCompatCheck(v2);
1156 return false;
1158 if (v2.isVecArray()) throw_vec_compare_exception();
1159 if (v2.isDict()) throw_dict_compare_exception();
1160 assert(v2.isKeyset());
1161 throw_keyset_compare_exception();
1163 inline bool more(const Resource& /*v1*/, const Object& /*v2*/) {
1164 return false;
1166 inline bool more(const Resource& v1, const Resource& v2) { return v1.more(v2); }
1167 inline bool more(const Resource& v1, const Variant& v2) { return less(v2, v1); }
1169 ///////////////////////////////////////////////////////////////////////////////
1170 // ResourceHdr*
1172 inline bool equal(const ResourceHdr* v1, const ResourceHdr* v2) {
1173 return v1 == v2;
1176 inline bool nequal(const ResourceHdr* v1, const ResourceHdr* v2) {
1177 return v1 != v2;
1180 inline bool less(const ResourceHdr* v1, const ResourceHdr* v2) {
1181 assert(v1);
1182 assert(v2);
1183 return v1->data()->o_toInt64() < v2->data()->o_toInt64();
1186 inline bool lessEqual(const ResourceHdr* v1, const ResourceHdr* v2) {
1187 return less(v1, v2) || equal(v1, v2);
1190 inline bool more(const ResourceHdr* v1, const ResourceHdr* v2) {
1191 assert(v1);
1192 assert(v2);
1193 return v1->data()->o_toInt64() > v2->data()->o_toInt64();
1196 inline bool moreEqual(const ResourceHdr* v1, const ResourceHdr* v2) {
1197 return more(v1, v2) || equal(v1, v2);
1200 inline int64_t compare(const ResourceHdr* v1, const ResourceHdr* v2) {
1201 assert(v1);
1202 assert(v1);
1203 auto id1 = v1->data()->o_toInt64();
1204 auto id2 = v2->data()->o_toInt64();
1205 return (id1 < id2) ? -1 : ((id1 > id2) ? 1 : 0);
1208 ///////////////////////////////////////////////////////////////////////////////
1211 #endif // incl_HPHP_COMPARISONS_H_