/////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // Copyright (c) 2012-2015, Jan de Graaf (jan@jlib.nl) // // // // Permission to use, copy, modify, and/or distribute this software for any purpose with or // // without fee is hereby granted, provided that the above copyright notice and this permission // // notice appear in all copies. // // // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS // // SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL // // THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // // /////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _JLIB_HEADER_APPEND #define _JLIB_HEADER_APPEND #include #include #include #include namespace std { // Stream operator template inline basic_string& operator<<(basic_string& lhs, const input_type_t& rhs) { basic_ostringstream stream; return lhs.append(static_cast*>(&(stream << rhs))->str()); } // Parsing numbers template inline bool operator>>(const basic_string& lhs, input_type_t& rhs) { return (bool)(basic_istringstream(lhs) >> rhs); } // Addition operators // Utilizes enable_if to prevent colliding with string's existing operators template struct is_string_operand { static const bool value = std::is_same::type, char_type_t>::value || std::is_same::type, char_type_t*>::value || std::is_same::type, std::basic_string>::value; }; template inline typename std::enable_if::value, basic_string&>::type operator+=(basic_string& lhs, const input_type_t& rhs) { basic_ostringstream stream; return lhs.append(static_cast*>(&(stream << rhs))->str()); } template inline typename std::enable_if::value, basic_string>::type operator+(const basic_string& lhs, const input_type_t& rhs) { basic_ostringstream stream; return basic_string(lhs).append(static_cast*>(&(stream << rhs))->str()); } } template inline std::basic_string convert_cstring_type(const from_type_t* cstr) { static_assert(std::is_same::value, "Invalid char overload"); return std::basic_string(cstr); } template<> inline std::basic_string convert_cstring_type(const wchar_t* wcstr) { std::string str; size_t i = 0; while (wcstr[i] != L'\0') { const uint32_t c = uint32_t(wcstr[i]); str.resize(i + 1); str[i++] = (c < 32 || c >= 126) ? '?' : char(c); } return str; } template<> inline std::basic_string convert_cstring_type(const char* cstr) { std::wstring wstr; size_t i = 0; while (cstr[i] != L'\0') { const wchar_t c = wchar_t(cstr[i]); wstr.resize(i + 1); wstr[i++] = c; } return wstr; } template inline std::basic_string convert_string_type(const std::basic_string& from_string) { static_assert(std::is_same::value, "Invalid char overload"); return from_string; } template<> inline std::basic_string convert_string_type(const std::basic_string& wstr) { return convert_cstring_type(wstr.data()); } template<> inline std::basic_string convert_string_type(const std::basic_string& str) { return convert_cstring_type(str.data()); } namespace std { #ifndef _NOUNREAL template inline basic_string operator+(const basic_string& lhs, const class FString& rhs) { if (rhs.GetCharArray().GetData()) return basic_string(lhs).append((convert_cstring_type(rhs.GetCharArray().GetData()))); return basic_string(lhs); } template inline basic_string operator+(const basic_string& lhs, const class FName& rhs) { return basic_string(lhs) + rhs.ToString(); } template inline basic_string operator+(const basic_string& lhs, const class FText& rhs) { return basic_string(lhs) + rhs.ToString(); } template inline basic_string operator+(const basic_string& lhs, const struct FVector& rhs) { static const char __LogSpace = ' '; static const char __FVectorOpen = '{'; static const char __FVectorEnd = '}'; static const char __LogSep = ','; return lhs + (char_type_t)__FVectorOpen + rhs.X + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Y + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Z + (char_type_t)__FVectorEnd; } template inline basic_string operator+(const basic_string& lhs, const struct FVector2D& rhs) { static const char __LogSpace = ' '; static const char __FVectorOpen = '{'; static const char __FVectorEnd = '}'; static const char __LogSep = ','; return lhs + (char_type_t)__FVectorOpen + rhs.X + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Y + (char_type_t)__FVectorEnd; } template inline basic_string operator+(const basic_string& lhs, const struct FRotator& rhs) { static const char __LogSpace = ' '; static const char __FVectorOpen = '{'; static const char __FVectorEnd = '}'; static const char __LogSep = ','; return lhs + (char_type_t)__FVectorOpen + rhs.Pitch + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Yaw + (char_type_t)__LogSep + (char_type_t)__LogSpace + rhs.Roll + (char_type_t)__FVectorEnd; } #endif } #endif