| 1 | #ifndef MYCPP_COMPARATORS_H
 | 
| 2 | #define MYCPP_COMPARATORS_H
 | 
| 3 | 
 | 
| 4 | #include <string.h>  // memcmp
 | 
| 5 | 
 | 
| 6 | #include <algorithm>  // std::min()
 | 
| 7 | 
 | 
| 8 | #include "mycpp/gc_mops.h"  // mops::BigInt
 | 
| 9 | #include "mycpp/gc_str.h"   // len()
 | 
| 10 | 
 | 
| 11 | template <typename L, typename R>
 | 
| 12 | class Tuple2;
 | 
| 13 | 
 | 
| 14 | bool str_equals(BigStr* left, BigStr* right);
 | 
| 15 | bool maybe_str_equals(BigStr* left, BigStr* right);
 | 
| 16 | 
 | 
| 17 | bool items_equal(BigStr* left, BigStr* right);
 | 
| 18 | bool keys_equal(BigStr* left, BigStr* right);
 | 
| 19 | 
 | 
| 20 | // No List<T> comparison by pointer
 | 
| 21 | inline bool items_equal(void* left, void* right) {
 | 
| 22 |   assert(0);
 | 
| 23 | }
 | 
| 24 | 
 | 
| 25 | // e.g. for Dict<Token*, int>, use object IDENTITY, not value
 | 
| 26 | inline bool keys_equal(void* left, void* right) {
 | 
| 27 |   return left == right;
 | 
| 28 | }
 | 
| 29 | 
 | 
| 30 | inline bool items_equal(int left, int right) {
 | 
| 31 |   return left == right;
 | 
| 32 | }
 | 
| 33 | 
 | 
| 34 | inline bool keys_equal(int left, int right) {
 | 
| 35 |   return items_equal(left, right);
 | 
| 36 | }
 | 
| 37 | 
 | 
| 38 | inline bool items_equal(mops::BigInt left, mops::BigInt right) {
 | 
| 39 |   return left == right;
 | 
| 40 | }
 | 
| 41 | 
 | 
| 42 | inline bool keys_equal(mops::BigInt left, mops::BigInt right) {
 | 
| 43 |   return items_equal(left, right);
 | 
| 44 | }
 | 
| 45 | 
 | 
| 46 | bool items_equal(Tuple2<int, int>* t1, Tuple2<int, int>* t2);
 | 
| 47 | bool keys_equal(Tuple2<int, int>* t1, Tuple2<int, int>* t2);
 | 
| 48 | 
 | 
| 49 | bool items_equal(Tuple2<BigStr*, int>* t1, Tuple2<BigStr*, int>* t2);
 | 
| 50 | bool keys_equal(Tuple2<BigStr*, int>* t1, Tuple2<BigStr*, int>* t2);
 | 
| 51 | 
 | 
| 52 | namespace id_kind_asdl {
 | 
| 53 | enum class Kind;
 | 
| 54 | };
 | 
| 55 | 
 | 
| 56 | // Defined in cpp/translation_stubs.h
 | 
| 57 | bool items_equal(id_kind_asdl::Kind left, id_kind_asdl::Kind right);
 | 
| 58 | 
 | 
| 59 | inline int int_cmp(int a, int b) {
 | 
| 60 |   if (a == b) {
 | 
| 61 |     return 0;
 | 
| 62 |   }
 | 
| 63 |   return a < b ? -1 : 1;
 | 
| 64 | }
 | 
| 65 | 
 | 
| 66 | // mylib::str_cmp is in this common header to avoid gc_list.h -> gc_mylib.h
 | 
| 67 | // dependency
 | 
| 68 | //
 | 
| 69 | // It's also used for _cmp(BigStr*) in gc_list.
 | 
| 70 | namespace mylib {
 | 
| 71 | 
 | 
| 72 | // Used by [[ a > b ]] and so forth
 | 
| 73 | inline int str_cmp(BigStr* a, BigStr* b) {
 | 
| 74 |   int len_a = len(a);
 | 
| 75 |   int len_b = len(b);
 | 
| 76 | 
 | 
| 77 |   int min = std::min(len_a, len_b);
 | 
| 78 |   if (min == 0) {
 | 
| 79 |     return int_cmp(len_a, len_b);
 | 
| 80 |   }
 | 
| 81 |   int comp = memcmp(a->data_, b->data_, min);
 | 
| 82 |   if (comp == 0) {
 | 
| 83 |     return int_cmp(len_a, len_b);  // tiebreaker
 | 
| 84 |   }
 | 
| 85 |   return comp;
 | 
| 86 | }
 | 
| 87 | 
 | 
| 88 | }  // namespace mylib
 | 
| 89 | 
 | 
| 90 | #endif  // MYCPP_COMPARATORS_H
 |