Coverage Report

Created: 2023-05-25 06:18

/proc/self/cwd/internal/status_macros.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2021 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef THIRD_PARTY_CEL_CPP_INTERNAL_STATUS_MACROS_H_
16
#define THIRD_PARTY_CEL_CPP_INTERNAL_STATUS_MACROS_H_
17
18
#include <utility>
19
20
#include "absl/base/optimization.h"
21
#include "absl/status/status.h"
22
#include "internal/status_builder.h"
23
24
#define CEL_RETURN_IF_ERROR(expr)                                            \
25
  CEL_INTERNAL_STATUS_MACROS_IMPL_ELSE_BLOCKER_                              \
26
  if (::cel::internal::StatusAdaptor cel_internal_status_macro = {(expr)}) { \
27
  } else /* NOLINT */                                                        \
28
    return cel_internal_status_macro.Consume()
29
30
// The GNU compiler historically emitted warnings for obscure usages of
31
// `if (foo) if (bar) {} else`. This suppresses that.
32
33
// clang-format off
34
#define CEL_INTERNAL_STATUS_MACROS_IMPL_ELSE_BLOCKER_ \
35
  switch (0) case 0: default: /* NOLINT */
36
// clang-format on
37
38
#define CEL_ASSIGN_OR_RETURN(...)                                   \
39
11.8k
  CEL_INTERNAL_STATUS_MACROS_GET_VARIADIC_(                         \
40
11.8k
      (__VA_ARGS__, CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_3_, \
41
11.8k
       CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_2_))             \
42
11.8k
  (__VA_ARGS__)
43
44
// The following are macro magic to select either the 2 arg variant or 3 arg
45
// variant of CEL_ASSIGN_OR_RETURN.
46
47
#define CEL_INTERNAL_STATUS_MACROS_GET_VARIADIC_HELPER_(_1, _2, _3, NAME, ...) \
48
11.8k
  NAME
49
#define CEL_INTERNAL_STATUS_MACROS_GET_VARIADIC_(args) \
50
11.8k
  CEL_INTERNAL_STATUS_MACROS_GET_VARIADIC_HELPER_ args
51
52
#define CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_2_(lhs, rexpr)        \
53
19.2k
  CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_(                           \
54
11.8k
      CEL_INTERNAL_STATUS_MACROS_CONCAT(_status_or_value, __LINE__), lhs, \
55
11.8k
      rexpr,                                                              \
56
11.8k
      return absl::Status(std::move(CEL_INTERNAL_STATUS_MACROS_CONCAT(    \
57
11.8k
                                        _status_or_value, __LINE__))      \
58
11.8k
                              .status()))
59
60
#define CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_3_(lhs, rexpr,           \
61
                                                       error_expression)     \
62
  CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_(                              \
63
      CEL_INTERNAL_STATUS_MACROS_CONCAT(_status_or_value, __LINE__), lhs,    \
64
      rexpr,                                                                 \
65
      ::cel::internal::StatusBuilder _(                                      \
66
          std::move(                                                         \
67
              CEL_INTERNAL_STATUS_MACROS_CONCAT(_status_or_value, __LINE__)) \
68
              .status());                                                    \
69
      (void)_; /* error_expression is allowed to not use this variable */    \
70
      return (error_expression))
71
72
// Common implementation of CEL_ASSIGN_OR_RETURN. Both the 2 arg variant and 3
73
// arg variant are implemented by this macro.
74
75
#define CEL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_(statusor, lhs, rexpr, \
76
                                                     error_expression)     \
77
19.2k
  auto statusor = (rexpr);                                                 \
78
19.2k
  if (ABSL_PREDICT_FALSE(!statusor.ok())) {                                \
79
7.41k
    error_expression;                                                      \
80
7.41k
  }                                                                        \
81
19.2k
  CEL_INTERNAL_STATUS_MACROS_UNPARENTHESIZE_IF_PARENTHESIZED(lhs) =        \
82
11.8k
      std::move(statusor).value()
83
84
#define CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_INNER(...) \
85
  CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_INNER_HELPER((__VA_ARGS__, 0, 1))
86
87
// MSVC historically expands variadic macros incorrectly, so another level of
88
// indirection is required.
89
#define CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_INNER_HELPER(args) \
90
  CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_INNER_I args
91
#define CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_INNER_I(e0, e1, is_empty, ...) \
92
  is_empty
93
94
#define CEL_INTERNAL_STATUS_MACROS_IS_EMPTY(...) \
95
  CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_I(__VA_ARGS__)
96
#define CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_I(...) \
97
  CEL_INTERNAL_STATUS_MACROS_IS_EMPTY_INNER(_, ##__VA_ARGS__)
98
99
#define CEL_INTERNAL_STATUS_MACROS_IF_1(_Then, _Else) _Then
100
#define CEL_INTERNAL_STATUS_MACROS_IF_0(_Then, _Else) _Else
101
#define CEL_INTERNAL_STATUS_MACROS_IF(_Cond, _Then, _Else)                 \
102
  CEL_INTERNAL_STATUS_MACROS_CONCAT(CEL_INTERNAL_STATUS_MACROS_IF_, _Cond) \
103
  (_Then, _Else)
104
105
#define CEL_INTERNAL_STATUS_MACROS_EAT(...)
106
#define CEL_INTERNAL_STATUS_MACROS_REM(...) __VA_ARGS__
107
#define CEL_INTERNAL_STATUS_MACROS_EMPTY()
108
109
// Expands to 1 if the input is surrounded by parenthesis, 0 otherwise.
110
#define CEL_INTERNAL_STATUS_MACROS_IS_PARENTHESIZED(...) \
111
  CEL_INTERNAL_STATUS_MACROS_IS_EMPTY(                   \
112
      CEL_INTERNAL_STATUS_MACROS_EAT __VA_ARGS__)
113
114
// If the input is surrounded by parenthesis, remove them. Otherwise expand it
115
// unchanged.
116
#define CEL_INTERNAL_STATUS_MACROS_UNPARENTHESIZE_IF_PARENTHESIZED(...)   \
117
19.2k
  CEL_INTERNAL_STATUS_MACROS_IF(                                          \
118
19.2k
      CEL_INTERNAL_STATUS_MACROS_IS_PARENTHESIZED(__VA_ARGS__),           \
119
19.2k
      CEL_INTERNAL_STATUS_MACROS_REM, CEL_INTERNAL_STATUS_MACROS_EMPTY()) \
120
19.2k
  __VA_ARGS__
121
122
#define CEL_INTERNAL_STATUS_MACROS_CONCAT_HELPER(x, y) x##y
123
#define CEL_INTERNAL_STATUS_MACROS_CONCAT(x, y) \
124
  CEL_INTERNAL_STATUS_MACROS_CONCAT_HELPER(x, y)
125
126
namespace cel::internal {
127
128
class StatusAdaptor final {
129
 public:
130
  StatusAdaptor() = default;
131
132
  StatusAdaptor(const StatusAdaptor&) = delete;
133
134
  StatusAdaptor(StatusAdaptor&&) = delete;
135
136
0
  StatusAdaptor(const absl::Status& status) : builder_(status) {}  // NOLINT
137
138
  StatusAdaptor& operator=(const StatusAdaptor&) = delete;
139
140
  StatusAdaptor& operator=(StatusAdaptor&&) = delete;
141
142
0
  StatusBuilder&& Consume() { return std::move(builder_); }
143
144
0
  explicit operator bool() const { return ABSL_PREDICT_TRUE(builder_.ok()); }
145
146
 private:
147
  StatusBuilder builder_;
148
};
149
150
}  // namespace cel::internal
151
152
#endif  // THIRD_PARTY_CEL_CPP_INTERNAL_STATUS_MACROS_H_