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 |