basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | ffa7d35ed8baeff0e5db817445a5a55d494718d1 |
parent | e2e839a3bc872c30a3de628a2d3caf72d95660aa |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Thu, 12 Jun 2025 20:24:12 +0200 |
Simple string format utility
A | include/based/string/format.hpp | | | ++++++++++++++++++++++++++++ |
M | test/CMakeLists.txt | | | ++ - |
A | test/source/string/format_test.cpp | | | ++++++++++++++++++++++++++++++++ |
A | test/source/string/literal_test.cpp | | | ++++++++++++++++++++++++++++++++++++++ |
D | test/source/string_literal_test.cpp | | | -------------------------------------- |
5 files changed, 100 insertions(+), 39 deletions(-)
diff --git a/ include/based/string/format.hpp b/ include/based/string/format.hpp
@@ -0,0 +1,28 @@
#pragma once
#include <string>
#include <string_view>
namespace based
{
constexpr auto string_format(std::string_view format, auto... args)
{
std::string_view::size_type last = 0;
std::string res;
const auto func = [&](std::string_view arg)
{
if (auto pos = format.find("{}", last); pos != std::string_view::npos) {
res += format.substr(last, pos - last);
res += arg;
last = pos + 2;
}
};
(func(args), ...);
res += format.substr(last, std::size(format) - last);
return res;
}
} // namespace based
diff --git a/ test/CMakeLists.txt b/ test/CMakeLists.txt
@@ -84,7 +84,8 @@
add_test(. list_test)
## ----- String -----
add_test(. string_literal_test)
add_test(string literal_test)
add_test(string format_test)
## ----- Char -----
diff --git a/ test/source/string/format_test.cpp b/ test/source/string/format_test.cpp
@@ -0,0 +1,32 @@
#include "based/string/format.hpp"
#include <catch2/catch_test_macros.hpp>
TEST_CASE("format", "[string/format]")
{
const std::string format = "This is a {}! {}";
SECTION("none")
{
const auto res = based::string_format(format);
REQUIRE(res == "This is a {}! {}");
}
SECTION("one")
{
const auto res = based::string_format(format, "test");
REQUIRE(res == "This is a test! {}");
}
SECTION("two")
{
const auto res = based::string_format(format, "test", "hello");
REQUIRE(res == "This is a test! hello");
}
SECTION("three")
{
const auto res = based::string_format(format, "test", "hello", "yo");
REQUIRE(res == "This is a test! hello");
}
}
diff --git a/ test/source/string/literal_test.cpp b/ test/source/string/literal_test.cpp
@@ -0,0 +1,38 @@
#include <catch2/catch_test_macros.hpp>
#include "based/string/literal.hpp"
TEST_CASE("empty", "[string/literal]")
{
const based::string_literal sltr = "";
REQUIRE(sltr.size() == 1);
REQUIRE(std::memcmp(sltr.data(), "", sltr.size()) == 0);
}
TEST_CASE("nonempty", "[string/literal]")
{
const based::string_literal sltr = "nonempty";
REQUIRE(sltr.size() == 9);
REQUIRE(std::memcmp(sltr.data(), "nonempty", sltr.size()) == 0);
}
TEST_CASE("template", "[string/literal]")
{
const auto data = []<based::string_literal l>()
{
return l.data();
};
const auto size = []<based::string_literal l>()
{
return l.size();
};
REQUIRE(size.operator()<"">() == 1);
REQUIRE(size.operator()<"nonempty">() == 9);
REQUIRE(std::memcmp(data.operator()<"">(), "", 1) == 0);
REQUIRE(std::memcmp(data.operator()<"nonempty">(), "nonempty", 9) == 0);
}
diff --git a/ test/source/string_literal_test.cpp b/ test/source/string_literal_test.cpp
@@ -1,38 +0,0 @@
#include <catch2/catch_test_macros.hpp>
#include "based/string/literal.hpp"
TEST_CASE("empty", "[string/string_literal]")
{
const based::string_literal sltr = "";
REQUIRE(sltr.size() == 1);
REQUIRE(std::memcmp(sltr.data(), "", sltr.size()) == 0);
}
TEST_CASE("nonempty", "[string/string_literal]")
{
const based::string_literal sltr = "nonempty";
REQUIRE(sltr.size() == 9);
REQUIRE(std::memcmp(sltr.data(), "nonempty", sltr.size()) == 0);
}
TEST_CASE("template", "[string/string_literal]")
{
const auto data = []<based::string_literal l>()
{
return l.data();
};
const auto size = []<based::string_literal l>()
{
return l.size();
};
REQUIRE(size.operator()<"">() == 1);
REQUIRE(size.operator()<"nonempty">() == 9);
REQUIRE(std::memcmp(data.operator()<"">(), "", 1) == 0);
REQUIRE(std::memcmp(data.operator()<"nonempty">(), "nonempty", 9) == 0);
}