#pragma once
#include
#include
#include
#include
#include
#include
#include
template
bool is_in(const SEQUENCE& trims, CHAR c)
{
if constexpr (is_searchable_v)
return trims.find(c) != trims.end();
return std::find(std::begin(trims), std::end(trims), c) != std::end(trims);
}
template
bool is_in(const char*trims, CHAR c)
{
return std::strchr(trims, c) != NULL;
}
template
bool is_in(char trims, CHAR c)
{
return trims == c;
}
// strip algorithms taking first, last pointer pairs.
//
//note: i used to have identical names for the predicate variants,
//and select the function by using:
// std::enable_if_t
// std::enable_if_t, P>
//
// where 'std::is_void_v' means: 'is_container'
template
P rstrip_if(P first, P last, PRED pred)
{
auto i = last;
while (i > first)
{
i--;
if (!pred(*i))
return i+1;
}
return first;
}
template
P rstrip(P first, P last, const S& trims)
{
return rstrip_if(first, last, [&](auto c) { return is_in(trims, c); });
}
template
P lstrip_if(P first, P last, PRED pred)
{
auto i = first;
while (i < last)
{
if (!pred(*i))
return i;
i++;
}
return last;
}
template
P lstrip(P first, P last, const S& trims)
{
return lstrip_f(first, last, [&](auto c) { return is_in(trims, c); });
}
template
std::pair strip_if(P first, P last, PRED pred)
{
auto l = lstrip_if(first, last, pred);
auto r = rstrip_if(first, last, pred);
return {l, r};
}
template
std::pair strip(P first, P last, const S& trims)
{
return strip_if(first, last, [&](auto c) { return is_in(trims, c); });
}
template
T makeresult(P first, P last)
{
if constexpr (std::is_same_v || std::is_same_v)
return {first, typename T::size_type(last-first)};
else
return {first, last};
}
// adaptors for stl types
template
T rstrip_if(const T& str, PRED pred)
{
return makeresult(std::begin(str), rstrip_if(std::begin(str), std::end(str), pred));
}
template
T rstrip(const T& str, const S& trims)
{
return rstrip_if(str, [&](auto c) { return is_in(trims, c); });
}
template
T lstrip_if(const T& str, PRED pred)
{
return makeresult(lstrip_if(std::begin(str), std::end(str), pred), std::end(str));
}
template
T lstrip(const T& str, const S& trims)
{
return lstrip_if(str, [&](auto c) { return is_in(trims, c); });
}
template
T strip_if(const T& str, PRED pred)
{
auto l = lstrip_if(std::begin(str), std::end(str), pred);
auto r = rstrip_if(std::begin(str), std::end(str), pred);
return makeresult(l, r);
}
template
T strip(const T& str, const S& trims)
{
return strip_if(str, [&](auto c) { return is_in(trims, c); });
}