[ADT] Add a fallible_iterator wrapper.
authorLang Hames <lhames@gmail.com>
Tue, 5 Feb 2019 23:17:11 +0000 (23:17 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 5 Feb 2019 23:17:11 +0000 (23:17 +0000)
commit3e040e05f89c058bb6e6a88c4e9ffccf1185b084
tree499687725ced8471cb5893b8d57f80f937c60165
parent7b7a4ef3d33d85efa6b27a51919fe7ef956be6ee
[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
llvm/docs/ProgrammersManual.rst
llvm/include/llvm/ADT/fallible_iterator.h [new file with mode: 0644]
llvm/include/llvm/Object/Archive.h
llvm/lib/Object/Archive.cpp
llvm/tools/llvm-objcopy/llvm-objcopy.cpp
llvm/unittests/ADT/CMakeLists.txt
llvm/unittests/ADT/FallibleIteratorTest.cpp [new file with mode: 0644]