py, str: Replace enum with actual function pointer.
This way, it's slightly more efficient, uses less ROM (60 bytes less for stmhal), and doesn't require to raise exception if bad operation given.
This commit is contained in:
parent
f1dbd78b30
commit
fcc9cf63f1
52
py/objstr.c
52
py/objstr.c
@ -1476,73 +1476,47 @@ STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
|
||||
return str_partitioner(self_in, arg, -1);
|
||||
}
|
||||
|
||||
enum { CASE_UPPER, CASE_LOWER };
|
||||
|
||||
// Supposedly not too critical operations, so optimize for code size
|
||||
STATIC mp_obj_t str_caseconv(int op, mp_obj_t self_in) {
|
||||
STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) {
|
||||
GET_STR_DATA_LEN(self_in, self_data, self_len);
|
||||
byte *data;
|
||||
mp_obj_t s = mp_obj_str_builder_start(mp_obj_get_type(self_in), self_len, &data);
|
||||
for (int i = 0; i < self_len; i++) {
|
||||
if (op == CASE_UPPER) {
|
||||
*data++ = unichar_toupper(*self_data++);
|
||||
} else {
|
||||
*data++ = unichar_tolower(*self_data++);
|
||||
}
|
||||
*data++ = op(*self_data++);
|
||||
}
|
||||
*data = 0;
|
||||
return mp_obj_str_builder_end(s);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_lower(mp_obj_t self_in) {
|
||||
return str_caseconv(CASE_LOWER, self_in);
|
||||
return str_caseconv(unichar_tolower, self_in);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_upper(mp_obj_t self_in) {
|
||||
return str_caseconv(CASE_UPPER, self_in);
|
||||
return str_caseconv(unichar_toupper, self_in);
|
||||
}
|
||||
|
||||
enum { IS_SPACE, IS_ALPHA, IS_DIGIT, IS_UPPER, IS_LOWER };
|
||||
|
||||
STATIC mp_obj_t str_uni_istype(int type, mp_obj_t self_in) {
|
||||
STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) {
|
||||
GET_STR_DATA_LEN(self_in, self_data, self_len);
|
||||
|
||||
if (self_len == 0) {
|
||||
return mp_const_false; // default to False for empty str
|
||||
}
|
||||
|
||||
typedef bool (*check_function)(unichar);
|
||||
check_function f;
|
||||
|
||||
if (type != IS_UPPER && type != IS_LOWER) {
|
||||
switch (type) {
|
||||
case IS_SPACE: f = &unichar_isspace; break;
|
||||
case IS_ALPHA: f = &unichar_isalpha; break;
|
||||
case IS_DIGIT: f = &unichar_isdigit; break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unknown type provided for str_uni_istype"));
|
||||
}
|
||||
|
||||
if (f != unichar_isupper && f != unichar_islower) {
|
||||
for (int i = 0; i < self_len; i++) {
|
||||
if (!f(*self_data++)) {
|
||||
return mp_const_false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (type) {
|
||||
case IS_UPPER: f = &unichar_isupper; break;
|
||||
case IS_LOWER: f = &unichar_islower; break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unknown type provided for str_uni_istype"));
|
||||
}
|
||||
|
||||
bool contains_alpha = false;
|
||||
|
||||
for (int i = 0; i < self_len; i++) { // only check alphanumeric characters
|
||||
if (unichar_isalpha(*self_data++)) {
|
||||
contains_alpha = true;
|
||||
if (!f(*(self_data-1))) {
|
||||
return mp_const_false; // we already incremented
|
||||
if (!f(*(self_data - 1))) { // -1 because we already incremented above
|
||||
return mp_const_false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1556,23 +1530,23 @@ STATIC mp_obj_t str_uni_istype(int type, mp_obj_t self_in) {
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_isspace(mp_obj_t self_in) {
|
||||
return str_uni_istype(IS_SPACE, self_in);
|
||||
return str_uni_istype(unichar_isspace, self_in);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_isalpha(mp_obj_t self_in) {
|
||||
return str_uni_istype(IS_ALPHA, self_in);
|
||||
return str_uni_istype(unichar_isalpha, self_in);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_isdigit(mp_obj_t self_in) {
|
||||
return str_uni_istype(IS_DIGIT, self_in);
|
||||
return str_uni_istype(unichar_isdigit, self_in);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_isupper(mp_obj_t self_in) {
|
||||
return str_uni_istype(IS_UPPER, self_in);
|
||||
return str_uni_istype(unichar_isupper, self_in);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t str_islower(mp_obj_t self_in) {
|
||||
return str_uni_istype(IS_LOWER, self_in);
|
||||
return str_uni_istype(unichar_islower, self_in);
|
||||
}
|
||||
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
|
Loading…
Reference in New Issue
Block a user