Skip to content

Commit

Permalink
format_string_for_each_named_arg
Browse files Browse the repository at this point in the history
Summary: To replace uses of `folly::defaulted` with `folly::svformat`.

Reviewed By: dmm-fb

Differential Revision: D67211009

fbshipit-source-id: 303d99eca714aac80b45220b72c8012a2816e1dd
  • Loading branch information
yfeldblum authored and facebook-github-bot committed Dec 16, 2024
1 parent 1acde9a commit 132d899
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
31 changes: 31 additions & 0 deletions folly/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,37 @@ inline bool hasSpaceOrCntrlSymbols(folly::StringPiece s) {
return detail::simdHasSpaceOrCntrlSymbols(s);
}

struct format_string_for_each_named_arg_fn {
template <typename C, typename CT, typename Fn>
constexpr void operator()(std::basic_string_view<C, CT> str, Fn fn) const
noexcept(noexcept(fn(str))) {
using view = std::basic_string_view<C, CT>;
while (true) {
auto const pos = str.find('{');
auto const beg = pos == view::npos ? str.size() : pos + 1;
if (beg == str.size()) {
return; // malformed
}
if (str[beg] == '{') {
str = str.substr(beg + 1);
continue; // escaped
}
auto const end = std::min(str.find('}', pos), str.find(':', pos));
if (end == view::npos) {
return; // malformed
}
auto const arg = str.substr(beg, end - beg);
if (!arg.empty() && (arg[0] == '_' || std::isalpha(arg[0]))) {
fn(arg);
}
str = str.substr(beg);
}
}
};

inline constexpr format_string_for_each_named_arg_fn
format_string_for_each_named_arg{};

} // namespace folly

#include <folly/String-inl.h>
1 change: 1 addition & 0 deletions folly/test/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,7 @@ cpp_unittest(
"//folly:fbvector",
"//folly:string",
"//folly/container:array",
"//folly/portability:gmock",
"//folly/portability:gtest",
],
external_deps = [
Expand Down
22 changes: 22 additions & 0 deletions folly/test/StringTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <folly/FBVector.h>
#include <folly/container/Array.h>
#include <folly/portability/GMock.h>
#include <folly/portability/GTest.h>
#include <folly/test/TestUtils.h>

Expand Down Expand Up @@ -1466,3 +1467,24 @@ TEST(String, hasSpaceOrCntrlSymbolsTest) {
ASSERT_TRUE(std::iscntrl(1));
ASSERT_TRUE(hasSpaceOrCntrlSymbols(hasCntrl));
}

TEST(String, format_string_for_each_named_arg) {
auto const fn = [](std::string_view str) {
std::vector<std::string> out;
folly::format_string_for_each_named_arg(str, [&](auto sub) {
out.push_back(std::string(sub));
});
return out;
};
EXPECT_THAT(fn(""), testing::ElementsAre());
EXPECT_THAT(fn("hello"), testing::ElementsAre());
EXPECT_THAT(fn("{{}}"), testing::ElementsAre());
EXPECT_THAT(fn("hello{{}}world"), testing::ElementsAre());
EXPECT_THAT(fn("hello{}world"), testing::ElementsAre());
EXPECT_THAT(fn("hello{3}world"), testing::ElementsAre());
EXPECT_THAT(fn("hello{34}world"), testing::ElementsAre());
EXPECT_THAT(fn("hello{bob}world"), testing::ElementsAre("bob"));
EXPECT_THAT(fn("hello{3}world{bob}go"), testing::ElementsAre("bob"));
EXPECT_THAT(fn("hello{bob}world{3}go"), testing::ElementsAre("bob"));
EXPECT_THAT(fn("hello{bob}world{sam}go"), testing::ElementsAre("bob", "sam"));
}

0 comments on commit 132d899

Please sign in to comment.