146 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| //                                                                                                           //
 | |
| //  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 <string>
 | |
| #include <sstream>
 | |
| #include <iostream>
 | |
| #include <type_traits>
 | |
| 
 | |
| namespace std
 | |
| {
 | |
| 	// Stream operator
 | |
| 	template<typename char_type_t, typename input_type_t> inline basic_string<char_type_t>& operator<<(basic_string<char_type_t>& lhs, const input_type_t& rhs)
 | |
| 	{
 | |
| 		basic_ostringstream<char_type_t> stream;
 | |
| 		return lhs.append(static_cast<basic_ostringstream<char_type_t>*>(&(stream << rhs))->str());
 | |
| 	}
 | |
| 
 | |
| 	// Parsing numbers
 | |
| 	template<typename char_type_t, typename input_type_t> inline bool operator>>(const basic_string<char_type_t>& lhs, input_type_t& rhs)
 | |
| 	{
 | |
| 		return (bool)(basic_istringstream<char_type_t>(lhs) >> rhs);
 | |
| 	}
 | |
| 
 | |
| 	// Addition operators
 | |
| 	// Utilizes enable_if to prevent colliding with string's existing operators
 | |
| 	template<typename char_type_t, typename value_type> struct is_string_operand
 | |
| 	{
 | |
| 		static const bool value = std::is_same<typename std::decay<value_type>::type, char_type_t>::value || std::is_same<typename std::decay<value_type>::type, char_type_t*>::value || std::is_same<typename std::decay<value_type>::type, std::basic_string<char_type_t>>::value;
 | |
| 	};
 | |
| 	template<typename char_type_t, typename input_type_t> inline typename std::enable_if<!is_string_operand<char_type_t, input_type_t>::value, basic_string<char_type_t>&>::type operator+=(basic_string<char_type_t>& lhs, const input_type_t& rhs)
 | |
| 	{
 | |
| 		basic_ostringstream<char_type_t> stream;
 | |
| 		return lhs.append(static_cast<basic_ostringstream<char_type_t>*>(&(stream << rhs))->str());
 | |
| 	}
 | |
| 	template<typename char_type_t, typename input_type_t> inline typename std::enable_if<!is_string_operand<char_type_t, input_type_t>::value, basic_string<char_type_t>>::type operator+(const basic_string<char_type_t>& lhs, const input_type_t& rhs)
 | |
| 	{
 | |
| 		basic_ostringstream<char_type_t> stream;
 | |
| 		return basic_string<char_type_t>(lhs).append(static_cast<basic_ostringstream<char_type_t>*>(&(stream << rhs))->str());
 | |
| 	}
 | |
| }
 | |
| 
 | |
| template<typename to_type_t, typename from_type_t> inline std::basic_string<to_type_t> convert_cstring_type(const from_type_t* cstr)
 | |
| {
 | |
| 	static_assert(std::is_same<to_type_t, from_type_t>::value, "Invalid char overload");
 | |
| 	return std::basic_string<to_type_t>(cstr);
 | |
| }
 | |
| template<> inline std::basic_string<char> 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<wchar_t> 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<typename to_type_t, typename from_type_t> inline std::basic_string<to_type_t> convert_string_type(const std::basic_string<from_type_t>& from_string)
 | |
| {
 | |
| 	static_assert(std::is_same<to_type_t, from_type_t>::value, "Invalid char overload");
 | |
| 	return from_string;
 | |
| }
 | |
| template<> inline std::basic_string<char> convert_string_type(const std::basic_string<wchar_t>& wstr)
 | |
| {
 | |
| 	return convert_cstring_type<char, wchar_t>(wstr.data());
 | |
| }
 | |
| template<> inline std::basic_string<wchar_t> convert_string_type(const std::basic_string<char>& str)
 | |
| {
 | |
| 	return convert_cstring_type<wchar_t, char>(str.data());
 | |
| }
 | |
| 
 | |
| namespace std
 | |
| {
 | |
| #ifndef _NOUNREAL
 | |
| 	template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const class FString& rhs)
 | |
| 	{
 | |
| 		if (rhs.GetCharArray().GetData())
 | |
| 			return basic_string<char_type_t>(lhs).append((convert_cstring_type<char_type_t, wchar_t>(rhs.GetCharArray().GetData())));
 | |
| 		return basic_string<char_type_t>(lhs);
 | |
| 	}
 | |
| 	template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const class FName& rhs)
 | |
| 	{
 | |
| 		return basic_string<char_type_t>(lhs) + rhs.ToString();
 | |
| 	}
 | |
| 	template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& lhs, const class FText& rhs)
 | |
| 	{
 | |
| 		return basic_string<char_type_t>(lhs) + rhs.ToString();
 | |
| 	}
 | |
| 
 | |
| 	template<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& 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<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& 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<typename char_type_t> inline basic_string<char_type_t> operator+(const basic_string<char_type_t>& 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 |