Skip to content

Instantly share code, notes, and snippets.

@sigman78
Last active January 17, 2024 23:43
Show Gist options
  • Save sigman78/e2cafe6049d4ee8e2f986aca581446f9 to your computer and use it in GitHub Desktop.
Save sigman78/e2cafe6049d4ee8e2f986aca581446f9 to your computer and use it in GitHub Desktop.
custom concat for strings and string_views
#include <iostream>
#include <string>
#include <string_view>
namespace impl {
template<typename T>
concept StringLike = requires(T t) {
{ t.data() } -> std::convertible_to<const char*>;
{ t.size() } -> std::convertible_to<std::size_t>;
};
template<StringLike T>
size_t totalSize(const T& s) {
return s.size();
}
template <size_t N>
size_t totalSize(const char(&)[N]) {
return N - 1; // Exclude the null terminator
}
template <typename First, typename... Rest>
size_t totalSize(const First& first, const Rest&... rest) {
return totalSize(first) + totalSize(rest...);
}
template <StringLike T>
void concatHelper(std::string& result, const T& arg) {
result.append(arg.data(), arg.size());
}
template <size_t N>
void concatHelper(std::string& result, const char(&arg)[N]) {
result.append(arg, N - 1);
}
} // namespace impl
// Accepts literals and any stirng-like objects
template <typename... Args>
std::string concat(const Args&... args) {
std::string result;
result.reserve(impl::totalSize(args...)); // Reserve necessary space in advance
(impl::concatHelper(result, args), ...); // Unpack and concatenate each argument
return result;
}
int main() {
std::string str1 = "Hello, ";
std::string_view strView = "World ";
std::string str2 = " and ";
std::string concatenated = concat(str1, strView, "C++", str2, "programmers!");
std::cout << concatenated << std::endl; // Outputs: Hello, World C++ and programmers!
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment