From 933b495ed1c82c1d360fd45d8aad32d5f06bd2bb Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Thu, 21 May 2020 12:19:17 +0200 Subject: [PATCH] * Optimization for M_LET for a string_t in case of constant non formatted string * Support for string_t in M_LET for string_t in C11 mode. * Adding associate test --- m-string.h | 20 +++++++++++++++++--- tests/test-mstring.c | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/m-string.h b/m-string.h index 1c9201de..2d8285aa 100644 --- a/m-string.h +++ b/m-string.h @@ -1588,10 +1588,24 @@ namespace m_string { m_string::m_aligned_string(s).string #endif -/* Initialize and set a string to the given formatted value */ -#define STRING_INIT_PRINTF(v, ...) \ +/* Initialize and set a string to the given formatted value. */ +#define STRINGI_INIT_PRINTF(v, ...) \ (string_init (v), string_printf (v, __VA_ARGS__) ) +/* Initialize a string with the given list of arguments. + Check if it is a formatted input or not by counting the number of arguments. + If there is only one argument, it can only be a set to C string. + It is much faster in this case to call string_init_set_str. + In C11 mode, it uses the fact that string_init_set is overloaded to handle both + C string and string. */ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) +#define STRINGI_INIT_WITH(v, ...) \ + M_IF_NARGS_EQ1(__VA_ARGS__)(string_init_set, STRINGI_INIT_PRINTF)(v, __VA_ARGS__) +#else +#define STRINGI_INIT_WITH(v, ...) \ + M_IF_NARGS_EQ1(__VA_ARGS__)(string_init_set_str, STRINGI_INIT_PRINTF)(v, __VA_ARGS__) +#endif + /* NOTE: Use GCC extension (OBSOLETE) */ #define STRING_DECL_INIT(v) \ string_t v __attribute__((cleanup(stringi_clear2))) = {{ 0, 0, NULL}} @@ -1605,7 +1619,7 @@ namespace m_string { /* Define the OPLIST of a STRING */ #define STRING_OPLIST \ (INIT(string_init),INIT_SET(string_init_set), SET(string_set), \ - INIT_WITH(STRING_INIT_PRINTF), \ + INIT_WITH(STRINGI_INIT_WITH), \ INIT_MOVE(string_init_move), MOVE(string_move), \ SWAP(string_swap), CLEAN(string_clean), \ TEST_EMPTY(string_empty_p), \ diff --git a/tests/test-mstring.c b/tests/test-mstring.c index 322bc67d..95071e86 100644 --- a/tests/test-mstring.c +++ b/tests/test-mstring.c @@ -573,10 +573,33 @@ static void test_bounded_io(void) string16_clear(d); } +static void test_M_LET(void) +{ + M_LET(s, string_t) { + assert(string_empty_p(s)); + } + M_LET(s1, s2, string_t) { + assert(string_empty_p(s1)); + assert(string_empty_p(s2)); + } + M_LET( (s1, "Hello %s", "world"), string_t) { + assert(string_equal_str_p(s1, "Hello world")); + } + M_LET( (s1, "Hello"), string_t) { + assert(string_equal_str_p(s1, "Hello")); +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) + // Initalization with another string is only supported in C11 mode. + M_LET( (s2, s1), string_t) { + assert(string_equal_str_p(s2, "Hello")); + } +#endif + } +} int main(void) { test0(); test1(); + test_M_LET(); test_utf8_basic(); test_utf8_it(); test_bounded1();