Browse code

Various changes:

* Use enum class instead of enum (except for the enums for the resource IDs, not really necessary there).
* For NCSF specifically, included a function to convert an enum class to its underlying integral type (as this is needed for use with the std::bitset class).
* Cleanup headers so all the ones needed in a file are explicitly included even if they may possibly be included in another header.
* Used forward declarations in a few spots.
* Explicitly namespaced all (u)int*_t uses (this might seem like overkill, but it helps me see when the standard types are being used with a simple search for std::).
* Made sure it all builds with MinGW-w64 as well (both gcc and clang).
* Removed some std::move from DialogBuilder.cpp based on clang's warnings for that.
* Replaced use of std::copy_n on strings in DialogBuilder.cpp with my CopyToString functions that use wcscpy.
* Replaced CHAR_MIN/CHAR_MAX in eqstr.h and ltstr.h with std::numeric_limits<char>::min/max().

Naram Qashat authored on 2021/03/21 03:16:45
Showing 1 changed files
... ...
@@ -5,13 +5,12 @@
5 5
 
6 6
 #pragma once
7 7
 
8
-#include <string>
9
-#include <sstream>
10 8
 #include <locale>
11
-#include <vector>
12
-#include <memory>
9
+#include <string>
13 10
 #include <type_traits>
11
+#include <vector>
14 12
 #include <cmath>
13
+#include <cstddef>
15 14
 #include "windowsh_wrapper.h"
16 15
 
17 16
 /*
... ...
@@ -62,10 +61,10 @@ private:
62 61
 	template<typename T> static bool IsDigitsOnly(const std::basic_string<T> &input, const std::locale &loc = std::locale::classic())
63 62
 	{
64 63
 		auto inputChars = std::vector<T>(input.begin(), input.end());
65
-		size_t length = inputChars.size();
64
+		std::size_t length = inputChars.size();
66 65
 		auto masks = std::vector<typename std::ctype<T>::mask>(length);
67 66
 		std::use_facet<std::ctype<T>>(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
68
-		for (size_t x = 0; x < length; ++x)
67
+		for (std::size_t x = 0; x < length; ++x)
69 68
 			if (inputChars[x] != '.' && !(masks[x] & std::ctype<T>::digit))
70 69
 				return false;
71 70
 		return true;
... ...
@@ -77,10 +76,10 @@ public:
77 76
 		unsigned long hours = 0, minutes = 0;
78 77
 		double seconds = 0.0;
79 78
 		std::string hoursStr, minutesStr, secondsStr;
80
-		size_t firstcolon = time.find(':');
79
+		std::size_t firstcolon = time.find(':');
81 80
 		if (firstcolon != std::string::npos)
82 81
 		{
83
-			size_t secondcolon = time.substr(firstcolon + 1).find(':');
82
+			std::size_t secondcolon = time.substr(firstcolon + 1).find(':');
84 83
 			if (secondcolon != std::string::npos)
85 84
 			{
86 85
 				secondcolon = firstcolon + secondcolon + 1;
... ...
@@ -112,7 +111,7 @@ public:
112 111
 		{
113 112
 			if (!ConvertFuncs::IsDigitsOnly(secondsStr))
114 113
 				return 0;
115
-			size_t comma = secondsStr.find(',');
114
+			std::size_t comma = secondsStr.find(',');
116 115
 			if (comma != std::string::npos)
117 116
 				secondsStr[comma] = '.';
118 117
 			seconds = convertTo<double>(secondsStr);
Browse code

Cleanup a few comments and strings.

Naram Qashat authored on 2021/03/20 20:25:12
Showing 1 changed files
... ...
@@ -14,14 +14,14 @@
14 14
 #include <cmath>
15 15
 #include "windowsh_wrapper.h"
16 16
 
17
- /*
18
-  * Originally the convert* functions came from the C++ FAQ, Miscellaneous Technical Issues:
19
-  * https://isocpp.org/wiki/faq/misc-technical-issues#convert-string-to-any
20
-  *
21
-  * They have been replaced with a couple functions that use the C++11 std::enable_if
22
-  * construct along with various other type traits constructs to use the proper
23
-  * string conversions.
24
-  */
17
+/*
18
+ * Originally the convert* functions came from the C++ FAQ, Miscellaneous Technical Issues:
19
+ * https://isocpp.org/wiki/faq/misc-technical-issues#convert-string-to-any
20
+ *
21
+ * They have been replaced with a couple functions that use the C++11 std::enable_if
22
+ * construct along with various other type traits constructs to use the proper
23
+ * string conversions.
24
+ */
25 25
 template<typename T, typename S> inline typename std::enable_if_t<!std::is_enum_v<T> &&std::is_arithmetic_v<T>, T> convertTo(const std::basic_string<S> &s)
26 26
 {
27 27
 	if (std::is_integral_v<T>)
Browse code

A few more conversion changes:

* To go along with the previous change, XSFConfig now had internal get/set value functions that use type traits to choose between the enum and non-enum versions. (This also means I do not need to manually double-cast enums now.)
* Fix bug with the Windows API string conversions, so they do not include the trailing null byte in the output string.
* Added function to trim trailing 0s (and the decimal point if necessary) from a string that came from a double.

Naram Qashat authored on 2021/03/19 14:27:11
Showing 1 changed files
... ...
@@ -130,14 +130,14 @@ public:
130 130
 	{
131 131
 		double seconds = time / 1000.0;
132 132
 		if (seconds < 60)
133
-			return std::to_string(seconds);
133
+			return ConvertFuncs::TrimDoubleString(std::to_string(seconds));
134 134
 		unsigned long minutes = static_cast<unsigned long>(seconds) / 60;
135 135
 		seconds -= minutes * 60;
136 136
 		if (minutes < 60)
137
-			return std::to_string(minutes) + ":" + (seconds < 10 ? "0" : "") + std::to_string(seconds);
137
+			return std::to_string(minutes) + ":" + (seconds < 10 ? "0" : "") + ConvertFuncs::TrimDoubleString(std::to_string(seconds));
138 138
 		unsigned long hours = minutes / 60;
139 139
 		minutes %= 60;
140
-		return std::to_string(hours) + ":" + (minutes < 10 ? "0" : "") + std::to_string(minutes) + ":" + (seconds < 10 ? "0" : "") + std::to_string(seconds);
140
+		return std::to_string(hours) + ":" + (minutes < 10 ? "0" : "") + std::to_string(minutes) + ":" + (seconds < 10 ? "0" : "") + ConvertFuncs::TrimDoubleString(std::to_string(seconds));
141 141
 	}
142 142
 
143 143
 	static std::wstring MSToWString(unsigned long time)
... ...
@@ -145,13 +145,22 @@ public:
145 145
 		return ConvertFuncs::StringToWString(ConvertFuncs::MSToString(time));
146 146
 	}
147 147
 
148
+	// Derived from https://stackoverflow.com/a/13709929 (specifically the comments)
149
+	template<typename T> static std::basic_string<T> TrimDoubleString(const std::basic_string<T> &str)
150
+	{
151
+		auto strCopy = str;
152
+		auto lastNonZero = strCopy.find_last_not_of('0');
153
+		strCopy.erase(lastNonZero + (lastNonZero == strCopy.find('.') ? 0 : 1));
154
+		return strCopy;
155
+	}
156
+
148 157
 	static std::wstring StringToWString(const std::string &str)
149 158
 	{
150 159
 		auto strC = str.c_str();
151 160
 		int bufferSize = MultiByteToWideChar(CP_UTF8, 0, strC, -1, nullptr, 0);
152 161
 		auto buffer = std::vector<wchar_t>(bufferSize);
153 162
 		MultiByteToWideChar(CP_UTF8, 0, strC, -1, &buffer[0], bufferSize);
154
-		return std::wstring(buffer.begin(), buffer.end());
163
+		return std::wstring(buffer.begin(), buffer.begin() + bufferSize - 1);
155 164
 	}
156 165
 
157 166
 	static std::string WStringToString(const std::wstring &wstr)
... ...
@@ -160,6 +169,6 @@ public:
160 169
 		int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wstrC, -1, nullptr, 0, nullptr, nullptr);
161 170
 		auto buffer = std::vector<char>(bufferSize);
162 171
 		WideCharToMultiByte(CP_UTF8, 0, wstrC, -1, &buffer[0], bufferSize, nullptr, nullptr);
163
-		return std::string(buffer.begin(), buffer.end());
172
+		return std::string(buffer.begin(), buffer.begin() + bufferSize - 1);
164 173
 	}
165 174
 };
Browse code

Some conversion replacements:

* Replace the (w)stringify functions with the standard std::to_(w)string functions.
* Replace convertTo with versions that use type_traits to determine which standard string conversion function to call, as well as handle enums specically.

Naram Qashat authored on 2021/03/19 11:57:21
Showing 1 changed files
... ...
@@ -5,61 +5,54 @@
5 5
 
6 6
 #pragma once
7 7
 
8
-#include <stdexcept>
9 8
 #include <string>
10 9
 #include <sstream>
11
-#include <typeinfo>
12 10
 #include <locale>
13
-#include <codecvt>
14 11
 #include <vector>
15 12
 #include <memory>
13
+#include <type_traits>
16 14
 #include <cmath>
17 15
 #include "windowsh_wrapper.h"
18 16
 
19
-/*
20
- * The following exception class and the *stringify and convert* functions are
21
- * from the C++ FAQ, section 39, entry 3:
22
- * http://www.parashift.com/c++-faq/convert-string-to-any.html
23
- *
24
- * The convert and convertTo functions were made into templates of std::basic_string
25
- * to handle wide-character strings properly, as well as adding wstringify for the
26
- * same reason.
27
- */
28
-class BadConversion : public std::runtime_error
29
-{
30
-public:
31
-	BadConversion(const std::string &s) : std::runtime_error(s) { }
32
-};
33
-
34
-template<typename T> inline std::string stringify(const T &x)
35
-{
36
-	std::ostringstream o;
37
-	if (!(o << x))
38
-		throw BadConversion(std::string("stringify(") + typeid(x).name() + ")");
39
-	return o.str();
40
-}
41
-
42
-template<typename T> inline std::wstring wstringify(const T &x)
43
-{
44
-	std::wostringstream o;
45
-	if (!(o << x))
46
-		throw BadConversion(std::string("wstringify(") + typeid(x).name() + ")");
47
-	return o.str();
48
-}
49
-
50
-template<typename T, typename S> inline void convert(const std::basic_string<S> &s, T &x, bool failIfLeftoverChars = true)
17
+ /*
18
+  * Originally the convert* functions came from the C++ FAQ, Miscellaneous Technical Issues:
19
+  * https://isocpp.org/wiki/faq/misc-technical-issues#convert-string-to-any
20
+  *
21
+  * They have been replaced with a couple functions that use the C++11 std::enable_if
22
+  * construct along with various other type traits constructs to use the proper
23
+  * string conversions.
24
+  */
25
+template<typename T, typename S> inline typename std::enable_if_t<!std::is_enum_v<T> &&std::is_arithmetic_v<T>, T> convertTo(const std::basic_string<S> &s)
51 26
 {
52
-	std::basic_istringstream<S> i(s);
53
-	S c;
54
-	if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
55
-		throw BadConversion(std::string("convert(") + typeid(S).name() + ")");
27
+	if (std::is_integral_v<T>)
28
+	{
29
+		if (std::is_unsigned_v<T>)
30
+		{
31
+			if (std::is_same_v<unsigned long long, std::remove_cv_t<T>>)
32
+				return static_cast<T>(std::stoull(s));
33
+			else
34
+				return static_cast<T>(std::stoul(s));
35
+		}
36
+		else if (std::is_same_v<long long, std::remove_cv_t<T>>)
37
+			return static_cast<T>(std::stoll(s));
38
+		else if (std::is_same_v<long, std::remove_cv_t<T>>)
39
+			return static_cast<T>(std::stol(s));
40
+		else
41
+			return static_cast<T>(std::stoi(s));
42
+	}
43
+	else if (std::is_floating_point_v<T>)
44
+	{
45
+		if (std::is_same_v<long double, std::remove_cv_t<T>>)
46
+			return static_cast<T>(std::stold(s));
47
+		else if (std::is_same_v<double, std::remove_cv_t<T>>)
48
+			return static_cast<T>(std::stod(s));
49
+		else
50
+			return static_cast<T>(std::stof(s));
51
+	}
56 52
 }
57
-
58
-template<typename T, typename S> inline T convertTo(const std::basic_string<S> &s, bool failIfLeftoverChars = true)
53
+template<typename T, typename S> inline typename std::enable_if_t<std::is_enum_v<T>, T> convertTo(const std::basic_string<S> &s)
59 54
 {
60
-	T x;
61
-	convert(s, x, failIfLeftoverChars);
62
-	return x;
55
+	return static_cast<T>(convertTo<std::underlying_type_t<T>>(s));
63 56
 }
64 57
 
65 58
 // Miscellaneous conversion functions
... ...
@@ -107,13 +100,13 @@ public:
107 100
 		{
108 101
 			if (!ConvertFuncs::IsDigitsOnly(hoursStr))
109 102
 				return 0;
110
-			hours = convertTo<unsigned long>(hoursStr, false);
103
+			hours = convertTo<unsigned long>(hoursStr);
111 104
 		}
112 105
 		if (!minutesStr.empty())
113 106
 		{
114 107
 			if (!ConvertFuncs::IsDigitsOnly(minutesStr))
115 108
 				return 0;
116
-			minutes = convertTo<unsigned long>(minutesStr, false);
109
+			minutes = convertTo<unsigned long>(minutesStr);
117 110
 		}
118 111
 		if (!secondsStr.empty())
119 112
 		{
... ...
@@ -122,7 +115,7 @@ public:
122 115
 			size_t comma = secondsStr.find(',');
123 116
 			if (comma != std::string::npos)
124 117
 				secondsStr[comma] = '.';
125
-			seconds = convertTo<double>(secondsStr, false);
118
+			seconds = convertTo<double>(secondsStr);
126 119
 		}
127 120
 		seconds += minutes * 60 + hours * 1440;
128 121
 		return static_cast<unsigned long>(std::floor(seconds * 1000 + 0.5));
... ...
@@ -137,14 +130,14 @@ public:
137 130
 	{
138 131
 		double seconds = time / 1000.0;
139 132
 		if (seconds < 60)
140
-			return stringify(seconds);
133
+			return std::to_string(seconds);
141 134
 		unsigned long minutes = static_cast<unsigned long>(seconds) / 60;
142 135
 		seconds -= minutes * 60;
143 136
 		if (minutes < 60)
144
-			return stringify(minutes) + ":" + (seconds < 10 ? "0" : "") + stringify(seconds);
137
+			return std::to_string(minutes) + ":" + (seconds < 10 ? "0" : "") + std::to_string(seconds);
145 138
 		unsigned long hours = minutes / 60;
146 139
 		minutes %= 60;
147
-		return stringify(hours) + ":" + (minutes < 10 ? "0" : "") + stringify(minutes) + ":" + (seconds < 10 ? "0" : "") + stringify(seconds);
140
+		return std::to_string(hours) + ":" + (minutes < 10 ? "0" : "") + std::to_string(minutes) + ":" + (seconds < 10 ? "0" : "") + std::to_string(seconds);
148 141
 	}
149 142
 
150 143
 	static std::wstring MSToWString(unsigned long time)
Browse code

Replace deprecated wstring_convert with Windows API functions.

Naram Qashat authored on 2021/03/19 11:27:57
Showing 1 changed files
... ...
@@ -14,6 +14,7 @@
14 14
 #include <vector>
15 15
 #include <memory>
16 16
 #include <cmath>
17
+#include "windowsh_wrapper.h"
17 18
 
18 19
 /*
19 20
  * The following exception class and the *stringify and convert* functions are
... ...
@@ -153,13 +154,19 @@ public:
153 154
 
154 155
 	static std::wstring StringToWString(const std::string &str)
155 156
 	{
156
-		static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
157
-		return conv.from_bytes(str);
157
+		auto strC = str.c_str();
158
+		int bufferSize = MultiByteToWideChar(CP_UTF8, 0, strC, -1, nullptr, 0);
159
+		auto buffer = std::vector<wchar_t>(bufferSize);
160
+		MultiByteToWideChar(CP_UTF8, 0, strC, -1, &buffer[0], bufferSize);
161
+		return std::wstring(buffer.begin(), buffer.end());
158 162
 	}
159 163
 
160 164
 	static std::string WStringToString(const std::wstring &wstr)
161 165
 	{
162
-		static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
163
-		return conv.to_bytes(wstr);
166
+		auto wstrC = wstr.c_str();
167
+		int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wstrC, -1, nullptr, 0, nullptr, nullptr);
168
+		auto buffer = std::vector<char>(bufferSize);
169
+		WideCharToMultiByte(CP_UTF8, 0, wstrC, -1, &buffer[0], bufferSize, nullptr, nullptr);
170
+		return std::string(buffer.begin(), buffer.end());
164 171
 	}
165 172
 };
Browse code

Remove last modification date from files.

(I never remember to update these and besides, GitHub history can show when they were last modified.)

Naram Qashat authored on 2021/03/19 10:58:12
Showing 1 changed files
... ...
@@ -1,7 +1,6 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-24
5 4
  */
6 5
 
7 6
 #pragma once
Browse code

fix mingw build, clean up new warnings

Adam Higerd authored on 2021/02/11 17:42:05
Showing 1 changed files
... ...
@@ -11,12 +11,7 @@
11 11
 #include <sstream>
12 12
 #include <typeinfo>
13 13
 #include <locale>
14
-#if (defined(__GNUC__) || defined(__clang__)) && !defined(_LIBCPP_VERSION)
15
-# include "wstring_convert.h"
16
-# include "codecvt.h"
17
-#else
18
-# include <codecvt>
19
-#endif
14
+#include <codecvt>
20 15
 #include <vector>
21 16
 #include <memory>
22 17
 #include <cmath>
Browse code

Lots of changes in regards to strings, as follows:

* Removed my custom String class, as well as removed the really old
Unicode ConvertUTF, the UTF Converter, and the UTF Encode/Decode
functions.
* Replaced the above with using standard C++ std::wstring_convert and
std::codecvt_utf8.
* Added headers adapted from llvm's libc++ project for allowing the
above C++ classes to exist with GCC and Clang when libc++ isn't being
used.
* Used std::string over std::wstring whenever possible.
* Added header adapted from llvm's libc++ project to create special
versions of the ifstream and ofstream classes that would utilize _wfopen
on non-MSVC Windows compilers, so those compilers could access files on
Windows that use characters outside the current codepage.
* Removed the -static-libgcc and -static-libstdc++ flags from the
Makefile for non-MSVC builds. The generated DLLs will require extra DLLs
from either Cygwin or MinGW (whichever is used to compile), I've only
tested with MinGW and for some reason they crash Winamp on exit, I have
no idea why.

Naram Qashat authored on 2014/09/24 13:58:55
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  */
6 6
 
7 7
 #pragma once
... ...
@@ -11,10 +11,15 @@
11 11
 #include <sstream>
12 12
 #include <typeinfo>
13 13
 #include <locale>
14
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_LIBCPP_VERSION)
15
+# include "wstring_convert.h"
16
+# include "codecvt.h"
17
+#else
18
+# include <codecvt>
19
+#endif
14 20
 #include <vector>
15 21
 #include <memory>
16 22
 #include <cmath>
17
-#include "BigSString.h"
18 23
 
19 24
 /*
20 25
  * The following exception class and the *stringify and convert* functions are
... ...
@@ -130,7 +135,7 @@ public:
130 135
 
131 136
 	static unsigned long StringToMS(const std::wstring &time)
132 137
 	{
133
-		return ConvertFuncs::StringToMS(String(time).GetAnsi());
138
+		return ConvertFuncs::StringToMS(ConvertFuncs::WStringToString(time));
134 139
 	}
135 140
 
136 141
 	static std::string MSToString(unsigned long time)
... ...
@@ -149,6 +154,18 @@ public:
149 154
 
150 155
 	static std::wstring MSToWString(unsigned long time)
151 156
 	{
152
-		return String(ConvertFuncs::MSToString(time)).GetWStr();
157
+		return ConvertFuncs::StringToWString(ConvertFuncs::MSToString(time));
158
+	}
159
+
160
+	static std::wstring StringToWString(const std::string &str)
161
+	{
162
+		static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
163
+		return conv.from_bytes(str);
164
+	}
165
+
166
+	static std::string WStringToString(const std::wstring &wstr)
167
+	{
168
+		static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
169
+		return conv.to_bytes(wstr);
153 170
 	}
154 171
 };
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-17
5 5
  */
6 6
 
7 7
 #pragma once
... ...
@@ -12,6 +12,7 @@
12 12
 #include <typeinfo>
13 13
 #include <locale>
14 14
 #include <vector>
15
+#include <memory>
15 16
 #include <cmath>
16 17
 #include "BigSString.h"
17 18
 
... ...
@@ -48,7 +49,7 @@ template<typename T> inline std::wstring wstringify(const T &x)
48 49
 
49 50
 template<typename T, typename S> inline void convert(const std::basic_string<S> &s, T &x, bool failIfLeftoverChars = true)
50 51
 {
51
-	auto i = std::basic_istringstream<S>(s);
52
+	std::basic_istringstream<S> i(s);
52 53
 	S c;
53 54
 	if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
54 55
 		throw BadConversion(std::string("convert(") + typeid(S).name() + ")");
... ...
@@ -69,7 +70,7 @@ private:
69 70
 	{
70 71
 		auto inputChars = std::vector<T>(input.begin(), input.end());
71 72
 		size_t length = inputChars.size();
72
-		auto masks = std::vector<std::ctype<T>::mask>(length);
73
+		auto masks = std::vector<typename std::ctype<T>::mask>(length);
73 74
 		std::use_facet<std::ctype<T>>(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
74 75
 		for (size_t x = 0; x < length; ++x)
75 76
 			if (inputChars[x] != '.' && !(masks[x] & std::ctype<T>::digit))
Browse code

Use #pragma once instead of include guards.

Naram Qashat authored on 2014/09/08 14:47:36
Showing 1 changed files
... ...
@@ -1,11 +1,10 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-23
4
+ * Last modification on 2014-09-08
5 5
  */
6 6
 
7
-#ifndef _CONVERT_H_
8
-#define _CONVERT_H_
7
+#pragma once
9 8
 
10 9
 #include <stdexcept>
11 10
 #include <string>
... ...
@@ -152,5 +151,3 @@ public:
152 151
 		return String(ConvertFuncs::MSToString(time)).GetWStr();
153 152
 	}
154 153
 };
155
-
156
-#endif
Browse code

Added Lanczos interpolation to the NCSF plugin, and cleaned up a bit of the other code, as well as removing pstdint.h since it's no longer needed.

Naram Qashat authored on 2013/04/23 20:29:21
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-30
4
+ * Last modification on 2013-04-23
5 5
  */
6 6
 
7 7
 #ifndef _CONVERT_H_
... ...
@@ -66,14 +66,14 @@ template<typename T, typename S> inline T convertTo(const std::basic_string<S> &
66 66
 class ConvertFuncs
67 67
 {
68 68
 private:
69
-	static inline bool IsDigitsOnly(const std::string &input, const std::locale &loc = std::locale::classic())
69
+	template<typename T> static bool IsDigitsOnly(const std::basic_string<T> &input, const std::locale &loc = std::locale::classic())
70 70
 	{
71
-		auto inputChars = std::vector<char>(input.begin(), input.end());
71
+		auto inputChars = std::vector<T>(input.begin(), input.end());
72 72
 		size_t length = inputChars.size();
73
-		auto masks = std::vector<std::ctype<char>::mask>(length);
74
-		std::use_facet<std::ctype<char>>(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
73
+		auto masks = std::vector<std::ctype<T>::mask>(length);
74
+		std::use_facet<std::ctype<T>>(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
75 75
 		for (size_t x = 0; x < length; ++x)
76
-			if (inputChars[x] != '.' && !(masks[x] & std::ctype<char>::digit))
76
+			if (inputChars[x] != '.' && !(masks[x] & std::ctype<T>::digit))
77 77
 				return false;
78 78
 		return true;
79 79
 	}
Browse code

Cleanup of some warnings, updating modification dates, using nullptr instead of NULL in some cases.

Naram Qashat authored on 2013/03/30 16:17:42
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-28
4
+ * Last modification on 2013-03-30
5 5
  */
6 6
 
7 7
 #ifndef _CONVERT_H_
Browse code

Utilized more C++11 constructs. Also attempted to fix issue with the Info Box not wanting to come up anymore if the file doesn't exist.

Naram Qashat authored on 2013/03/30 07:36:38
Showing 1 changed files
... ...
@@ -71,7 +71,7 @@ private:
71 71
 		auto inputChars = std::vector<char>(input.begin(), input.end());
72 72
 		size_t length = inputChars.size();
73 73
 		auto masks = std::vector<std::ctype<char>::mask>(length);
74
-		std::use_facet<std::ctype<char> >(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
74
+		std::use_facet<std::ctype<char>>(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
75 75
 		for (size_t x = 0; x < length; ++x)
76 76
 			if (inputChars[x] != '.' && !(masks[x] & std::ctype<char>::digit))
77 77
 				return false;
Browse code

Minor lack of a reference in IsDigitsOnly.

Naram Qashat authored on 2013/03/28 14:54:12
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-25
4
+ * Last modification on 2013-03-28
5 5
  */
6 6
 
7 7
 #ifndef _CONVERT_H_
... ...
@@ -66,7 +66,7 @@ template<typename T, typename S> inline T convertTo(const std::basic_string<S> &
66 66
 class ConvertFuncs
67 67
 {
68 68
 private:
69
-	static inline bool IsDigitsOnly(const std::string input, const std::locale &loc = std::locale::classic())
69
+	static inline bool IsDigitsOnly(const std::string &input, const std::locale &loc = std::locale::classic())
70 70
 	{
71 71
 		auto inputChars = std::vector<char>(input.begin(), input.end());
72 72
 		size_t length = inputChars.size();
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,156 @@
1
+/*
2
+ * Common conversion functions
3
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
+ * Last modification on 2013-03-25
5
+ */
6
+
7
+#ifndef _CONVERT_H_
8
+#define _CONVERT_H_
9
+
10
+#include <stdexcept>
11
+#include <string>
12
+#include <sstream>
13
+#include <typeinfo>
14
+#include <locale>
15
+#include <vector>
16
+#include <cmath>
17
+#include "BigSString.h"
18
+
19
+/*
20
+ * The following exception class and the *stringify and convert* functions are
21
+ * from the C++ FAQ, section 39, entry 3:
22
+ * http://www.parashift.com/c++-faq/convert-string-to-any.html
23
+ *
24
+ * The convert and convertTo functions were made into templates of std::basic_string
25
+ * to handle wide-character strings properly, as well as adding wstringify for the
26
+ * same reason.
27
+ */
28
+class BadConversion : public std::runtime_error
29
+{
30
+public:
31
+	BadConversion(const std::string &s) : std::runtime_error(s) { }
32
+};
33
+
34
+template<typename T> inline std::string stringify(const T &x)
35
+{
36
+	std::ostringstream o;
37
+	if (!(o << x))
38
+		throw BadConversion(std::string("stringify(") + typeid(x).name() + ")");
39
+	return o.str();
40
+}
41
+
42
+template<typename T> inline std::wstring wstringify(const T &x)
43
+{
44
+	std::wostringstream o;
45
+	if (!(o << x))
46
+		throw BadConversion(std::string("wstringify(") + typeid(x).name() + ")");
47
+	return o.str();
48
+}
49
+
50
+template<typename T, typename S> inline void convert(const std::basic_string<S> &s, T &x, bool failIfLeftoverChars = true)
51
+{
52
+	auto i = std::basic_istringstream<S>(s);
53
+	S c;
54
+	if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
55
+		throw BadConversion(std::string("convert(") + typeid(S).name() + ")");
56
+}
57
+
58
+template<typename T, typename S> inline T convertTo(const std::basic_string<S> &s, bool failIfLeftoverChars = true)
59
+{
60
+	T x;
61
+	convert(s, x, failIfLeftoverChars);
62
+	return x;
63
+}
64
+
65
+// Miscellaneous conversion functions
66
+class ConvertFuncs
67
+{
68
+private:
69
+	static inline bool IsDigitsOnly(const std::string input, const std::locale &loc = std::locale::classic())
70
+	{
71
+		auto inputChars = std::vector<char>(input.begin(), input.end());
72
+		size_t length = inputChars.size();
73
+		auto masks = std::vector<std::ctype<char>::mask>(length);
74
+		std::use_facet<std::ctype<char> >(loc).is(&inputChars[0], &inputChars[length], &masks[0]);
75
+		for (size_t x = 0; x < length; ++x)
76
+			if (inputChars[x] != '.' && !(masks[x] & std::ctype<char>::digit))
77
+				return false;
78
+		return true;
79
+	}
80
+
81
+public:
82
+	static unsigned long StringToMS(const std::string &time)
83
+	{
84
+		unsigned long hours = 0, minutes = 0;
85
+		double seconds = 0.0;
86
+		std::string hoursStr, minutesStr, secondsStr;
87
+		size_t firstcolon = time.find(':');
88
+		if (firstcolon != std::string::npos)
89
+		{
90
+			size_t secondcolon = time.substr(firstcolon + 1).find(':');
91
+			if (secondcolon != std::string::npos)
92
+			{
93
+				secondcolon = firstcolon + secondcolon + 1;
94
+				hoursStr = time.substr(0, firstcolon);
95
+				minutesStr = time.substr(firstcolon + 1, secondcolon - firstcolon - 1);
96
+				secondsStr = time.substr(secondcolon + 1);
97
+			}
98
+			else
99
+			{
100
+				minutesStr = time.substr(0, firstcolon);
101
+				secondsStr = time.substr(firstcolon + 1);
102
+			}
103
+		}
104
+		else
105
+			secondsStr = time;
106
+		if (!hoursStr.empty())
107
+		{
108
+			if (!ConvertFuncs::IsDigitsOnly(hoursStr))
109
+				return 0;
110
+			hours = convertTo<unsigned long>(hoursStr, false);
111
+		}
112
+		if (!minutesStr.empty())
113
+		{
114
+			if (!ConvertFuncs::IsDigitsOnly(minutesStr))
115
+				return 0;
116
+			minutes = convertTo<unsigned long>(minutesStr, false);
117
+		}
118
+		if (!secondsStr.empty())
119
+		{
120
+			if (!ConvertFuncs::IsDigitsOnly(secondsStr))
121
+				return 0;
122
+			size_t comma = secondsStr.find(',');
123
+			if (comma != std::string::npos)
124
+				secondsStr[comma] = '.';
125
+			seconds = convertTo<double>(secondsStr, false);
126
+		}
127
+		seconds += minutes * 60 + hours * 1440;
128
+		return static_cast<unsigned long>(std::floor(seconds * 1000 + 0.5));
129
+	}
130
+
131
+	static unsigned long StringToMS(const std::wstring &time)
132
+	{
133
+		return ConvertFuncs::StringToMS(String(time).GetAnsi());
134
+	}
135
+
136
+	static std::string MSToString(unsigned long time)
137
+	{
138
+		double seconds = time / 1000.0;
139
+		if (seconds < 60)
140
+			return stringify(seconds);
141
+		unsigned long minutes = static_cast<unsigned long>(seconds) / 60;
142
+		seconds -= minutes * 60;
143
+		if (minutes < 60)
144
+			return stringify(minutes) + ":" + (seconds < 10 ? "0" : "") + stringify(seconds);
145
+		unsigned long hours = minutes / 60;
146
+		minutes %= 60;
147
+		return stringify(hours) + ":" + (minutes < 10 ? "0" : "") + stringify(minutes) + ":" + (seconds < 10 ? "0" : "") + stringify(seconds);
148
+	}
149
+
150
+	static std::wstring MSToWString(unsigned long time)
151
+	{
152
+		return String(ConvertFuncs::MSToString(time)).GetWStr();
153
+	}
154
+};
155
+
156
+#endif