)]}'
{
  "commit": "b5f440780b424b9ce68d0dbf32b83e854207ea25",
  "tree": "8788a0a8289fc682b17b878704afaa1b3f3a7190",
  "parents": [
    "5d154d1eac1044b01f31b6422b8a9551e10bb1e4"
  ],
  "author": {
    "name": "Marcin Kowalczyk",
    "email": "qrczak@google.com",
    "time": "Thu Apr 16 12:25:50 2026 +0200"
  },
  "committer": {
    "name": "Marcin Kowalczyk",
    "email": "qrczak@google.com",
    "time": "Fri Apr 17 11:50:28 2026 +0200"
  },
  "message": "Fix `With{Equal,Compare}` in C++17 for corner cases:\n\n1. Heterogeneous secondary comparisons (`!\u003d`, `\u003c`, `\u003e`, `\u003c\u003d`, and `\u003e\u003d`)\n   are not defined if the other type is also implemented using `WithEqual`\n   or `WithCompare`.\n\n2. Heterogeneous primary comparisons with swapped parameters (`\u003d\u003d` and\n   `RIEGELI_COMPARE`) are added only for types explicitly specified by\n   additional template parameters of `WithEqual` and `WithCompare`.\n\nThis avoids ambiguous overloads and cyclic template instantiations:\n\n1. If both parameter types consider swapping the parameters, but the types are\n   not comparable, then each definition is rewritten from the other one, and\n   their SFINAE constraints depend on each other.\n\n   This does not happen only if the code tries to compare incomparable values.\n   Due to how ADL works, a call to an unqualified function name with an argument\n   of type `A\u003cT\u003e` brings not only functions related to `A`, but also functions\n   related to `T`. The argument of type `A\u003cT\u003e` will not match the parameter\n   of type `T`, but the function template is instantiated earlier, trying to\n   compare `T` against `A\u003cT\u003e`.\n\n2. Automatic parameter swapping could only generate a constrained template\n   rather than overloads with concrete parameter types.\n\n   That converts parameters in the callee rather than in the caller, which leads\n   to different overload resolution.\n\n   That would create ambiguities in cases like `CompactString \u003d\u003d Chain`.\n   The parameters are not swapped because both types use `WithEqual`.\n   Intended `Chain \u003d\u003d absl::string_view` is not found because it requires\n   parameter swapping after all, since the converted parameter does not use\n   `WithEqual`.\n\nPiperOrigin-RevId: 900626664\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "43dd57ea65dc5ef3f79b9e77c5c7c4633e483711",
      "old_mode": 33188,
      "old_path": "riegeli/base/any.h",
      "new_id": "81c397be66abacb34efde981b9e970a339f1e83e",
      "new_mode": 33188,
      "new_path": "riegeli/base/any.h"
    },
    {
      "type": "modify",
      "old_id": "8ce45647cdf7580b1b706fda40a43be7e8b1c2db",
      "old_mode": 33188,
      "old_path": "riegeli/base/c_string_ref.h",
      "new_id": "7d5a60cd143f11c41b33a750a3bffec905c7ce2c",
      "new_mode": 33188,
      "new_path": "riegeli/base/c_string_ref.h"
    },
    {
      "type": "modify",
      "old_id": "ffcbcd21d1d03d9e8d4af5c3e083dc2f61ea979e",
      "old_mode": 33188,
      "old_path": "riegeli/base/chain_base.h",
      "new_id": "e957426398cf3dc6256da185598d2508c445e7f4",
      "new_mode": 33188,
      "new_path": "riegeli/base/chain_base.h"
    },
    {
      "type": "modify",
      "old_id": "66542c82457c04430794ba3cc01dbba4ee65d90f",
      "old_mode": 33188,
      "old_path": "riegeli/base/compact_string.h",
      "new_id": "a212c978145c453e7cb830c5ee612627fc53197a",
      "new_mode": 33188,
      "new_path": "riegeli/base/compact_string.h"
    },
    {
      "type": "modify",
      "old_id": "52eb4560fd1f312cf8e99d74d727fd4346928e92",
      "old_mode": 33188,
      "old_path": "riegeli/base/compare.h",
      "new_id": "a23e9e227079c5a9af6aad34ced3e36940257ef2",
      "new_mode": 33188,
      "new_path": "riegeli/base/compare.h"
    },
    {
      "type": "modify",
      "old_id": "9ecb4aa3ca3604f863a2c57acd85af0807de7796",
      "old_mode": 33188,
      "old_path": "riegeli/base/dependency.h",
      "new_id": "23b000820be025e5fcc78a9a8ca0208baf192953",
      "new_mode": 33188,
      "new_path": "riegeli/base/dependency.h"
    },
    {
      "type": "modify",
      "old_id": "be5781a5fa998c42b0b6bbd4e0b0d0ecd7d5b502",
      "old_mode": 33188,
      "old_path": "riegeli/base/hybrid_direct_internal.h",
      "new_id": "85f0beaaa85619b60deb28fc230cc8f285e4e1b9",
      "new_mode": 33188,
      "new_path": "riegeli/base/hybrid_direct_internal.h"
    },
    {
      "type": "modify",
      "old_id": "7e339b40c3926e448526c78920c31792c2ef5f91",
      "old_mode": 33188,
      "old_path": "riegeli/base/intrusive_shared_ptr.h",
      "new_id": "6c217936bd9263630d1bdaaf94f067738408575c",
      "new_mode": 33188,
      "new_path": "riegeli/base/intrusive_shared_ptr.h"
    },
    {
      "type": "modify",
      "old_id": "506df7f24bfeccd97fdc7e90999f3f7e85b4beee",
      "old_mode": 33188,
      "old_path": "riegeli/base/optional_compact_string.h",
      "new_id": "02adc362677ff6b898255b0e54c7eddf9accc536",
      "new_mode": 33188,
      "new_path": "riegeli/base/optional_compact_string.h"
    },
    {
      "type": "modify",
      "old_id": "b7c0ac75b7f6fe4c0caec24da81962b54b288864",
      "old_mode": 33188,
      "old_path": "riegeli/base/shared_ptr.h",
      "new_id": "0fbc7912932fc8c9e5e5e821ad5a148bd4edc8d4",
      "new_mode": 33188,
      "new_path": "riegeli/base/shared_ptr.h"
    },
    {
      "type": "modify",
      "old_id": "910b3e68a03fb251f6d095d9c7d2ed9ab73f6765",
      "old_mode": 33188,
      "old_path": "riegeli/bytes/cfile_handle.h",
      "new_id": "71999c0e31d06765b1807d275d6ea3469fe28f56",
      "new_mode": 33188,
      "new_path": "riegeli/bytes/cfile_handle.h"
    },
    {
      "type": "modify",
      "old_id": "dab232a01bcd4d9edd8b7cfc1734ee88eed73189",
      "old_mode": 33188,
      "old_path": "riegeli/bytes/fd_handle.h",
      "new_id": "a8fbf6852936e2ff9dce9896399de47d8bdc673f",
      "new_mode": 33188,
      "new_path": "riegeli/bytes/fd_handle.h"
    },
    {
      "type": "modify",
      "old_id": "0b68f1f6c02d0b39e551a3df802dceae176414b9",
      "old_mode": 33188,
      "old_path": "riegeli/containers/linear_sorted_string_set.h",
      "new_id": "fe8715be5dc01e483024d5974aabd748f1738735",
      "new_mode": 33188,
      "new_path": "riegeli/containers/linear_sorted_string_set.h"
    },
    {
      "type": "modify",
      "old_id": "bb9e9b9cec20fea66aa447070e93e92bdccf3d66",
      "old_mode": 33188,
      "old_path": "riegeli/digests/digester_handle.h",
      "new_id": "91763a2acf75792ca42d0a896ea1b2a68d917122",
      "new_mode": 33188,
      "new_path": "riegeli/digests/digester_handle.h"
    }
  ]
}
