Skip to content

Commit

Permalink
Add strip_if_parts
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoinePrv committed Mar 13, 2023
1 parent dbacafd commit a130485
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 12 deletions.
87 changes: 75 additions & 12 deletions libmamba/include/mamba/core/util_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ namespace mamba
template <typename UnaryFunc>
std::wstring_view lstrip_if(std::wstring_view input, UnaryFunc should_strip);

template <typename UnaryFunc>
std::array<std::string_view, 2> lstrip_if_parts(std::string_view input, UnaryFunc should_strip);
template <typename UnaryFunc>
std::array<std::wstring_view, 2> lstrip_if_parts(std::wstring_view input, UnaryFunc should_strip);

std::string_view rstrip(std::string_view input, char c);
std::wstring_view rstrip(std::wstring_view input, wchar_t c);
std::string_view rstrip(std::string_view input, std::string_view chars);
Expand All @@ -128,6 +133,11 @@ namespace mamba
template <typename UnaryFunc>
std::wstring_view rstrip_if(std::wstring_view input, UnaryFunc should_strip);

template <typename UnaryFunc>
std::array<std::string_view, 2> rstrip_if_parts(std::string_view input, UnaryFunc should_strip);
template <typename UnaryFunc>
std::array<std::wstring_view, 2> rstrip_if_parts(std::wstring_view input, UnaryFunc should_strip);

std::string_view strip(std::string_view input, char c);
std::wstring_view strip(std::wstring_view input, wchar_t c);
std::string_view strip(std::string_view input, std::string_view chars);
Expand All @@ -145,6 +155,11 @@ namespace mamba
template <typename UnaryFunc>
std::wstring_view strip_if(std::wstring_view input, UnaryFunc should_strip);

template <typename UnaryFunc>
std::array<std::string_view, 3> strip_if_parts(std::string_view input, UnaryFunc should_strip);
template <typename UnaryFunc>
std::array<std::wstring_view, 3> strip_if_parts(std::wstring_view input, UnaryFunc should_strip);

std::array<std::string_view, 2> split_once(std::string_view input, char sep);
std::array<std::wstring_view, 2> split_once(std::wstring_view input, wchar_t sep);
std::array<std::string_view, 2> split_once(std::string_view input, std::string_view sep);
Expand Down Expand Up @@ -324,69 +339,117 @@ namespace mamba
namespace detail
{
template <typename Char, typename UnaryFunc>
std::basic_string_view<Char>
lstrip_if_impl(std::basic_string_view<Char> input, UnaryFunc should_strip)
std::array<std::basic_string_view<Char>, 2>
lstrip_if_parts_impl(std::basic_string_view<Char> input, UnaryFunc should_strip)
{
const auto start_iter = std::find_if(
input.cbegin(),
input.cend(),
[&should_strip](Char c) -> bool { return !should_strip(c); }
);
const auto start_idx = static_cast<std::size_t>(start_iter - input.cbegin());
return input.substr(start_idx);
return { input.substr(0, start_idx), input.substr(start_idx) };
}
}

template <typename UnaryFunc>
std::string_view lstrip_if(std::string_view input, UnaryFunc should_strip)
{
return detail::lstrip_if_impl(input, std::move(should_strip));
return lstrip_if_parts(input, std::move(should_strip))[1];
}

template <typename UnaryFunc>
std::wstring_view lstrip_if(std::wstring_view input, UnaryFunc should_strip)
{
return detail::lstrip_if_impl(input, std::move(should_strip));
return lstrip_if_parts(input, std::move(should_strip))[1];
}

template <typename UnaryFunc>
std::array<std::string_view, 2> lstrip_if_parts(std::string_view input, UnaryFunc should_strip)
{
return detail::lstrip_if_parts_impl(input, std::move(should_strip));
}

template <typename UnaryFunc>
std::array<std::wstring_view, 2> lstrip_if_parts(std::wstring_view input, UnaryFunc should_strip)
{
return detail::lstrip_if_parts_impl(input, std::move(should_strip));
}

namespace detail
{
template <typename Char, typename UnaryFunc>
std::basic_string_view<Char>
rstrip_if_impl(std::basic_string_view<Char> input, UnaryFunc should_strip)
std::array<std::basic_string_view<Char>, 2>
rstrip_if_parts_impl(std::basic_string_view<Char> input, UnaryFunc should_strip)
{
const auto rstart_iter = std::find_if(
input.crbegin(),
input.crend(),
[&should_strip](Char c) -> bool { return !should_strip(c); }
);
const auto past_end_idx = static_cast<std::size_t>(input.crend() - rstart_iter);
return input.substr(0, past_end_idx);
return { input.substr(0, past_end_idx), input.substr(past_end_idx) };
}
}

template <typename UnaryFunc>
std::string_view rstrip_if(std::string_view input, UnaryFunc should_strip)
{
return detail::rstrip_if_impl(input, std::move(should_strip));
return rstrip_if_parts(input, std::move(should_strip))[0];
}

template <typename UnaryFunc>
std::wstring_view rstrip_if(std::wstring_view input, UnaryFunc should_strip)
{
return detail::rstrip_if_impl(input, std::move(should_strip));
return rstrip_if_parts(input, std::move(should_strip))[0];
}

template <typename UnaryFunc>
std::array<std::string_view, 2> rstrip_if_parts(std::string_view input, UnaryFunc should_strip)
{
return detail::rstrip_if_parts_impl(input, std::move(should_strip));
}

template <typename UnaryFunc>
std::array<std::wstring_view, 2> rstrip_if_parts(std::wstring_view input, UnaryFunc should_strip)
{
return detail::rstrip_if_parts_impl(input, std::move(should_strip));
}

namespace detail
{
template <typename Char, typename UnaryFunc>
std::array<std::basic_string_view<Char>, 3>
strip_if_parts_impl(std::basic_string_view<Char> input, UnaryFunc should_strip)
{
const auto [head, not_head] = lstrip_if_parts(input, should_strip);
const auto [body, tail] = rstrip_if_parts(not_head, std::move(should_strip));
return { head, body, tail };
}
}

template <typename UnaryFunc>
std::string_view strip_if(std::string_view input, UnaryFunc should_strip)
{
return rstrip_if(lstrip_if(input, should_strip), should_strip);
return strip_if_parts(input, std::move(should_strip))[1];
}

template <typename UnaryFunc>
std::wstring_view strip_if(std::wstring_view input, UnaryFunc should_strip)
{
return rstrip_if(lstrip_if(input, should_strip), should_strip);
return strip_if_parts(input, std::move(should_strip))[1];
}

template <typename UnaryFunc>
std::array<std::string_view, 3> strip_if_parts(std::string_view input, UnaryFunc should_strip)
{
return detail::strip_if_parts_impl(input, std::move(should_strip));
}

template <typename UnaryFunc>
std::array<std::wstring_view, 3> strip_if_parts(std::wstring_view input, UnaryFunc should_strip)
{
return detail::strip_if_parts_impl(input, std::move(should_strip));
}

/**************************************
Expand Down
48 changes: 48 additions & 0 deletions libmamba/tests/test_util_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@ namespace mamba
EXPECT_EQ(lstrip_if("123hello456", [](auto c) { return is_digit(c); }), "hello456");
}

TEST(util_string, lstrip_if_parts)
{
using StrPair = std::array<std::string_view, 2>;
EXPECT_EQ(lstrip_if_parts("", [](auto) { return true; }), StrPair({ "", "" }));
EXPECT_EQ(lstrip_if_parts("hello", [](auto) { return true; }), StrPair({ "hello", "" }));
EXPECT_EQ(lstrip_if_parts("hello", [](auto) { return false; }), StrPair({ "", "hello" }));
EXPECT_EQ(
lstrip_if_parts("\n \thello \t\n", [](auto c) { return !is_alphanum(c); }),
StrPair({ "\n \t", "hello \t\n" })
);
EXPECT_EQ(
lstrip_if_parts("123hello456", [](auto c) { return is_digit(c); }),
StrPair({ "123", "hello456" })
);
}

TEST(util_string, rstrip)
{
EXPECT_EQ(rstrip("\n \thello \t\n"), "\n \thello");
Expand Down Expand Up @@ -145,6 +161,22 @@ namespace mamba
EXPECT_EQ(rstrip_if("123hello456", [](auto c) { return is_digit(c); }), "123hello");
}

TEST(util_string, rstrip_if_parts)
{
using StrPair = std::array<std::string_view, 2>;
EXPECT_EQ(rstrip_if_parts("", [](auto) { return true; }), StrPair({ "", "" }));
EXPECT_EQ(rstrip_if_parts("hello", [](auto) { return true; }), StrPair({ "", "hello" }));
EXPECT_EQ(rstrip_if_parts("hello", [](auto) { return false; }), StrPair({ "hello", "" }));
EXPECT_EQ(
rstrip_if_parts("\n \thello \t\n", [](auto c) { return !is_alphanum(c); }),
StrPair({ "\n \thello", " \t\n" })
);
EXPECT_EQ(
rstrip_if_parts("123hello456", [](auto c) { return is_digit(c); }),
StrPair({ "123hello", "456" })
);
}

TEST(util_string, strip)
{
EXPECT_EQ(strip(" hello \t\n"), "hello");
Expand Down Expand Up @@ -174,6 +206,22 @@ namespace mamba
EXPECT_EQ(strip_if("123hello456", [](auto c) { return is_digit(c); }), "hello");
}

TEST(util_string, strip_if_parts)
{
using StrTrio = std::array<std::string_view, 3>;
EXPECT_EQ(strip_if_parts("", [](auto) { return true; }), StrTrio({ "", "", "" }));
EXPECT_EQ(strip_if_parts("hello", [](auto) { return true; }), StrTrio({ "hello", "", "" }));
EXPECT_EQ(strip_if_parts("hello", [](auto) { return false; }), StrTrio({ "", "hello", "" }));
EXPECT_EQ(
strip_if_parts("\n \thello \t\n", [](auto c) { return !is_alphanum(c); }),
StrTrio({ "\n \t", "hello", " \t\n" })
);
EXPECT_EQ(
strip_if_parts("123hello456", [](auto c) { return is_digit(c); }),
StrTrio({ "123", "hello", "456" })
);
}

TEST(utils, strip_whitespaces)
{
{
Expand Down

0 comments on commit a130485

Please sign in to comment.