Skip to content

Commit 0395936

Browse files
committed
Add a validate_handler macro that checks handlers for the mode enums
1 parent 8b32c1b commit 0395936

10 files changed

+39
-20
lines changed

atom/src/behaviors.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,28 @@ enum Mode: uint8_t
205205
Property,
206206
ObjectMethod_Name,
207207
MemberMethod_Object,
208+
Last // sentinel
208209
};
209210

210211
} // namespace GetState
211212

213+
constexpr uint8_t _required_handler_size(uint8_t x) {
214+
return (
215+
(x > 128) ? 255 :
216+
(x > 64) ? 128 :
217+
(x > 32) ? 64 :
218+
(x > 16) ? 32 :
219+
(x > 8) ? 16 :
220+
(x > 4) ? 8 :
221+
(x > 2) ? 4 :
222+
2
223+
);
224+
}
225+
226+
#define _handlers_size( a ) ( sizeof(a) / sizeof(a[0]) )
227+
#define validate_handlers( handlers, sentinel ) \
228+
_handlers_size(handlers) - 1; \
229+
static_assert(sentinel <= _handlers_size(handlers), "Not enough handlers for all enum values"); \
230+
static_assert(_required_handler_size(sentinel) == _handlers_size(handlers), "Handlers size does not match enum width") \
231+
212232
} // namespace atom

atom/src/defaultvaluebehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,15 +207,15 @@ handlers[] = {
207207
no_op_handler
208208
};
209209

210-
static_assert( sizeof(handlers) / sizeof(handler) == 16, "Must be exactly 16 handlers" );
210+
const auto mask = validate_handlers(handlers, DefaultValue::Mode::Last);
211211

212212
} // namespace
213213

214214

215215
PyObject*
216216
Member::default_value( CAtom* atom )
217217
{
218-
return handlers[ get_default_value_mode() & 0xf ]( this, atom );
218+
return handlers[ get_default_value_mode() & mask ]( this, atom );
219219
}
220220

221221

atom/src/delattrbehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,15 @@ handlers[] = {
192192
property_handler
193193
};
194194

195-
static_assert( sizeof(handlers) / sizeof(handler) == 8, "Must be exactly 8 handlers" );
195+
const auto mask = validate_handlers(handlers, DelAttr::Mode::Last);
196196

197197
} // namespace
198198

199199

200200
int
201201
Member::delattr( CAtom* atom )
202202
{
203-
return handlers[ get_delattr_mode() & 0x7 ]( this, atom );
203+
return handlers[ get_delattr_mode() & mask ]( this, atom );
204204
}
205205

206206

atom/src/getattrbehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,15 @@ handlers[] = {
263263
no_op_handler
264264
};
265265

266-
static_assert( sizeof(handlers) / sizeof(handler) == 16, "Must be exactly 16 handlers" );
266+
const auto mask = validate_handlers(handlers, GetAttr::Mode::Last);
267267

268268
} // namespace
269269

270270

271271
PyObject*
272272
Member::getattr( CAtom* atom )
273273
{
274-
return handlers[ get_getattr_mode() & 0xf ]( this, atom );
274+
return handlers[ get_getattr_mode() & mask ]( this, atom );
275275
}
276276

277277
} // namespace atom

atom/src/getstatebehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ handlers[] = {
129129
include_handler
130130
};
131131

132-
static_assert( sizeof(handlers) / sizeof(handler) == 8, "Must be exactly 8 handlers" );
132+
const auto mask = validate_handlers(handlers, GetState::Mode::Last);
133133

134134
} // namespace
135135

136136

137137
PyObject*
138138
Member::should_getstate( CAtom* atom )
139139
{
140-
return handlers[ get_getstate_mode() & 0x7 ]( this, atom );
140+
return handlers[ get_getstate_mode() & mask ]( this, atom );
141141
}
142142

143143
} // namespace atom

atom/src/postgetattrbehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,15 @@ handlers[] = {
9999
no_op_handler,
100100
};
101101

102-
static_assert( sizeof(handlers) / sizeof(handler) == 8, "Must be exactly 8 handlers" );
102+
const auto mask = validate_handlers(handlers, PostGetAttr::Mode::Last);
103103

104104
} // namespace
105105

106106

107107
PyObject*
108108
Member::post_getattr( CAtom* atom, PyObject* value )
109109
{
110-
return handlers[ get_post_getattr_mode() & 0x7 ]( this, atom, value );
110+
return handlers[ get_post_getattr_mode() & mask ]( this, atom, value );
111111
}
112112

113113

atom/src/postsetattrbehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,15 @@ handlers[] = {
112112
no_op_handler
113113
};
114114

115-
static_assert( sizeof(handlers) / sizeof(handler) == 8, "Must be exactly 8 handlers" );
115+
const auto mask = validate_handlers(handlers, PostSetAttr::Mode::Last);
116116

117117
} // namespace
118118

119119

120120
int
121121
Member::post_setattr( CAtom* atom, PyObject* oldvalue, PyObject* newvalue )
122122
{
123-
return handlers[ get_post_setattr_mode() & 0x7 ]( this, atom, oldvalue, newvalue );
123+
return handlers[ get_post_setattr_mode() & mask ]( this, atom, oldvalue, newvalue );
124124
}
125125

126126

atom/src/postvalidatebehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,15 @@ handlers[] = {
103103
no_op_handler
104104
};
105105

106-
static_assert( sizeof(handlers) / sizeof(handler) == 8, "Must be exactly 8 handlers" );
106+
const auto mask = validate_handlers(handlers, PostValidate::Mode::Last);
107107

108108
} // namespace
109109

110110

111111
PyObject*
112112
Member::post_validate( CAtom* atom, PyObject* oldvalue, PyObject* newvalue )
113113
{
114-
return handlers[ get_post_validate_mode() & 0x7 ]( this, atom, oldvalue, newvalue );
114+
return handlers[ get_post_validate_mode() & mask ]( this, atom, oldvalue, newvalue );
115115
}
116116

117117
} // namespace atom

atom/src/setattrbehavior.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,15 +383,15 @@ handlers[] = {
383383
no_op_handler
384384
};
385385

386-
static_assert( sizeof(handlers) / sizeof(handler) == 16, "Must be exactly 16 handlers" );
386+
const auto mask = validate_handlers(handlers, SetAttr::Mode::Last);
387387

388388
} // namespace
389389

390390

391391
int
392392
Member::setattr( CAtom* atom, PyObject* value )
393393
{
394-
return handlers[ get_setattr_mode() & 0xf ]( this, atom, value );
394+
return handlers[ get_setattr_mode() & mask ]( this, atom, value );
395395
}
396396

397397

atom/src/validatebehavior.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -997,19 +997,18 @@ handlers[] = {
997997
delegate_handler,
998998
object_method_old_new_handler,
999999
object_method_name_old_new_handler,
1000-
member_method_object_old_new_handler
1000+
member_method_object_old_new_handler,
10011001
};
10021002

1003+
const auto mask = validate_handlers(handlers, Validate::Mode::Last);
10031004

10041005
} // namespace
10051006

10061007

10071008
PyObject*
10081009
Member::validate( CAtom* atom, PyObject* oldvalue, PyObject* newvalue )
10091010
{
1010-
if( get_validate_mode() >= sizeof( handlers ) / sizeof( handler ) )
1011-
return no_op_handler( this, atom, oldvalue, newvalue ); // LCOV_EXCL_LINE
1012-
return handlers[ get_validate_mode() ]( this, atom, oldvalue, newvalue );
1011+
return handlers[ get_validate_mode() & mask ]( this, atom, oldvalue, newvalue );
10131012
}
10141013

10151014

0 commit comments

Comments
 (0)