From f95a698b94069ed03f6a8f2d0f7eb089d66c91ef Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 23 Oct 2022 12:58:06 -0400 Subject: Add string view API --- include/zix/attributes.h | 8 ++-- include/zix/string_view.h | 107 ++++++++++++++++++++++++++++++++++++++++++++++ include/zix/zix.h | 1 + 3 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 include/zix/string_view.h (limited to 'include') diff --git a/include/zix/attributes.h b/include/zix/attributes.h index 1fe1183..b076fa7 100644 --- a/include/zix/attributes.h +++ b/include/zix/attributes.h @@ -34,13 +34,15 @@ // GCC function attributes #ifdef __GNUC__ +# define ZIX_ALWAYS_INLINE_FUNC __attribute__((always_inline)) # define ZIX_PURE_FUNC __attribute__((pure)) # define ZIX_CONST_FUNC __attribute__((const)) # define ZIX_MALLOC_FUNC __attribute__((malloc)) #else -# define ZIX_PURE_FUNC ///< Only reads memory -# define ZIX_CONST_FUNC ///< Only reads its parameters -# define ZIX_MALLOC_FUNC ///< Allocates memory +# define ZIX_ALWAYS_INLINE_FUNC ///< Should absolutely always be inlined +# define ZIX_PURE_FUNC ///< Only reads memory +# define ZIX_CONST_FUNC ///< Only reads its parameters +# define ZIX_MALLOC_FUNC ///< Allocates memory #endif /// A pure function in the public API that only reads memory diff --git a/include/zix/string_view.h b/include/zix/string_view.h new file mode 100644 index 0000000..f4cd6c2 --- /dev/null +++ b/include/zix/string_view.h @@ -0,0 +1,107 @@ +// Copyright 2011-2021 David Robillard +// SPDX-License-Identifier: ISC + +#ifndef ZIX_STRING_VIEW_H +#define ZIX_STRING_VIEW_H + +#include "zix/allocator.h" +#include "zix/attributes.h" + +#include +#include + +ZIX_BEGIN_DECLS + +/** + @defgroup zix_string_view String View + @ingroup zix_utilities + @{ +*/ + +/** + An immutable slice of a string. + + This type is used for many string parameters, to allow referring to slices + of strings in-place and to avoid redundant string measurement. +*/ +typedef struct { + const char* ZIX_NONNULL data; ///< Pointer to the first character + size_t length; ///< Length of string in bytes +} ZixStringView; + +/// Return a view of an empty string +ZIX_ALWAYS_INLINE_FUNC +ZIX_CONST_FUNC +static inline ZixStringView +zix_empty_string(void) +{ + const ZixStringView view = {"", 0U}; + return view; +} + +/** + Return a view of a substring, or a premeasured string. + + This makes either a view of a slice of a string (which may not be null + terminated), or a view of a string that has already been measured. This is + faster than zix_string() for dynamic strings since it does not call + `strlen`, so should be used when the length of the string is already known. + + @param str Pointer to the start of the substring. + + @param len Length of the substring in bytes, not including the trailing null + terminator if present. +*/ +ZIX_ALWAYS_INLINE_FUNC +ZIX_CONST_FUNC +static inline ZixStringView +zix_substring(const char* const ZIX_NONNULL str, const size_t len) +{ + const ZixStringView view = {str, len}; + return view; +} + +/** + Return a view of an entire string by measuring it. + + This makes a view of the given string by measuring it with `strlen`. + + @param str Pointer to the start of a null-terminated C string, or null. +*/ +ZIX_ALWAYS_INLINE_FUNC +ZIX_PURE_FUNC +static inline ZixStringView +zix_string(const char* const ZIX_NONNULL str) +{ + const ZixStringView view = {str, strlen(str)}; + return view; +} + +/** + Return a view of an entire string by measuring it. + + This makes a view of the given string by measuring it with `strlen`. + + @param str Pointer to the start of a null-terminated C string, or null. +*/ +ZIX_PURE_FUNC +static inline ZixStringView +zix_optional_string(const char* const ZIX_NULLABLE str) +{ + return str ? zix_string(str) : zix_empty_string(); +} + +/** + Copy a string view into a newly allocated null-terminated string. +*/ +ZIX_API +char* ZIX_ALLOCATED +zix_string_view_copy(ZixAllocator* ZIX_NULLABLE allocator, ZixStringView view); + +/** + @} +*/ + +ZIX_END_DECLS + +#endif // ZIX_STRING_VIEW_H diff --git a/include/zix/zix.h b/include/zix/zix.h index 02ab31f..223d1dc 100644 --- a/include/zix/zix.h +++ b/include/zix/zix.h @@ -20,6 +20,7 @@ #include "zix/digest.h" #include "zix/function_types.h" #include "zix/status.h" +#include "zix/string_view.h" /** @} -- cgit v1.2.1