Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions data/doxygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ namespace gul17 {
*
* \section changelog_gul17 GUL17 Versions
*
* \subsection UNRELEASED To be released
*
* - Add gul17::null_safe_string_view(const char*, std::size_t), which returns an empty
* string_view if given a null pointer.
*
* \subsection V25_7_0 Version 25.7.0
*
* - Add gul17::null_safe_string(const char*) and
Expand Down
55 changes: 41 additions & 14 deletions include/gul17/string_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,41 +230,66 @@ hex_string(const Container& container, std::string_view separator = "")
* to find a zero-terminated C string and constructs a std::string from it.
*
* \code
* auto a = safe_string(nullptr); // a == ""s
* auto b = safe_string("ABC"); // b == "ABC"s
* auto c = safe_string("AB\0CD"); // c == "AB"s
* auto a = null_safe_string(nullptr); // a == ""s
* auto b = null_safe_string("ABC"); // b == "ABC"s
* auto c = null_safe_string("AB\0CD"); // c == "AB"s
* \endcode
*
* \param char_ptr Pointer to a null-terminated string or a null pointer
*
* \see safe_string(), null_safe_string_view()
* \see null_safe_string_view(), safe_string(), safe_string_view()
*
* \since version 25.7.0
*/
GUL_EXPORT
std::string null_safe_string(const char* char_ptr);

/**
* Safely construct a string_view from a char pointer.
* Safely construct a string_view from a C string or a null pointer.
*
* If the pointer is null, an empty string_view is constructed. Otherwise, the function
* If the pointer is null, an empty string_view is constructed. Otherwise, the function
* assumes to find a zero-terminated C string and constructs a std::string_view from it.
*
* \code
* auto a = safe_string_view(nullptr); // a == ""sv
* auto b = safe_string_view("ABC"); // b == "ABC"sv
* auto c = safe_string_view("AB\0CD"); // c == "AB"sv
* auto a = null_safe_string_view(nullptr); // a == ""sv
* auto b = null_safe_string_view("ABC"); // b == "ABC"sv
* auto c = null_safe_string_view("AB\0CD"); // c == "AB"sv
* \endcode
*
* \param char_ptr Pointer to a null-terminated string or a null pointer
*
* \see safe_string_view(), null_safe_string()
* \see null_safe_string(), safe_string(), safe_string_view()
*
* \since version 25.7.0
*/
GUL_EXPORT
std::string_view null_safe_string_view(const char* char_ptr);

/**
* Safely construct a string_view from a char pointer and a length; intermediate null
* bytes do not terminate the string.
*
* If the pointer is null, an empty string_view is constructed. Otherwise, the function
* constructs a std::string_view with the specified length from it. Zero bytes in the
* input range do not terminate the string_view.
*
* \code
* auto a = null_safe_string_view(nullptr, 10); // a == ""sv
* auto b = null_safe_string_view("ABC", 4); // b == "ABC\0"sv
* auto c = null_safe_string_view("AB\0CD", 4); // c == "AB\0C"sv
* \endcode
*
* \param char_ptr Pointer to a string with at least \c length accessible bytes, or a
* null pointer
* \param length Length of the generated string_view (unless the pointer is null)
*
* \see null_safe_string(), safe_string(), safe_string_view()
*
* \since version UNRELEASED
*/
GUL_EXPORT
std::string_view null_safe_string_view(const char* char_ptr, std::size_t length);

/**
* Repeat a string N times.
* \code
Expand All @@ -282,7 +307,8 @@ GUL_EXPORT
std::string repeat(std::string_view str, std::size_t n);

/**
* Safely construct a std::string from a char pointer and a length.
* Safely construct a std::string from a char pointer and a length, respecting null
* termination in the style of a C string.
*
* If the pointer is null, an empty string is constructed. If there are no zero bytes in
* the input range, a string of length \c length is constructed. Otherwise, the input
Expand All @@ -300,15 +326,16 @@ std::string repeat(std::string_view str, std::size_t n);
* \c length accessible bytes, or a null pointer
* \param length Maximum length of the generated string
*
* \see null_safe_string(), safe_string_view()
* \see null_safe_string(), null_safe_string_view(), safe_string_view()
*
* \since GUL version 2.6
*/
GUL_EXPORT
std::string safe_string(const char* char_ptr, std::size_t length);

/**
* Safely construct a string_view from a char pointer and a length.
* Safely construct a string_view from a char pointer and a length, respecting null
* termination in the style of a C string.
*
* If the pointer is null, an empty string_view is constructed. If there are no zero bytes
* in the input range, a string_view of length \c length is constructed. Otherwise, the
Expand All @@ -326,7 +353,7 @@ std::string safe_string(const char* char_ptr, std::size_t length);
* \c length accessible bytes, or a null pointer
* \param length Maximum length of the generated string_view
*
* \see null_safe_string_view(), safe_string()
* \see null_safe_string(), null_safe_string_view(), safe_string()
*
* \since GUL version 25.4.0
*/
Expand Down
10 changes: 10 additions & 0 deletions src/string_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ std::string_view null_safe_string_view(const char* char_ptr)
return result;
}

std::string_view null_safe_string_view(const char* char_ptr, std::size_t length)
{
std::string_view result;

if (char_ptr)
result = std::string_view(char_ptr, length);

return result;
}

std::string repeat(std::string_view str, std::size_t n)
{
std::string result;
Expand Down
14 changes: 14 additions & 0 deletions tests/test_string_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ TEST_CASE("null_safe_string_view(const char*)", "[string_util]")
REQUIRE(null_safe_string_view("hi\0there") == "hi"sv);
}

TEST_CASE("null_safe_string_view(const char*, std::size_t)", "[string_util]")
{
using gul17::null_safe_string_view;

REQUIRE(null_safe_string_view(nullptr, 0ull) == std::string_view{});
REQUIRE(null_safe_string_view(nullptr, 10ull) == std::string_view{});
REQUIRE(null_safe_string_view("", 0ull) == ""sv);
REQUIRE(null_safe_string_view("", 1ull) == "\0"sv);
REQUIRE(null_safe_string_view("hello", 5ull) == "hello"sv);
REQUIRE(null_safe_string_view("hello", 2ull) == "he"sv);
REQUIRE(null_safe_string_view("hi\0there", 2ull) == "hi"sv);
REQUIRE(null_safe_string_view("hi\0there", 4ull) == "hi\0t"sv);
}

TEST_CASE("repeat()", "[string_util]")
{
REQUIRE(repeat("du", 3) == "dududu");
Expand Down
Loading