Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
finally.hh
Go to the documentation of this file.
1#pragma once
3
4#include <utility>
5#include <cassert>
6#include <exception>
7
11template<typename Fn>
12class [[nodiscard("Finally values must be used")]] Finally
13{
14private:
15 Fn fun;
16 bool movedFrom = false;
17
18public:
19 Finally(Fn fun) : fun(std::move(fun)) { }
20 // Copying Finallys is definitely not a good idea and will cause them to be
21 // called twice.
22 Finally(Finally &other) = delete;
23 // NOTE: Move constructor can be nothrow if the callable type is itself nothrow
24 // move-constructible.
25 Finally(Finally && other) noexcept(std::is_nothrow_move_constructible_v<Fn>)
26 : fun(std::move(other.fun))
27 {
28 other.movedFrom = true;
29 }
30 ~Finally() noexcept(false)
31 {
32 try {
33 if (!movedFrom)
34 fun();
35 } catch (...) {
36 // finally may only throw an exception if exception handling is not already
37 // in progress. if handling *is* in progress we have to return cleanly here
38 // but are still prohibited from doing so since eating the exception would,
39 // in almost all cases, mess up error handling even more. the only good way
40 // to handle this is to abort entirely and leave a message, so we'll assert
41 // (and rethrow anyway, just as a defense against possible NASSERT builds.)
42 if (std::uncaught_exceptions()) {
43 assert(false &&
44 "Finally function threw an exception during exception handling. "
45 "this is not what you want, please use some other methods (like "
46 "std::promise or async) instead.");
47 }
48 throw;
49 }
50 }
51};
std::function< void(Sink &)> fun
Definition lexer.l:3485