str/cexpr: Add a function to make a constexpr generated string
This allows the user to generate an arbitrary length string at compile
time and convert it automatically to an std::array that is embedded in
the program for zero overhead runtime strings.
Change-Id: Ib6c2dd20cac53bb55e7a32e2fca194bdf0e06211
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/meson.build b/include/meson.build
index dc4de82..c3bfdfe 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -10,6 +10,7 @@
'stdplus/raw.hpp',
'stdplus/signal.hpp',
'stdplus/str/cat.hpp',
+ 'stdplus/str/cexpr.hpp',
'stdplus/util/cexec.hpp',
'stdplus/util/string.hpp',
'stdplus/zstring.hpp',
diff --git a/include/stdplus/str/cexpr.hpp b/include/stdplus/str/cexpr.hpp
new file mode 100644
index 0000000..a3d5f1c
--- /dev/null
+++ b/include/stdplus/str/cexpr.hpp
@@ -0,0 +1,38 @@
+#pragma once
+#include <algorithm>
+#include <array>
+#include <string_view>
+
+namespace stdplus
+{
+
+template <auto f, bool nul>
+consteval auto cexprToStrArr()
+{
+ std::array<typename decltype(f())::value_type, f().size() + (nul ? 1 : 0)>
+ ret;
+ {
+ auto res = f();
+ std::copy(res.begin(), res.end(), ret.begin());
+ if constexpr (nul)
+ {
+ ret[ret.size() - 1] = '\0';
+ }
+ }
+ return ret;
+}
+
+template <auto f, bool nul>
+inline constexpr auto cexprStrArr = cexprToStrArr<f, nul>();
+
+template <auto f>
+consteval auto cexprToSv()
+{
+ constexpr auto& d = cexprStrArr<f, /*nul=*/false>;
+ return std::basic_string_view(d.begin(), d.end());
+}
+
+template <auto f>
+inline constexpr auto cexprSv = cexprToSv<f>();
+
+} // namespace stdplus
diff --git a/include/stdplus/zstring_view.hpp b/include/stdplus/zstring_view.hpp
index 79003bd..0c18bfb 100644
--- a/include/stdplus/zstring_view.hpp
+++ b/include/stdplus/zstring_view.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <fmt/core.h>
+#include <stdplus/str/cexpr.hpp>
#include <stdplus/zstring.hpp>
#include <stdexcept>
@@ -318,6 +319,19 @@
}
} // namespace zstring_view_literals
+template <auto f>
+consteval auto cexprToZsv()
+{
+ constexpr auto& d = cexprStrArr<f, /*nul=*/true>;
+ static_assert(detail::zstring_find_term(d.data(), d.size() - 1, d.size()) >=
+ 0);
+ return detail::unsafe_zstring_view(
+ std::basic_string_view(d.begin(), d.end() - 1));
+}
+
+template <auto f>
+inline constexpr auto cexprZsv = cexprToZsv<f>();
+
} // namespace stdplus
#define zstring_view_all(char_t, pfx) \