1 /*
2 ** cdecl -- C gibberish translator
3 ** src/c_operator.h
4 **
5 ** Copyright (C) 2018-2021 Paul J. Lucas
6 **
7 ** This program is free software: you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation, either version 3 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #ifndef cdecl_c_operator_H
22 #define cdecl_c_operator_H
23
24 /**
25 * @file
26 * Declares constants, macros, types, and functions for C++ operators.
27 */
28
29 // local
30 #include "pjl_config.h" /* must go first */
31 #include "types.h"
32
33 /// @cond DOXYGEN_IGNORE
34
35 // standard
36 #include <stdbool.h>
37
38 _GL_INLINE_HEADER_BEGIN
39 #ifndef C_OPERATOR_INLINE
40 # define C_OPERATOR_INLINE _GL_INLINE
41 #endif /* C_OPERATOR_INLINE */
42
43 /// @endcond
44
45 /**
46 * @defgroup cpp-operators-group C++ Operators
47 * Macros, types, and functions for C++ operators.
48 * @{
49 */
50
51 // overloadability
52
53 /**
54 * For c_operator.flags, denotes that the operator is not overloadable.
55 *
56 * @sa #C_OP_MEMBER
57 * @sa #C_OP_NON_MEMBER
58 * @sa #C_OP_OVERLOADABLE
59 * @sa #C_OP_UNSPECIFIED
60 */
61 #define C_OP_NOT_OVERLOADABLE (1u << 2)
62
63 /**
64 * For c_operator.params_max of `operator()()`, denotes an unlimited number of
65 * parameters.
66 */
67 #define C_OP_PARAMS_UNLIMITED (~0u)
68
69 /**
70 * For c_operator.flags, denotes that the operator overloadability (member or
71 * non-member) is unspecified.
72 *
73 * @sa #C_OP_MEMBER
74 * @sa #C_OP_NON_MEMBER
75 * @sa #C_OP_NOT_OVERLOADABLE
76 * @sa #C_OP_OVERLOADABLE
77 */
78 #define C_OP_UNSPECIFIED C_FN_UNSPECIFIED
79
80 /**
81 * For c_operator.flags, denotes that the operator is overload{able|ed} as a
82 * member only.
83 *
84 * @sa #C_OP_NON_MEMBER
85 * @sa #C_OP_NOT_OVERLOADABLE
86 * @sa #C_OP_OVERLOADABLE
87 * @sa #C_OP_UNSPECIFIED
88 */
89 #define C_OP_MEMBER C_FN_MEMBER
90
91 /**
92 * For c_operator.flags, denotes that the operator is overload{able|ed} as a
93 * non-member only.
94 *
95 * @sa #C_OP_MEMBER
96 * @sa #C_OP_NOT_OVERLOADABLE
97 * @sa #C_OP_OVERLOADABLE
98 * @sa #C_OP_UNSPECIFIED
99 */
100 #define C_OP_NON_MEMBER C_FN_NON_MEMBER
101
102 /**
103 * For c_operator.flags, denotes that the operator is overloadable as either a
104 * member or non-member.
105 *
106 * @sa #C_OP_MEMBER
107 * @sa #C_OP_NON_MEMBER
108 * @sa #C_OP_NOT_OVERLOADABLE
109 * @sa #C_OP_UNSPECIFIED
110 */
111 #define C_OP_OVERLOADABLE (C_OP_MEMBER | C_OP_NON_MEMBER)
112
113 /**
114 * For c_operator.flags, overloadability bitmask.
115 */
116 #define C_OP_MASK_OVERLOAD 0x7u
117
118 ///////////////////////////////////////////////////////////////////////////////
119
120 /**
121 * C++ operators.
122 *
123 * @note Operators are named based on the characters comprising them rather
124 * than their semantics because many operators have more than one meaning
125 * depending upon context, e.g. `*` is both the "times" and the "dereference"
126 * operator.
127 */
128 enum c_oper_id {
129 C_OP_NONE, ///< No operator.
130 C_OP_NEW, ///< The `new` operator.
131 C_OP_NEW_ARRAY, ///< The `new[]` operator.
132 C_OP_DELETE, ///< The `delete` operator.
133 C_OP_DELETE_ARRAY, ///< The `delete[]` operator.
134 C_OP_EXCLAM, ///< The `!` operator.
135 C_OP_EXCLAM_EQ, ///< The `!=` operator.
136 C_OP_PERCENT, ///< The `%` operator.
137 C_OP_PERCENT_EQ, ///< The `%=` operator.
138 C_OP_AMPER, ///< The `&` operator.
139 C_OP_AMPER2, ///< The `&&` operator.
140 C_OP_AMPER_EQ, ///< The `&=` operator.
141 C_OP_PARENS, ///< The `()` operator.
142 C_OP_STAR, ///< The `*` operator.
143 C_OP_STAR_EQ, ///< The `*=` operator.
144 C_OP_PLUS, ///< The `+` operator.
145 C_OP_PLUS2, ///< The `++` operator.
146 C_OP_PLUS_EQ, ///< The `+=` operator.
147 C_OP_COMMA, ///< The `,` operator.
148 C_OP_MINUS, ///< The `-` operator.
149 C_OP_MINUS2, ///< The `--` operator.
150 C_OP_MINUS_EQ, ///< The `-=` operator.
151 C_OP_ARROW, ///< The `->` operator.
152 C_OP_ARROW_STAR, ///< The `->*` operator.
153 C_OP_DOT, ///< The `.` operator.
154 C_OP_DOT_STAR, ///< The `.*` operator.
155 C_OP_SLASH, ///< The `/` operator.
156 C_OP_SLASH_EQ, ///< The `/=` operator.
157 C_OP_COLON2, ///< The `::` operator.
158 C_OP_LESS, ///< The `<` operator.
159 C_OP_LESS2, ///< The `<<` operator.
160 C_OP_LESS2_EQ, ///< The `<<=` operator.
161 C_OP_LESS_EQ, ///< The `<=` operator.
162 C_OP_LESS_EQ_GREATER, ///< The `<=>` operator.
163 C_OP_EQ, ///< The `=` operator.
164 C_OP_EQ2, ///< The `==` operator.
165 C_OP_GREATER, ///< The `>` operator.
166 C_OP_GREATER_EQ, ///< The `>=` operator.
167 C_OP_GREATER2, ///< The `>>` operator.
168 C_OP_GREATER2_EQ, ///< The `>>=` operator.
169 C_OP_QMARK_COLON, ///< The `?:` operator.
170 C_OP_BRACKETS, ///< The `[]` operator.
171 C_OP_CIRC, ///< The `^` operator.
172 C_OP_CIRC_EQ, ///< The `^=` operator.
173 C_OP_PIPE, ///< The `|` operator.
174 C_OP_PIPE_EQ, ///< The `|=` operator.
175 C_OP_PIPE2, ///< The `||` operator.
176 C_OP_TILDE, ///< The `~` operator.
177 };
178
179 /**
180 * C++ operator information.
181 *
182 * @note `params_min` and `params_max` comprise the inclusive range for the
183 * union of member and non-member versions. If you know you're dealing with a
184 * member operator, use only `params_min`; if you know you're dealing with a
185 * non-member operator, use only `params_max`; if you don't know which, use
186 * both.
187 */
188 struct c_operator {
189 c_oper_id_t oper_id; ///< ID.
190 char const *name; ///< Name.
191
192 /**
193 * Bitwise-or of flags specifying whether the operator is a member, non-
194 * member, both, or not overloadable.
195 *
196 * @sa #C_OP_MEMBER
197 * @sa #C_OP_NON_MEMBER
198 * @sa #C_OP_OVERLOADABLE
199 * @sa #C_OP_NOT_OVERLOADABLE
200 * @sa #C_OP_MASK_OVERLOAD
201 */
202 unsigned flags;
203
204 unsigned params_min; ///< Minimum number of parameters.
205 unsigned params_max; ///< Maximum number of parameters.
206 c_lang_id_t lang_ids; ///< Language(s) OK in.
207 };
208
209 ////////// extern functions ///////////////////////////////////////////////////
210
211 /**
212 * Gets the c_operator for \a oper_id.
213 *
214 * @param oper_id The ID of the c_operator to get.
215 * @return Returns a pointer to said c_operator.
216 */
217 PJL_WARN_UNUSED_RESULT
218 c_operator_t const* c_oper_get( c_oper_id_t oper_id );
219
220 /**
221 * Checks whether the C++ operator is ambiguous.
222 *
223 * The operators `&`, `*`, `+`, `++`, `-`, and `--`, when declared as:
224 *
225 * T operator OP(U);
226 *
227 * i.e., having one parameter, are ambiguous (to cdecl) between being a member
228 * or non-member operator since cdecl doesn't have the context in which the
229 * operator is declared. If it were declared in-class, e.g.:
230 *
231 * class T {
232 * public:
233 * // ...
234 * T& operator OP(U);
235 * };
236 *
237 * then clearly it's a member operator; if it were declared at file scope, then
238 * clearly it's a non-member operator; but cdecl doesn't have this context.
239 *
240 * We can tell if an operator is ambiguous if it can take 1 parameter when the
241 * minimum is 0 and the maximum is 2.
242 *
243 * @param op The C++ operator to check.
244 * @return Returns `true` only if the operator is ambiguous.
245 */
246 C_OPERATOR_INLINE PJL_WARN_UNUSED_RESULT
c_oper_is_ambiguous(c_operator_t const * op)247 bool c_oper_is_ambiguous( c_operator_t const *op ) {
248 return op->params_min == 0 && op->params_max == 2;
249 }
250
251 /**
252 * Gets the C++ token for the operator having \a oper_id.
253 *
254 * @param oper_id The ID of the c_operator to get the token for.
255 * @return Returns said token (including alternative or graph tokens, if either
256 * is enabled); otherwise, returns the unaltered token.
257 */
258 PJL_WARN_UNUSED_RESULT
259 char const* c_oper_token_c( c_oper_id_t oper_id );
260
261 ///////////////////////////////////////////////////////////////////////////////
262
263 /** @} */
264
265 _GL_INLINE_HEADER_END
266
267 #endif /* cdecl_c_operator_H */
268 /* vim:set et sw=2 ts=2: */
269