aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/src/mpt/parse/parse.hpp
blob: 30dc22a07e0cfc0fd3073821c45636f4acd59098 (plain) (blame)
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
/* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */

#ifndef MPT_PARSE_PARSE_HPP
#define MPT_PARSE_PARSE_HPP



#include "mpt/base/detect.hpp"
#include "mpt/base/namespace.hpp"
#include "mpt/string/types.hpp"
#include "mpt/string_transcode/transcode.hpp"

#include <ios>
#include <locale>
#include <sstream>
#include <string>
#include <type_traits>



namespace mpt {
inline namespace MPT_INLINE_NS {



inline std::string parse_as_internal_string_type(const std::string & s) {
	return s;
}

#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
inline std::wstring parse_as_internal_string_type(const std::wstring & s) {
	return s;
}
#endif // !MPT_COMPILER_QUIRK_NO_WCHAR

#if MPT_USTRING_MODE_WIDE
template <typename Tstring>
inline std::wstring parse_as_internal_string_type(const Tstring & s) {
	return mpt::transcode<std::wstring>(s);
}
#else  // !MPT_USTRING_MODE_WIDE
template <typename Tstring>
inline std::string parse_as_internal_string_type(const Tstring & s) {
	return mpt::transcode<std::string>(mpt::common_encoding::utf8, s);
}
#endif // MPT_USTRING_MODE_WIDE


template <typename T, typename Tstring>
inline T ConvertStringTo(const Tstring & str) {
	std::basic_istringstream<typename decltype(mpt::parse_as_internal_string_type(mpt::as_string(str)))::value_type> stream(mpt::parse_as_internal_string_type(mpt::as_string(str)));
	stream.imbue(std::locale::classic());
	T value;
	if constexpr (std::is_same<T, signed char>::value) {
		signed int tmp;
		if (!(stream >> tmp)) {
			return T{};
		}
		value = static_cast<T>(tmp);
	} else if constexpr (std::is_same<T, unsigned char>::value) {
		unsigned int tmp;
		if (!(stream >> tmp)) {
			return T{};
		}
		value = static_cast<T>(tmp);
	} else {
		if (!(stream >> value)) {
			return T{};
		}
	}
	return value;
}


template <typename T, typename Tstring>
inline T ConvertHexStringTo(const Tstring & str) {
	std::basic_istringstream<typename decltype(mpt::parse_as_internal_string_type(mpt::as_string(str)))::value_type> stream(mpt::parse_as_internal_string_type(mpt::as_string(str)));
	stream.imbue(std::locale::classic());
	T value;
	if constexpr (std::is_same<T, signed char>::value) {
		signed int tmp;
		if (!(stream >> std::hex >> tmp)) {
			return T{};
		}
		value = static_cast<T>(tmp);
	} else if constexpr (std::is_same<T, unsigned char>::value) {
		unsigned int tmp;
		if (!(stream >> std::hex >> tmp)) {
			return T{};
		}
		value = static_cast<T>(tmp);
	} else {
		if (!(stream >> std::hex >> value)) {
			return T{};
		}
	}
	return value;
}



} // namespace MPT_INLINE_NS
} // namespace mpt



#endif // MPT_PARSE_PARSE_HPP