mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 15:10:12 +01:00
Introduce FindIfOrNull() FindIfOrNone() and Contains() (#5322)
`FindIfOrNull` returns a pointer to the element in the range if it's found, and nullptr otherwise. `FindIfOrNone` returns a copy of the element in the range if it's found, and `T::None` (for a range of elements of type `T`) otherwise. `Contains` returns a bool indicating whether the element in the range is found. These functions replace `llvm::find()` and `llvm::find_if()` when you want a single answer back instead of an iterator. This avoids the need to check against `end()`, allowing the return condition to be tested as a standard bool. We replace uses of `find()` and `find_if()` that did not require an iterator with these new helpers. Note that the return type of `FindIfOrNull` is a pointer since we can not write `optional<T&>`, which must be tested for null. If the null check is omitted, UB occurs and the resulting code may end up with an incorrect pointer (https://crbug.com/40153300) into the range (or elsewhere), rather than a null dereference. And this would be very confusing to debug. Hopefully debug builds and sanitizers keep this from being an issue we sink a bunch of time into debugging.
This commit is contained in:
@@ -43,6 +43,7 @@ cc_library(
|
||||
"//common:check",
|
||||
"//common:error",
|
||||
"//common:exe_path",
|
||||
"//common:find",
|
||||
"//common:init_llvm",
|
||||
"//common:ostream",
|
||||
"//common:raw_string_ostream",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "common/check.h"
|
||||
#include "common/error.h"
|
||||
#include "common/find.h"
|
||||
#include "common/raw_string_ostream.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/JSON.h"
|
||||
@@ -132,14 +133,13 @@ static auto AutoFillDidOpenParams(llvm::json::Object* params,
|
||||
}
|
||||
|
||||
CARBON_ASSIGN_OR_RETURN(auto file_path, ExtractFilePathFromUri(*uri));
|
||||
const auto* split_it =
|
||||
llvm::find_if(splits, [&](const TestFile::Split& split) {
|
||||
return split.filename == file_path;
|
||||
});
|
||||
if (split_it == splits.end()) {
|
||||
const auto* split = FindIfOrNull(splits, [&](const TestFile::Split& split) {
|
||||
return split.filename == file_path;
|
||||
});
|
||||
if (!split) {
|
||||
return ErrorBuilder() << "No split found for uri: " << *uri;
|
||||
}
|
||||
attr_it->second = split_it->content;
|
||||
attr_it->second = split->content;
|
||||
return Success();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user