Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add strip_if functions #2344

Merged
merged 6 commits into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 114 additions & 2 deletions libmamba/include/mamba/core/util_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <ostream>
#include <iterator>
#include <sstream>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>

#include "mamba/core/util_compare.hpp"
Expand All @@ -26,8 +27,32 @@ namespace mamba
*/
const char* raw_str_or_empty(const char* ptr);

/**
* Safe non utf-8 wrapping of <cctype> (see its doc).
*/
bool is_control(char c);
bool is_control(wchar_t c);
bool is_print(char c);
bool is_print(wchar_t c);
bool is_space(char c);
bool is_space(wchar_t c);
bool is_blank(char c);
bool is_blank(wchar_t c);
bool is_graphic(char c);
bool is_graphic(wchar_t c);
bool is_digit(char c);
bool is_digit(wchar_t c);
bool is_alpha(char c);
bool is_alpha(wchar_t c);
bool is_alphanum(char c);
bool is_alphanum(wchar_t c);
bool is_lower(char c);
bool is_lower(wchar_t c);
bool is_upper(char c);
bool is_upper(wchar_t c);
char to_lower(char c);
wchar_t to_lower(wchar_t c);

std::string to_lower(std::string_view str);
std::wstring to_lower(std::wstring_view str);
// The use of a template here serves to exclude the overload for const Char*
Expand Down Expand Up @@ -75,20 +100,35 @@ namespace mamba
std::string_view lstrip(std::string_view input);
std::wstring_view lstrip(std::wstring_view input);

template <typename UnaryFunc>
std::string_view lstrip_if(std::string_view input, UnaryFunc should_strip);
template <typename UnaryFunc>
std::wstring_view lstrip_if(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);
std::wstring_view rstrip(std::wstring_view input, std::wstring_view chars);
std::string_view rstrip(std::string_view input);
std::wstring_view rstrip(std::wstring_view input);

template <typename UnaryFunc>
std::string_view rstrip_if(std::string_view input, UnaryFunc should_strip);
template <typename UnaryFunc>
std::wstring_view rstrip_if(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);
std::wstring_view strip(std::wstring_view input, std::wstring_view chars);
std::string_view strip(std::string_view input);
std::wstring_view strip(std::wstring_view input);

template <typename UnaryFunc>
std::string_view strip_if(std::string_view input, UnaryFunc should_strip);
template <typename UnaryFunc>
std::wstring_view strip_if(std::wstring_view input, UnaryFunc should_strip);

std::vector<std::string>
split(std::string_view input, std::string_view sep, std::size_t max_split = SIZE_MAX);
std::vector<std::wstring>
Expand Down Expand Up @@ -251,6 +291,78 @@ namespace mamba
extern template bool starts_with_any(std::string_view, const std::vector<std::string>&);
extern template bool starts_with_any(std::string_view, const std::vector<std::string_view>&);

/***************************************
* Implementation of strip functions *
***************************************/

namespace detail
{
template <typename Char, typename UnaryFunc>
std::basic_string_view<Char>
lstrip_if_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);
}
}

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));
}

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));
}

namespace detail
{
template <typename Char, typename UnaryFunc>
std::basic_string_view<Char>
rstrip_if_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);
}
}

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));
}

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));
}

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);
}

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);
}

/**************************************
* Implementation of join functions *
**************************************/
Expand Down Expand Up @@ -286,7 +398,7 @@ namespace mamba
}
}

// TODO(C++20) Take an input range and return a range
// TODO(C++20) Use ``std::ranges::join_view`` (or ``std::ranges::join``)
template <typename InputIt, typename UnaryFunction, typename Value>
UnaryFunction join_for_each(InputIt first, InputIt last, UnaryFunction func, const Value& sep)
{
Expand Down
Loading