--- a/src/cx/string.h Sun Dec 28 14:47:36 2025 +0100 +++ b/src/cx/string.h Sun Dec 28 15:45:39 2025 +0100 @@ -395,6 +395,19 @@ #endif /** + * Casts away constness and converts a cxstring to a cxmutstr. + * For internal use only! + * @param str + * @return + */ +CX_INLINE cxmutstr cx_mutstrcast(cxstring str) { + cxmutstr s; + s.ptr = (char*)str.ptr; + s.length = str.length; + return s; +} + +/** * Passes the pointer in this string to the cxDefaultAllocator's @c free() function. * * The pointer in the struct is set to @c NULL, and the length is set to zero, @@ -530,22 +543,74 @@ cx_strcat_a(cxDefaultAllocator, str, count, __VA_ARGS__) /** - * Returns a substring starting at the specified location. + * Returns a substring. + * + * Internal function - do not use. * - * @attention the new string references the same memory area as the - * input string and is usually @em not zero-terminated. - * Use cx_strdup() to get a copy. + * @param string input string + * @param start start location of the substring + * @param length the maximum length of the returned string + * @return a substring of @p string starting at @p start + * @see cx_strsubsl() + */ +cx_attr_nodiscard +CX_EXPORT cxstring cx_strsubsl_(cxstring string, size_t start, size_t length); + +/** + * Returns a substring. + * + * Internal function - do not use. * * @param string input string * @param start start location of the substring * @return a substring of @p string starting at @p start + * @see cx_strsubs() + */ +cx_attr_nodiscard +CX_EXPORT cxstring cx_strsubs_(cxstring string, size_t start); + +CX_INLINE cxmutstr cx_strsubs_m_(cxmutstr string, size_t start) { + return cx_mutstrcast(cx_strsubs_(cx_strcast(string), start)); +} + +CX_INLINE cxmutstr cx_strsubsl_m_(cxmutstr string, size_t start, size_t length) { + return cx_mutstrcast(cx_strsubsl_(cx_strcast(string), start, length)); +} + +#ifdef __cplusplus +} // extern "C" +CX_CPPDECL cxstring cx_strsubs_cpp_(cxstring string, size_t start) { + return cx_strsubs_(string, start); +} +CX_CPPDECL cxstring cx_strsubsl_cpp_(cxstring string, size_t start, size_t length) { + return cx_strsubsl_(string, start, length); +} +CX_CPPDECL cxmutstr cx_strsubs_cpp_(cxmutstr string, size_t start) { + return cx_strsubs_m_(string, start); +} +CX_CPPDECL cxmutstr cx_strsubsl_cpp_(cxmutstr string, size_t start, size_t length) { + return cx_strsubsl_m_(string, start, length); +} +#define cx_strsubs(string, start) cx_strsubs_cpp_(cx_strcast_m(string), start) +#define cx_strsubsl(string, start, length) cx_strsubsl_cpp_(cx_strcast_m(string), start, length) +extern "C" { +#else +/** + * Returns a substring starting at the specified location. + * + * @attention the new string references the same memory area as the + * input string and is @em not zero-terminated. + * Use cx_strdup() to get a copy. + * + * @param string input string + * @param start (@c size_t) start location of the substring + * @return (@c cxstring or @c cxmutstr) a substring of @p string starting at @p start * * @see cx_strsubsl() - * @see cx_strsubs_m() - * @see cx_strsubsl_m() */ -cx_attr_nodiscard -CX_EXPORT cxstring cx_strsubs(cxstring string, size_t start); +#define cx_strsubs(string, start) _Generic(cx_strcast_m(string), \ + cxstring: cx_strsubs_, \ + cxmutstr: cx_strsubs_m_)(cx_strcast_m(string), start) /** * Returns a substring starting at the specified location. @@ -563,51 +628,11 @@ * @return a substring of @p string starting at @p start * * @see cx_strsubs() - * @see cx_strsubs_m() - * @see cx_strsubsl_m() */ -cx_attr_nodiscard -CX_EXPORT cxstring cx_strsubsl(cxstring string, size_t start, size_t length); - -/** - * Returns a substring starting at the specified location. - * - * @attention the new string references the same memory area as the - * input string and is usually @em not zero-terminated. - * Use cx_strdup() to get a copy. - * - * @param string input string - * @param start start location of the substring - * @return a substring of @p string starting at @p start - * - * @see cx_strsubsl_m() - * @see cx_strsubs() - * @see cx_strsubsl() - */ -cx_attr_nodiscard -CX_EXPORT cxmutstr cx_strsubs_m(cxmutstr string, size_t start); - -/** - * Returns a substring starting at the specified location. - * - * The returned string will be limited to @p length bytes or the number - * of bytes available in @p string, whichever is smaller. - * - * @attention the new string references the same memory area as the - * input string and is usually @em not zero-terminated. - * Use cx_strdup() to get a copy. - * - * @param string input string - * @param start start location of the substring - * @param length the maximum length of the returned string - * @return a substring of @p string starting at @p start - * - * @see cx_strsubs_m() - * @see cx_strsubs() - * @see cx_strsubsl() - */ -cx_attr_nodiscard -CX_EXPORT cxmutstr cx_strsubsl_m(cxmutstr string, size_t start, size_t length); +#define cx_strsubsl(string, start, length) _Generic(cx_strcast_m(string), \ + cxstring: cx_strsubsl_, \ + cxmutstr: cx_strsubsl_m_)(cx_strcast_m(string), start, length) +#endif /** * Returns the character at the specified index offset.