)]}'
{
  "commit": "068dd892acb22dc21d9e17691266c8499ba2d6c8",
  "tree": "b5a796b4818ae84ab7da235845b21f46fd6cfb91",
  "parents": [
    "7ecf26c4148fd141741775347af89aa9c00a80bc"
  ],
  "author": {
    "name": "Chris Bracken",
    "email": "cbracken@google.com",
    "time": "Mon May 11 14:46:46 2026 +0900"
  },
  "committer": {
    "name": "gn-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "email": "gn-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "time": "Mon May 11 01:53:49 2026 -0700"
  },
  "message": "Fix PointerSet and BuilderRecordMap iterators under C++23\n\nAdds explicit operator++() and operator++(int) overrides in\nPointerSet::const_iterator, BuilderRecordMap::const_iterator, and the\nunit test TestHashTable::const_iterator to satisfy weakly_incrementable\nrequirements. I\u0027ve also updated documentation and sample custom iterator\nimplementations in src/gn/hash_table_base.h.\n\nThis fixes a compilation error that started with the update to C++23 in\n88604adbcec2101f25b2e3ebd7f39b38163a6a33, which triggers the following\nerror (in my case: macOS 26.4.1 using Xcode 26.2) indicating that\nPointerSet\u003cconst Target\u003e::const_iterator fails to satisfy one of the\nrequirements of std::weakly_incrementable:\n\n    ../src/gn/json_project_writer.cc:80:14: note: in instantiation of function template specialization \u0027std::vector\u003cconst Target *\u003e::assign\u003cPointerSet\u003cconst Target\u003e::const_iterator, 0\u003e\u0027 requested here\n       80 |     targets-\u003eassign(target_set.begin(), target_set.end());\n          |              ^\n    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__algorithm/ranges_copy_n.h:64:3: note: candidate template ignored: constraints not satisfied [with _Ip \u003d __libcpp_remove_reference_t\u003cconst_iterator \u0026\u003e, _Op \u003d pointer]\n       64 |   operator()(_Ip __first, iter_difference_t\u003c_Ip\u003e __n, _Op __result) const {\n          |   ^\n    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__algorithm/ranges_copy_n.h:61:13: note: because \u0027PointerSet\u003cconst Target\u003e::const_iterator\u0027 does not satisfy \u0027input_iterator\u0027\n       61 |   template \u003cinput_iterator _Ip, weakly_incrementable _Op\u003e\n          |             ^\n    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__iterator/concepts.h:195:26: note: because \u0027PointerSet\u003cconst Target\u003e::const_iterator\u0027 does not satisfy \u0027input_or_output_iterator\u0027\n      195 | concept input_iterator \u003d input_or_output_iterator\u003c_Ip\u003e \u0026\u0026 indirectly_readable\u003c_Ip\u003e \u0026\u0026 requires {\n          |                          ^\n    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__iterator/concepts.h:140:6: note: because \u0027PointerSet\u003cconst Target\u003e::const_iterator\u0027 does not satisfy \u0027weakly_incrementable\u0027\n      140 | } \u0026\u0026 weakly_incrementable\u003c_Ip\u003e;\n          |      ^\n    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__iterator/concepts.h:126:20: note: because type constraint \u0027same_as\u003cHashTableBase\u003cPointerSetNode\u003e::NodeIterator \u0026, PointerSet\u003cconst Target\u003e::const_iterator \u0026\u003e\u0027 was not satisfied:\n      126 |       { ++__i } -\u003e same_as\u003c_Ip\u0026\u003e; // not required to be equality-preserving\n          |                    ^\n\nIt looks like the PointerSet\u003cT\u003e template class was originally introduced\nin commit 0e7ed6358c5bdf4e2448f735d5d6cfa3b58af06a. Its custom\nconst_iterator subclasses NodeIterator directly without overriding\noperator++ and operator++(int).\n\nSpecifically, when json_project_writer.cc calls\ntargets-\u003eassign(target_set.begin(), target_set.end()),\nstd::vector::asign() requires that its arguments staisfy\nstd::input_iterator, which in turn requires that it satisfy\nstd::input_or_output_iterator, which in turn requires\nstd::weakly_incrementable.\n\nLooking at the requirements of std::weakly_incrementable, there are four\ncriteria (https://en.cppreference.com/cpp/iterator/weakly_incrementable):\n\n  * std::movable\u003cI\u003e: must be moveable.\n  * std::iter_difference\u003cI\u003e: must have a related signed integer type\n    (such as std::ptrdiff_t) that represents the difference between two\n    iterators.\n  * { ++i } -\u003e std::same_as\u003cI\u0026\u003e: the pre-increment operator must exist\n    and its return type must be I\u0026. This is what we violated.\n  * i++: The post-increment operator must exist. There\u0027s no requirement\n    on return type, so no issue here.\n\nBecause PointerSet::const_iterator inherited operator++ from\nNodeIterator, pre-incrementing returned NodeIterator\u0026 instead of\nconst_iterator\u0026, it fails the concept check.\n\nChange-Id: I425c4e153d7a087beaf37b10a2e519184b4801c3\nReviewed-on: https://gn-review.googlesource.com/c/gn/+/22660\nReviewed-by: Takuto Ikuta \u003ctikuta@google.com\u003e\nReviewed-by: David Turner \u003cdigit@google.com\u003e\nCommit-Queue: David Turner \u003cdigit@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "77f0695e98e48e933ca72a6552cb583fab08b475",
      "old_mode": 33188,
      "old_path": "src/gn/builder_record_map.h",
      "new_id": "41c6565bcfd74f339ad96795ee28670403ebb43b",
      "new_mode": 33188,
      "new_path": "src/gn/builder_record_map.h"
    },
    {
      "type": "modify",
      "old_id": "7e5b34ede6525e4fc7780e3ada4749065613146a",
      "old_mode": 33188,
      "old_path": "src/gn/hash_table_base.h",
      "new_id": "cfe194deb447db9c3406aa65d7dacb31bf655d96",
      "new_mode": 33188,
      "new_path": "src/gn/hash_table_base.h"
    },
    {
      "type": "modify",
      "old_id": "7acbfbe344c9e1230081c594ea9d157c6beffe70",
      "old_mode": 33188,
      "old_path": "src/gn/hash_table_base_unittest.cc",
      "new_id": "17eaf98b19a238f2fe18d615e7b3ef114ec6081d",
      "new_mode": 33188,
      "new_path": "src/gn/hash_table_base_unittest.cc"
    },
    {
      "type": "modify",
      "old_id": "6a4ec62a650306f644036a3c4614b41f76ec4642",
      "old_mode": 33188,
      "old_path": "src/gn/pointer_set.h",
      "new_id": "4c4da2fac8e141c7da69be802b854016a4030245",
      "new_mode": 33188,
      "new_path": "src/gn/pointer_set.h"
    }
  ]
}
