// Copyright (c) 2016 Egor Tensin // This file is part of the "Privilege check" project. // For details, see https://github.com/egor-tensin/privilege-check. // Distributed under the MIT License. #pragma once #include #include #include #include #include #include #include #include namespace string { template void ltrim(std::basic_string& s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [] (const Char& c) { return !std::isspace(c); })); } template void rtrim(std::basic_string& s) { s.erase(std::find_if(s.rbegin(), s.rend(), [] (const Char& c) { return !std::isspace(c); }).base(), s.end()); } template void trim(std::basic_string& s) { ltrim(s); rtrim(s); } template std::basic_string join( const Sep& sep, InputIterator beg, InputIterator end) { std::basic_ostringstream oss; if (beg != end) { oss << *beg; ++beg; } for (; beg != end; ++beg) oss << sep << *beg; return oss.str(); } template std::basic_string join( const Sep& sep, const std::vector>& args) { return join(sep, args.cbegin(), args.cend()); } template struct StringHelper { }; template struct StringHelper::type>::type, Char>::value>::type> { StringHelper(const Char& c) : buf{&c} , len{1} { } StringHelper(const Char* s) : buf{s} , len{std::char_traits::length(s)} { } const Char* buffer() const { return buf; } std::size_t length() const { return len; } private: const Char* const buf; const std::size_t len; }; template struct StringHelper>::value>::type> { StringHelper(const std::basic_string& s) : s{s} { } const Char* buffer() const { return s.c_str(); } std::size_t length() const { return s.length(); } private: const std::basic_string& s; }; template void replace( std::basic_string& s, const What& what, const By& by) { std::size_t pos = 0; const StringHelper::type> what_helper{what}; const StringHelper::type> by_helper{by}; const auto what_buf = what_helper.buffer(); const auto what_len = what_helper.length(); const auto by_buf = by_helper.buffer(); const auto by_len = by_helper.length(); while ((pos = s.find(what_buf, pos, what_len)) != std::basic_string::npos) { s.replace(pos, what_len, by_buf, by_len); pos += by_len; } } template void prefix_with( std::basic_string& s, const What& what, const Char& by) { const StringHelper::type> what_helper{what}; const auto what_buf = what_helper.buffer(); const auto what_len = what_helper.length(); std::size_t numof_by = 0; for (std::size_t i = 0; i < what_len; ++i) numof_by += std::count(s.cbegin(), s.cend(), what_buf[i]); s.reserve(s.capacity() + numof_by); for (std::size_t i = 0; i < what_len; ++i) replace(s, what_buf[i], by); } }