Coverage Report

Created: 2025-07-23 06:45

/proc/self/cwd/cpp/htmlparser/defer.h
Line
Count
Source (jump to first uncovered line)
1
// Executes a block of code (lambda) after the function returns, or a block
2
// ends.
3
// Useful for multiple (and nested) returns inside a function.
4
//
5
// Usage:
6
// In the following example fd file descriptor is closed after MyFunction
7
// returns from any location.
8
//
9
// void MyObject::MyFunction() {
10
//   fd = open(...);
11
//   other_fd = open(...);
12
//   stream = open(...);
13
//   counter = 0;
14
//
15
//   defer(fd.close());
16
//   // Can include multiple statements.
17
//   defer({
18
//     other_fd.close();
19
//     stream.close();
20
//     counter++;
21
//   });
22
//
23
//   // do something with above descriptor.
24
// . if (condition) {
25
//     return;
26
// . } else {
27
// .   for (..) {
28
//         if (other_condition) return;
29
// .   }
30
// .   return;
31
// }
32
//
33
// defer() converts the block into lambda and captures all the variables in
34
// current block by reference. So instead of writing the following:
35
// defer([&]() {
36
//   delete mylocal_fd;
37
//   fd_counter++;
38
// });
39
//
40
// one can write:
41
// defer({
42
//   delete mylocal_fd;
43
//   fd_counter++;
44
// });
45
46
#ifndef CPP_HTMLPARSER_DEFER_H_
47
#define CPP_HTMLPARSER_DEFER_H_
48
49
#include <functional>
50
51
namespace htmlparser {
52
53
#define DEFER_CONCAT_(a, b) a ## b
54
#define DEFER_CONCAT(a, b) DEFER_CONCAT_(a, b)
55
56
class Defer {
57
 public:
58
  template<typename Callable>
59
  Defer(Callable&& defer_call) : defer_call_(std::forward<Callable>(
60
1.55M
      defer_call)) {}
parser.cc:htmlparser::Defer::Defer<htmlparser::Parser::AfterHeadIM()::$_1>(htmlparser::Parser::AfterHeadIM()::$_1&&)
Line
Count
Source
60
321
      defer_call)) {}
parser.cc:htmlparser::Defer::Defer<htmlparser::Parser::InTableIM()::$_2>(htmlparser::Parser::InTableIM()::$_2&&)
Line
Count
Source
60
1.55M
      defer_call)) {}
tokenizer.cc:htmlparser::Defer::Defer<htmlparser::Tokenizer::ReadScript()::$_0>(htmlparser::Tokenizer::ReadScript()::$_0&&)
Line
Count
Source
60
2.65k
      defer_call)) {}
tokenizer.cc:htmlparser::Defer::Defer<htmlparser::Tokenizer::ReadComment()::$_1>(htmlparser::Tokenizer::ReadComment()::$_1&&)
Line
Count
Source
60
1.25k
      defer_call)) {}
61
62
0
  Defer(Defer&& other) : defer_call_(std::move(other.defer_call_)) {
63
0
    other.defer_call_ = nullptr;
64
0
  }
65
66
1.55M
  ~Defer() {
67
1.55M
    if (defer_call_) defer_call_();
68
1.55M
  }
69
70
 private:
71
  Defer(const Defer&) = delete;
72
  void operator=(const Defer&) = delete;
73
74
  std::function<void(void)> defer_call_;
75
};
76
77
// Define a defer() keyword, whose behavior is similar to golang.
78
1.55M
#define defer(fn) Defer DEFER_CONCAT(__defer__, __LINE__) = [&] ( ) { fn ; }
parser.cc:htmlparser::Parser::AfterHeadIM()::$_1::operator()() const
Line
Count
Source
78
321
#define defer(fn) Defer DEFER_CONCAT(__defer__, __LINE__) = [&] ( ) { fn ; }
parser.cc:htmlparser::Parser::InTableIM()::$_2::operator()() const
Line
Count
Source
78
1.55M
#define defer(fn) Defer DEFER_CONCAT(__defer__, __LINE__) = [&] ( ) { fn ; }
tokenizer.cc:htmlparser::Tokenizer::ReadScript()::$_0::operator()() const
Line
Count
Source
78
2.65k
#define defer(fn) Defer DEFER_CONCAT(__defer__, __LINE__) = [&] ( ) { fn ; }
tokenizer.cc:htmlparser::Tokenizer::ReadComment()::$_1::operator()() const
Line
Count
Source
78
2.04k
#define defer(fn) Defer DEFER_CONCAT(__defer__, __LINE__) = [&] ( ) { fn ; }
79
80
}  // namespace htmlparser
81
82
#endif  // CPP_HTMLPARSER_DEFER_H_