diff options
author | Damien George <damien.p.george@gmail.com> | 2014-06-01 18:22:09 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-06-01 18:22:09 +0100 |
commit | fcc9cf63f194c632b9fe206a860dfece48303a98 (patch) | |
tree | d6d442056c83e65de176c5b1e488a695f1d9df27 /py | |
parent | f1dbd78b30e487ea667e222721bba4d79d3763de (diff) | |
download | micropython-fcc9cf63f194c632b9fe206a860dfece48303a98.tar.gz micropython-fcc9cf63f194c632b9fe206a860dfece48303a98.zip |
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.
Diffstat (limited to 'py')
-rw-r--r-- | py/objstr.c | 52 |
1 files changed, 13 insertions, 39 deletions
diff --git a/py/objstr.c b/py/objstr.c index 43425f6f78..9ff9106375 100644 --- a/py/objstr.c +++ b/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 |