From b4cc6ed754d32891f725ae6f4d6be127f328cadd Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 6 May 2021 12:39:41 -0500 Subject: [PATCH] [ox/std] Add sfmt (synced from 462f5b580b3f868b0ba624db7e1ba25a15c059d9) --- src/ox/std/CMakeLists.txt | 1 + src/ox/std/fmt.cpp | 74 ++++++++++++++++++++++++++++++++ src/ox/std/fmt.hpp | 89 +++++++++++---------------------------- 3 files changed, 99 insertions(+), 65 deletions(-) create mode 100644 src/ox/std/fmt.cpp diff --git a/src/ox/std/CMakeLists.txt b/src/ox/std/CMakeLists.txt index b81362458..cf71badd8 100644 --- a/src/ox/std/CMakeLists.txt +++ b/src/ox/std/CMakeLists.txt @@ -22,6 +22,7 @@ add_library( buffer.cpp buildinfo.cpp byteswap.cpp + fmt.cpp heapmgr.cpp memops.cpp random.cpp diff --git a/src/ox/std/fmt.cpp b/src/ox/std/fmt.cpp new file mode 100644 index 000000000..26a4d408f --- /dev/null +++ b/src/ox/std/fmt.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2015 - 2021 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "fmt.hpp" + +namespace ox::detail { + +static_assert(argCount("sadf asdf") == 0); +static_assert(argCount("{}") == 1); +static_assert(argCount("{}{}") == 2); +static_assert(argCount("thing1: {}, thing2: {}") == 2); +static_assert(argCount("thing1: {}, thing2: {}{}") == 3); + +static_assert([] { + constexpr auto fmt = "{}"; + return fmtSegments(fmt) == Fmt<2>{ + { + {"", 0}, + {"", 0}, + } + }; + }() +); +static_assert([] { + constexpr auto fmt = "thing: {}"; + return fmtSegments(fmt) == Fmt<2>{ + { + {"thing: ", 7}, + {"", 0}, + } + }; + }() +); +static_assert([] { + constexpr auto fmt = "thing: {}, thing2: {}"; + return fmtSegments(fmt) == Fmt<3>{ + { + {"thing: ", 7}, + {", thing2: ", 10}, + {"", 0}, + } + }; + }() +); +static_assert([] { + constexpr auto fmt = "thing: {}, thing2: {}s"; + return fmtSegments(fmt) == Fmt<3>{ + { + {"thing: ", 7}, + {", thing2: ", 10}, + {"s", 1}, + } + }; + }() +); +static_assert([] { + constexpr auto fmt = "loadTexture: section: {}, w: {}, h: {}"; + return fmtSegments(fmt) == Fmt<4>{ + { + {"loadTexture: section: ", 22}, + {", w: ", 5}, + {", h: ", 5}, + } + }; + }() +); + + +} diff --git a/src/ox/std/fmt.hpp b/src/ox/std/fmt.hpp index 4458ef3c8..147dfbf8b 100644 --- a/src/ox/std/fmt.hpp +++ b/src/ox/std/fmt.hpp @@ -16,13 +16,15 @@ #include #endif -#include -#include -#include -#include -#include +#include "assert.hpp" +#include "bstring.hpp" +#include "string.hpp" +#include "strops.hpp" +#include "types.hpp" +#include "typetraits.hpp" -namespace ox::detail { +namespace ox { +namespace detail { constexpr const char *stringify(const char *s) noexcept { return s; @@ -89,12 +91,6 @@ constexpr uint64_t argCount(const char *str) noexcept { return cnt; } -static_assert(argCount("sadf asdf") == 0); -static_assert(argCount("{}") == 1); -static_assert(argCount("{}{}") == 2); -static_assert(argCount("thing1: {}, thing2: {}") == 2); -static_assert(argCount("thing1: {}, thing2: {}{}") == 3); - struct FmtSegment { const char *str = nullptr; unsigned length = 0; @@ -156,59 +152,22 @@ constexpr Fmt fmtSegments(const char *fmt) noexcept { return out; } -static_assert([] { - constexpr auto fmt = "{}"; - return fmtSegments(fmt) == Fmt<2>{ - { - {"", 0}, - {"", 0}, - } - }; - }() -); -static_assert([] { - constexpr auto fmt = "thing: {}"; - return fmtSegments(fmt) == Fmt<2>{ - { - {"thing: ", 7}, - {"", 0}, - } - }; - }() -); -static_assert([] { - constexpr auto fmt = "thing: {}, thing2: {}"; - return fmtSegments(fmt) == Fmt<3>{ - { - {"thing: ", 7}, - {", thing2: ", 10}, - {"", 0}, - } - }; - }() -); -static_assert([] { - constexpr auto fmt = "thing: {}, thing2: {}s"; - return fmtSegments(fmt) == Fmt<3>{ - { - {"thing: ", 7}, - {", thing2: ", 10}, - {"s", 1}, - } - }; - }() -); -static_assert([] { - constexpr auto fmt = "loadTexture: section: {}, w: {}, h: {}"; - return fmtSegments(fmt) == Fmt<4>{ - { - {"loadTexture: section: ", 22}, - {", w: ", 5}, - {", h: ", 5}, - } - }; - }() -); +} +template +auto sfmt(const char *fmt, Args... args) noexcept { + oxAssert(ox::detail::argCount(fmt) == sizeof...(args), "Argument count mismatch."); + StringType out; + const auto fmtSegments = ox::detail::fmtSegments(fmt); + const auto &firstSegment = fmtSegments.segments[0]; + out.append(firstSegment.str, firstSegment.length); + const detail::FmtArg elements[sizeof...(args)] = {args...}; + for (auto i = 0u; i < fmtSegments.size - 1; ++i) { + out += elements[i].out; + const auto &s = fmtSegments.segments[i + 1]; + out.append(s.str, s.length); + } + return move(out); +} }