Skip to content

Commit fcc9cf6

Browse files
committed
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.
1 parent f1dbd78 commit fcc9cf6

File tree

1 file changed

+13
-39
lines changed

1 file changed

+13
-39
lines changed

py/objstr.c

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,73 +1476,47 @@ STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
14761476
return str_partitioner(self_in, arg, -1);
14771477
}
14781478

1479-
enum { CASE_UPPER, CASE_LOWER };
1480-
14811479
// Supposedly not too critical operations, so optimize for code size
1482-
STATIC mp_obj_t str_caseconv(int op, mp_obj_t self_in) {
1480+
STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) {
14831481
GET_STR_DATA_LEN(self_in, self_data, self_len);
14841482
byte *data;
14851483
mp_obj_t s = mp_obj_str_builder_start(mp_obj_get_type(self_in), self_len, &data);
14861484
for (int i = 0; i < self_len; i++) {
1487-
if (op == CASE_UPPER) {
1488-
*data++ = unichar_toupper(*self_data++);
1489-
} else {
1490-
*data++ = unichar_tolower(*self_data++);
1491-
}
1485+
*data++ = op(*self_data++);
14921486
}
14931487
*data = 0;
14941488
return mp_obj_str_builder_end(s);
14951489
}
14961490

14971491
STATIC mp_obj_t str_lower(mp_obj_t self_in) {
1498-
return str_caseconv(CASE_LOWER, self_in);
1492+
return str_caseconv(unichar_tolower, self_in);
14991493
}
15001494

15011495
STATIC mp_obj_t str_upper(mp_obj_t self_in) {
1502-
return str_caseconv(CASE_UPPER, self_in);
1496+
return str_caseconv(unichar_toupper, self_in);
15031497
}
15041498

1505-
enum { IS_SPACE, IS_ALPHA, IS_DIGIT, IS_UPPER, IS_LOWER };
1506-
1507-
STATIC mp_obj_t str_uni_istype(int type, mp_obj_t self_in) {
1499+
STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) {
15081500
GET_STR_DATA_LEN(self_in, self_data, self_len);
15091501

15101502
if (self_len == 0) {
15111503
return mp_const_false; // default to False for empty str
15121504
}
15131505

1514-
typedef bool (*check_function)(unichar);
1515-
check_function f;
1516-
1517-
if (type != IS_UPPER && type != IS_LOWER) {
1518-
switch (type) {
1519-
case IS_SPACE: f = &unichar_isspace; break;
1520-
case IS_ALPHA: f = &unichar_isalpha; break;
1521-
case IS_DIGIT: f = &unichar_isdigit; break;
1522-
default:
1523-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unknown type provided for str_uni_istype"));
1524-
}
1525-
1506+
if (f != unichar_isupper && f != unichar_islower) {
15261507
for (int i = 0; i < self_len; i++) {
15271508
if (!f(*self_data++)) {
15281509
return mp_const_false;
15291510
}
15301511
}
15311512
} else {
1532-
switch (type) {
1533-
case IS_UPPER: f = &unichar_isupper; break;
1534-
case IS_LOWER: f = &unichar_islower; break;
1535-
default:
1536-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unknown type provided for str_uni_istype"));
1537-
}
1538-
15391513
bool contains_alpha = false;
15401514

15411515
for (int i = 0; i < self_len; i++) { // only check alphanumeric characters
15421516
if (unichar_isalpha(*self_data++)) {
15431517
contains_alpha = true;
1544-
if (!f(*(self_data-1))) {
1545-
return mp_const_false; // we already incremented
1518+
if (!f(*(self_data - 1))) { // -1 because we already incremented above
1519+
return mp_const_false;
15461520
}
15471521
}
15481522
}
@@ -1556,23 +1530,23 @@ STATIC mp_obj_t str_uni_istype(int type, mp_obj_t self_in) {
15561530
}
15571531

15581532
STATIC mp_obj_t str_isspace(mp_obj_t self_in) {
1559-
return str_uni_istype(IS_SPACE, self_in);
1533+
return str_uni_istype(unichar_isspace, self_in);
15601534
}
15611535

15621536
STATIC mp_obj_t str_isalpha(mp_obj_t self_in) {
1563-
return str_uni_istype(IS_ALPHA, self_in);
1537+
return str_uni_istype(unichar_isalpha, self_in);
15641538
}
15651539

15661540
STATIC mp_obj_t str_isdigit(mp_obj_t self_in) {
1567-
return str_uni_istype(IS_DIGIT, self_in);
1541+
return str_uni_istype(unichar_isdigit, self_in);
15681542
}
15691543

15701544
STATIC mp_obj_t str_isupper(mp_obj_t self_in) {
1571-
return str_uni_istype(IS_UPPER, self_in);
1545+
return str_uni_istype(unichar_isupper, self_in);
15721546
}
15731547

15741548
STATIC mp_obj_t str_islower(mp_obj_t self_in) {
1575-
return str_uni_istype(IS_LOWER, self_in);
1549+
return str_uni_istype(unichar_islower, self_in);
15761550
}
15771551

15781552
#if MICROPY_CPYTHON_COMPAT

0 commit comments

Comments
 (0)