Skip to content

Instantly share code, notes, and snippets.

@2bbb
Last active March 18, 2018 07:14
Show Gist options
  • Save 2bbb/438a45341884a538d9966c4914b49ffd to your computer and use it in GitHub Desktop.
Save 2bbb/438a45341884a538d9966c4914b49ffd to your computer and use it in GitHub Desktop.
string_utils
#include <string>
#include <sstream>
#include <cstdio>
#include <type_traits>
#include <cstddef>
#include <iostream>
namespace bbb {
inline namespace string_utils {
static constexpr std::size_t format_default_buffer_size{256};
template <typename ... arguments>
inline std::string format(const char * const format_str, arguments && ... args) {
char buffer[format_default_buffer_size];
std::size_t size = std::snprintf(buffer, format_default_buffer_size, format_str, std::forward<arguments>(args) ...);
if(size < format_default_buffer_size) return { buffer, size };
std::string res(size + 1, '\0');
std::snprintf(&res[0], res.size(), format_str, std::forward<arguments>(args) ...);
return res;
};
template <typename ... arguments>
inline std::string format(const std::string &format_str, arguments && ... args) {
return std::move(format(format_str.c_str(), std::forward<arguments>(args) ...));
};
namespace detail {
template <typename delimiter_type>
inline std::string join(std::ostringstream &s, const delimiter_type &) { return std::move(s.str()); };
template <typename delimiter_type, typename argument, typename ... arguments>
inline std::string join(std::ostringstream &s, const delimiter_type &delim, argument &&arg, arguments && ... args)
{
s << std::forward<argument>(arg) << delim;
return std::move(join(s, delim, std::forward<arguments>(args) ...));
};
};
template <typename delimiter_type, typename ... arguments>
inline std::string va_join(const delimiter_type &delim, arguments && ... args) {
std::ostringstream s("");
return detail::join(s, delim, std::forward<arguments>(args) ...);
};
template <typename container_type, typename delimiter_type = std::string>
inline auto join(const container_type &vs, const delimiter_type &delim = std::string(""))
-> typename std::enable_if<
decltype(vs.cbegin(), std::true_type())::value
&& decltype(vs.cend(), std::true_type())::value,
std::string
>::type
{
std::ostringstream s("");
auto it = vs.cbegin(), end = vs.cend();
if(it == end) return std::move(s.str());
s << *it;
while(++it != end) s << delim << *it;
return std::move(s.str());
};
};
};
#include <iostream>
#include <vector>
int main(int argc, char *argv[]) {
std::cout << bbb::va_join(".", 1, 2, 3) << std::endl;
std::vector<int> p{1, 2, 3};
std::cout << bbb::join(p) << std::endl;
std::cout << bbb::format("%0X", 29) << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment