util/string: Expand string types and constexpr
It is useful to allow wide strings and other string types.
Now that c++20 strings are constexpr, we want these functions to be
constexpr too.
Change-Id: I8699f938332ea20e7873f5b5432f51711942ac0f
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/util/string.hpp b/include/stdplus/util/string.hpp
index fad0d7a..70af77d 100644
--- a/include/stdplus/util/string.hpp
+++ b/include/stdplus/util/string.hpp
@@ -1,5 +1,4 @@
#pragma once
-#include <cstring>
#include <string>
#include <string_view>
#include <utility>
@@ -11,13 +10,34 @@
namespace detail
{
-template <typename... Views>
-void strAppendViews(std::string& dst, Views... views)
+template <typename CharT, typename Traits, typename Alloc, typename... Views>
+constexpr void strAppendViews(std::basic_string<CharT, Traits, Alloc>& dst,
+ Views... views)
{
dst.reserve((dst.size() + ... + views.size()));
(dst.append(views), ...);
}
+template <typename CharT,
+ typename Traits = std::basic_string_view<CharT>::traits_type>
+struct DedSV : std::basic_string_view<CharT, Traits>
+{
+ template <typename... Args>
+ constexpr DedSV(Args&&... args) :
+ std::basic_string_view<CharT, Traits>(std::forward<Args>(args)...)
+ {
+ }
+};
+
+template <typename CharT>
+DedSV(const CharT*) -> DedSV<CharT>;
+
+template <typename CharT, typename Traits, typename Alloc>
+DedSV(const std::basic_string<CharT, Traits, Alloc>&) -> DedSV<CharT, Traits>;
+
+template <typename CharT, typename Traits>
+DedSV(std::basic_string_view<CharT, Traits>) -> DedSV<CharT, Traits>;
+
} // namespace detail
/** @brief Converts the string into its underlying nul-terminated c-str
@@ -27,7 +47,7 @@
*/
template <typename Str, typename = std::enable_if_t<
std::is_same_v<std::remove_cv_t<Str>, std::string>>>
-auto cStr(Str& str)
+constexpr auto cStr(Str& str)
{
return str.data();
}
@@ -36,7 +56,7 @@
typename = std::enable_if_t<
std::is_pointer_v<Str> &&
std::is_same_v<std::remove_cv_t<std::remove_pointer_t<Str>>, char>>>
-auto cStr(Str str)
+constexpr auto cStr(Str str)
{
return str;
}
@@ -47,10 +67,11 @@
* @param[in, out] dst - The string being appended to
* @param[in] ...strs - An arbitrary number of strings to concatenate
*/
-template <typename... Strs>
-void strAppend(std::string& dst, const Strs&... strs)
+template <typename CharT, typename Traits, typename Alloc, typename... Strs>
+constexpr void strAppend(std::basic_string<CharT, Traits, Alloc>& dst,
+ const Strs&... strs)
{
- detail::strAppendViews(dst, std::string_view(strs)...);
+ detail::strAppendViews(dst, detail::DedSV(strs)...);
}
/** @brief Concatenates multiple strings together in the most optimal
@@ -59,17 +80,21 @@
* @param[in] ...strs - An arbitrary number of strings to concatenate
* @return The concatenated result string
*/
-template <typename... Strs>
-std::string strCat(const Strs&... strs)
+template <typename CharT = char,
+ typename Traits = std::basic_string<CharT>::traits_type,
+ typename Alloc = std::basic_string<CharT>::allocator_type,
+ typename... Strs>
+constexpr std::basic_string<CharT, Traits, Alloc> strCat(const Strs&... strs)
{
- std::string ret;
+ std::basic_string<CharT, Traits, Alloc> ret;
strAppend(ret, strs...);
return ret;
}
-template <typename... Strs>
-std::string strCat(std::string&& in, const Strs&... strs)
+template <typename CharT, typename Traits, typename Alloc, typename... Strs>
+constexpr std::basic_string<CharT, Traits, Alloc>
+ strCat(std::basic_string<CharT, Traits, Alloc>&& in, const Strs&... strs)
{
- std::string ret = std::move(in);
+ std::basic_string<CharT, Traits, Alloc> ret = std::move(in);
strAppend(ret, strs...);
return ret;
}