summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2019-02-05 23:17:11 +0000
committerLang Hames <lhames@gmail.com>2019-02-05 23:17:11 +0000
commit3e040e05f89c058bb6e6a88c4e9ffccf1185b084 (patch)
tree499687725ced8471cb5893b8d57f80f937c60165 /llvm/lib/Object
parent7b7a4ef3d33d85efa6b27a51919fe7ef956be6ee (diff)
downloadbcm5719-llvm-3e040e05f89c058bb6e6a88c4e9ffccf1185b084.tar.gz
bcm5719-llvm-3e040e05f89c058bb6e6a88c4e9ffccf1185b084.zip
[ADT] Add a fallible_iterator wrapper.
A fallible iterator is one whose increment or decrement operations may fail. This would usually be supported by replacing the ++ and -- operators with methods that return error: class MyFallibleIterator { public: // ... Error inc(); Errro dec(); // ... }; The downside of this style is that it no longer conforms to the C++ iterator concept, and can not make use of standard algorithms and features such as range-based for loops. The fallible_iterator wrapper takes an iterator written in the style above and adapts it to (mostly) conform with the C++ iterator concept. It does this by providing standard ++ and -- operator implementations, returning any errors generated via a side channel (an Error reference passed into the wrapper at construction time), and immediately jumping the iterator to a known 'end' value upon error. It also marks the Error as checked any time an iterator is compared with a known end value and found to be inequal, allowing early exit from loops without redundant error checking*. Usage looks like: MyFallibleIterator I = ..., E = ...; Error Err = Error::success(); for (auto &Elem : make_fallible_range(I, E, Err)) { // Loop body is only entered when safe. // Early exits from loop body permitted without checking Err. if (SomeCondition) return; } if (Err) // Handle error. * Since failure causes a fallible iterator to jump to end, testing that a fallible iterator is not an end value implicitly verifies that the error is a success value, and so is equivalent to an error check. Reviewers: dblaikie, rupprecht Subscribers: mgorny, dexonsmith, kristina, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57618 llvm-svn: 353237
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r--llvm/lib/Object/Archive.cpp9
1 files changed, 4 insertions, 5 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp
index 3def30949fc..1d31feb714e 100644
--- a/llvm/lib/Object/Archive.cpp
+++ b/llvm/lib/Object/Archive.cpp
@@ -778,19 +778,18 @@ Archive::child_iterator Archive::child_begin(Error &Err,
return child_end();
if (SkipInternal)
- return child_iterator(Child(this, FirstRegularData,
- FirstRegularStartOfFile),
- &Err);
+ return child_iterator::itr(
+ Child(this, FirstRegularData, FirstRegularStartOfFile), Err);
const char *Loc = Data.getBufferStart() + strlen(Magic);
Child C(this, Loc, &Err);
if (Err)
return child_end();
- return child_iterator(C, &Err);
+ return child_iterator::itr(C, Err);
}
Archive::child_iterator Archive::child_end() const {
- return child_iterator(Child(nullptr, nullptr, nullptr), nullptr);
+ return child_iterator::end(Child(nullptr, nullptr, nullptr));
}
StringRef Archive::Symbol::getName() const {
OpenPOWER on IntegriCloud