-
Notifications
You must be signed in to change notification settings - Fork 0
/
CoreStrings.hpp
executable file
·169 lines (142 loc) · 5.57 KB
/
CoreStrings.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* ========================================================================= *
* CoreStrings.hpp *
* core strings functions and macros for C++ *
* Valentin Roussellet *
* ========================================================================= */
// Minimum C++ version : C++11
// requires CoreMacros.hpp for the assert and compiler macros
#pragma once
#ifndef CORE_STRING_HPP_
#define CORE_STRING_HPP_
#include "CoreMacros.hpp"
#include <string> // Needed for std::string
#include <sstream> // Needed for splitString
#include <vector> // Needed for splitString
#include <locale> // Needed for wstring_convert
#include <codecvt> // Needed for wstring to string codec
#include <algorithm>// Needed for std::max
#include <cstring> // Needed for sprintf
#include <cstdarg> // Needed for the va_list macros
#include <cinttypes>// Needed for the int32/64 print macros
namespace core
{
/// Split a string in multiple substrings according to a token.
/// Example : splitString("a,b,c and d", ',') returns { "a","b","c and d"}.
inline std::vector<std::string> splitString( const std::string& str, char token )
{
std::stringstream ss(str);
std::string element;
std::vector<std::string> result;
while ( std::getline(ss, element, token)) { result.push_back(element); }
return result;
}
/// Convert a std::string to wstring, the right way
inline std::wstring s2ws( const std::string& str )
{
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.from_bytes(str);
}
/// Convert a std::wstring to string, the right way
inline std::string ws2s( const std::wstring& wstr )
{
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX, wchar_t> converterX;
return converterX.to_bytes(wstr);
}
/// Print a float's binary representation in hexadecimal to a string.
inline std::string float2hex( float x )
{
static_assert(sizeof( float ) == sizeof( uint32 ), "`float` is not 32 bits wide");
union { float f; uint32 i; } f2ui;
char buf[sizeof( "0x00000000" )];
f2ui.f = x;
ON_ASSERT( int result = ) snprintf( buf, sizeof(buf), "0x%" PRIx32 , f2ui.i );
CORE_ASSERT( result > 0, "Error in snprintf");
return std::string( buf );
}
/// Print a double's binary representation in hexadecimal to a string.
inline std::string double2hex( double x )
{
static_assert(sizeof( double ) == sizeof( uint64 ), "`double` is not 32 bits wide");
union { double d; uint64 i; } d2ui;
char buf[sizeof( "0x0000000000000000" )];
d2ui.d = x;
ON_ASSERT (int result = ) snprintf( buf, sizeof(buf), "0x%" PRIx64, d2ui.i );
CORE_ASSERT( result > 0, "Error in snprintf");
return std::string( buf );
}
// Printf-to-string functions.
// Each function expecting varargs has a va_list equivalent
// which does the actual job (because you can't pas varargs to another
// function). See http://c-faq.com/varargs/handoff.html
int stringvPrintf( std::string& str, const char* fmt, va_list args )
{
// Random guessing value from the size of the format string.
size_t size = strlen( fmt ) * 2;
int finalSize = 0;
str.clear();
char* buffer = nullptr;
while ( 1 )
{
// Dynamically allocate a string.
delete[] buffer;
buffer = new char[size];
// Attempt to printf into the buffer
va_list argsCopy;
va_copy(argsCopy,args);
finalSize = vsnprintf( buffer, size, fmt, argsCopy );
va_end(argsCopy);
// vsnprinf can return -1 in case of an encoding error on some platforms.
CORE_ASSERT( finalSize >= 0, "Encoding error");
// If our buffer was too small, we know that final_size
// gives us the required buffer size.
if ( uint( finalSize ) >= size )
{
size = std::max( size + 1, size_t ( finalSize ) );
}
else
{
break;
}
}
if ( finalSize > 0 )
{
str = std::string( buffer );
}
delete[] buffer;
return finalSize;
}
int appendvPrintf( std::string& str, const char* fmt, va_list args )
{
std::string toAppend;
int result = stringvPrintf( toAppend, fmt, args );
str += toAppend;
return result;
}
// These functions are exposed to the interface, but they just call
// the va_list versions above.
int stringPrintf( std::string& str, const char* fmt, ... )
{
va_list args;
va_start(args,fmt);
int result = stringvPrintf(str,fmt,args);
va_end(args);
return result;
}
int appendPrintf( std::string& str, const char* fmt, ... )
{
va_list args;
va_start(args, fmt);
int result = appendvPrintf(str, fmt, args);
va_end(args);
return result;
}
} // end namespace core
#endif // CORE_STRING_HPP_
//
// Credits - References
//
// split string : https://stackoverflow.com/a/236803/746547
// string/wstring conversion : https://stackoverflow.com/a/18374698/746547
// printf to string : I wrote this originally for RadiumEngine : https://github.com/STORM-IRIT/Radium-Engine