}
};
-template<class T, class Allocator, class Functor>
+template<class CharT, class Allocator, class Functor>
class basic_mime_string : private Allocator {
public:
- using storage_type = std::basic_string<T, std::char_traits<T>, Allocator>;
- using view_type = std::basic_string_view<T, std::char_traits<T>>;
+ using storage_type = std::basic_string<CharT, std::char_traits<CharT>, Allocator>;
+ using view_type = std::basic_string_view<CharT, std::char_traits<CharT>>;
using filter_type = Functor;
using codepoint_type = UChar32;
- using value_type = T;
+ using value_type = CharT;
using difference_type = std::ptrdiff_t;
using iterator = rspamd::mime::iterator<basic_mime_string, false>;
using raw_iterator = rspamd::mime::iterator<basic_mime_string, true>;
basic_mime_string() noexcept : Allocator() {}
explicit basic_mime_string(const Allocator& alloc) noexcept : Allocator(alloc) {}
- basic_mime_string(const T* str, std::size_t sz, const Allocator& alloc = Allocator()) noexcept :
+ basic_mime_string(const CharT* str, std::size_t sz, const Allocator& alloc = Allocator()) noexcept :
Allocator(alloc)
{
append_c_string_unfiltered(str, sz);
* @param filt
* @param alloc
*/
- basic_mime_string(const T* str, std::size_t sz,
+ basic_mime_string(const CharT* str, std::size_t sz,
filter_type &&filt,
const Allocator& alloc = Allocator()) noexcept :
Allocator(alloc),
return storage.size();
}
- auto data() const -> const T* {
+ auto data() const -> const CharT* {
return storage.data();
}
}
}
- auto append(const T* str, std::size_t size) -> std::size_t {
+ /* Mutators */
+ auto append(const CharT* str, std::size_t size) -> std::size_t {
if (filter_func) {
return append_c_string_filtered(str, size);
}
return append(other.data(), other.size());
}
+ auto ltrim(const view_type &what) -> void
+ {
+ auto it = std::find_if(storage.begin(), storage.end(),
+ [&what](CharT c) {
+ return !std::any_of(what.begin(), what.end(), [&c](CharT sc) { return sc == c; });
+ });
+ storage.erase(storage.begin(), it);
+ }
+
+ auto rtrim(const view_type &what) -> void
+ {
+ auto it = std::find_if(storage.rbegin(), storage.rend(),
+ [&what](CharT c) {
+ return !std::any_of(what.begin(), what.end(), [&c](CharT sc) { return sc == c; });
+ });
+ storage.erase(it.base(), storage.end());
+ }
+
+ auto trim(const view_type &what) -> void {
+ ltrim(what);
+ rtrim(what);
+ }
+
+ /* Comparison */
auto operator ==(const basic_mime_string &other) {
return other.storage == storage;
}
auto operator ==(const view_type &other) {
return other == storage;
}
- auto operator ==(const T* other) {
+ auto operator ==(const CharT* other) {
if (other == NULL) {
return false;
}
return false;
}
+ /* Iterators */
inline auto begin() noexcept -> iterator
{
return {0, this};
return {(difference_type) size(), this};
}
+ /* Utility */
inline auto get_storage() const noexcept -> const storage_type &
{
return storage;
}
/* For doctest stringify */
- friend std::ostream& operator<< (std::ostream& os, const T& value) {
+ friend std::ostream& operator<< (std::ostream& os, const CharT& value) {
os << value.storage;
return os;
}
storage_type storage;
filter_type filter_func;
- auto append_c_string_unfiltered(const T* str, std::size_t len) -> std::size_t {
+ auto append_c_string_unfiltered(const CharT* str, std::size_t len) -> std::size_t {
/* This is fast path */
const auto *p = str;
const auto *end = str + len;
return storage.size() - orig_size;
}
- auto append_c_string_filtered(const T* str, std::size_t len) -> std::size_t {
+ auto append_c_string_filtered(const CharT* str, std::size_t len) -> std::size_t {
std::ptrdiff_t i = 0, o = 0;
UChar32 uc;
char tmp[4];