Created
September 6, 2022 02:36
-
-
Save SaitoAtsushi/3eabfe695f29a89e6afb7f1da9d8eafa to your computer and use it in GitHub Desktop.
文字列の連結
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <iostream> | |
#include <string> | |
#include <string_view> | |
#include <type_traits> | |
#include <utility> | |
template <class T, class = void> | |
class is_string : public std::false_type {}; | |
template <class T> | |
struct is_string<T, std::void_t<decltype(std::basic_string_view<typename T::value_type>(std::declval<T>()))>> : public std::true_type {}; | |
template <class T> | |
struct is_string<T *, std::void_t<decltype(std::basic_string_view<T>(std::declval<T *>()))>> : public std::true_type {}; | |
template <class T> | |
inline constexpr bool is_string_v = is_string<std::decay_t<T>>::value; | |
template <class T, class U = void> | |
struct string_element { | |
static_assert(!sizeof(T), "Expected string-like type."); | |
}; | |
template <class T> | |
struct string_element<T, std::void_t<decltype(std::basic_string_view<typename T::value_type>(std::declval<T>()))>> { | |
using type = typename std::basic_string_view<typename T::value_type>::value_type; | |
}; | |
template <class T> | |
struct string_element<T *, std::void_t<decltype(std::basic_string_view<T>(std::declval<T *>()))>> { | |
using type = typename std::basic_string_view<T>::value_type; | |
}; | |
template <class T> | |
using string_element_t = typename string_element<std::decay_t<T>>::type; | |
template <class T, class... U> | |
inline constexpr bool is_all_same_v = (std::is_same_v<T, U> && ...); | |
template <class T, class... U> | |
auto string_append(const T &head, const U &...tail) | |
-> std::enable_if_t<is_all_same_v<std::decay_t<T>, std::decay_t<U>...> && is_string_v<T>, std::basic_string<string_element_t<T>>> { | |
using char_type = string_element_t<T>; | |
auto input_strings = std::initializer_list<const std::basic_string_view<char_type>>{head, tail...}; | |
std::basic_string<char_type> result; | |
for (auto &x : input_strings) std::copy(std::begin(x), std::end(x), std::back_inserter(result)); | |
return result; | |
} | |
int main(void) { | |
// char* 同士の連結 | |
const std::string foo = string_append("abc", "defg", "hi"); | |
std::cout << foo << std::endl; | |
// wchar_t* 同士の連結 | |
const std::wstring bar = string_append(L"1", L"2345", L"678"); | |
std::wcout << bar << std::endl; | |
// std::string 同士の連結 | |
const std::string baz = string_append(foo, foo); | |
std::cout << baz << std::endl; | |
// std::wstring 同士の連結 | |
const std::wstring qux = string_append(bar, bar); | |
std::wcout << qux << std::endl; | |
// その他の型の文字列の連結 | |
const std::u16string quux = string_append(u"あ", u"いう", u"えお"); | |
std::u32string corge = string_append(U"いろ", U"はにほ", U"へと"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment