2525#define CODA_OSS_str_Convert_h_INCLUDED_
2626
2727#include < cerrno>
28+ #include < complex>
2829#include < cstdlib>
2930#include < iomanip>
3031#include < iostream>
3334#include < sstream>
3435#include < string>
3536#include < typeinfo>
36- #include < type_traits>
3737
3838#include " config/Exports.h"
3939#include " coda_oss/string.h"
@@ -52,112 +52,17 @@ template <typename T> int getPrecision(const std::complex<T>&);
5252template <typename T> int getPrecision (const types::ComplexInteger<T>&);
5353#endif
5454
55- namespace details
56- {
57- // Templating (and then specializing) toString() creates all kinds of weird name-look
58- // problems; avoid trying to work-around all that by just not doing it.
59- //
60- // The preferred approach is to make a a toString() free function.
61- template <typename T>
62- inline std::string default_toString (const T& value)
63- {
64- // Use operator<<() to generate a string value; this may not be quite
65- // 100% kosher, but it's been long-standing practice in this codebase.
66- //
67- // Note that std::to_string() doesn't necessarily generate the same
68- // output as writing to std::cout; see
69- // https://en.cppreference.com/w/cpp/string/basic_string/to_string
70- std::ostringstream buf;
71- buf.precision (getPrecision (value));
72- buf << std::boolalpha << value;
73- return buf.str ();
74- }
75-
76- // https://stackoverflow.com/a/73594999/19912380
77- template <int N> struct priority : priority<N - 1 > {};
78- template <> struct priority <0 > {};
79-
80- template <typename T>
81- inline auto toString_imp (const T& obj, priority<2 >) -> decltype(obj.toString(), std::string())
82- {
83- return obj.toString (); // member-function
84- }
85-
86- template <typename T>
87- inline auto toString_imp (const T& obj, priority<1 >) -> decltype(toString(obj), std::string())
88- {
89- return toString (obj); // free function
90- }
91-
92- template <typename T>
93- inline auto toString_imp (const T& obj, priority<0 >) -> decltype(default_toString(obj), std::string())
94- {
95- return details::default_toString (obj); // our default utility which uses operator<<()
96- }
97-
98- // In order, try to call 1) obj.toString() (highest priority), 2) toString(obj),
99- // and finally 3) toString_(obj) (lowest priority).
100- template <typename T>
101- inline auto toString_ (const T& obj) -> decltype(toString_imp(obj, priority<2 >{}), std::string())
102- {
103- return details::toString_imp (obj, priority<2 >{});
104- }
105- }
55+ // Note that std::to_string() doesn't necessarily generate the same output as writing
56+ // to std::cout; see https://en.cppreference.com/w/cpp/string/basic_string/to_string
10657template <typename T>
107- inline std::string toString (const T& value) // no dectype() noise here, leave that in details::toString_()
108- {
109- // This breaks the Windows-CMake build on GitHub (when building as an "external" in NITRO)
110- // ... different compilers or compile-options?
111- // return details::toString_(value);
112-
113- return details::default_toString (value);
114- }
115-
116- // C++11 has a bunch of overloads, do the same.
117- // https://en.cppreference.com/w/cpp/string/basic_string/to_string
118- inline std::string toString (int value)
119- {
120- return details::default_toString (value);
121- }
122- inline std::string toString (long value)
58+ std::string toString (const T& value)
12359{
124- return details::default_toString (value);
125- }
126- inline std::string toString (long long value)
127- {
128- return details::default_toString (value);
129- }
130- inline std::string toString (unsigned value)
131- {
132- return details::default_toString (value);
133- }
134- inline std::string toString (unsigned long value)
135- {
136- return details::default_toString (value);
137- }
138- inline std::string toString (unsigned long long value)
139- {
140- return details::default_toString (value);
141- }
142- inline std::string toString (float value)
143- {
144- return details::default_toString (value);
145- }
146- inline std::string toString (double value)
147- {
148- return details::default_toString (value);
149- }
150- inline std::string toString (long double value)
151- {
152- return details::default_toString (value);
60+ std::ostringstream buf;
61+ buf.precision (getPrecision (value));
62+ buf << std::boolalpha << value;
63+ return buf.str ();
15364}
15465
155- // C++ doesn't have these ...
156- // https://en.cppreference.com/w/cpp/string/basic_string/to_string
157- inline std::string toString (bool value)
158- {
159- return details::default_toString (value);
160- }
16166inline std::string toString (uint8_t value)
16267{
16368 return toString (gsl::narrow<unsigned int >(value));
@@ -213,19 +118,13 @@ template <typename T>
213118inline std::string toString (const coda_oss::optional<T>& value)
214119{
215120 // TODO: handle empty/NULL optional?
216- return details::default_toString (value.value ());
121+ return toString (value.value ());
217122}
218123
219- template <typename T>
124+ template <typename T>
220125inline std::string toString (const T& real, const T& imag)
221126{
222- return details::default_toString (std::complex <T>(real, imag));
223- }
224-
225- template <typename T>
226- inline std::string toString (const T* ptr)
227- {
228- return details::default_toString (ptr);
127+ return toString (std::complex <T>(real, imag));
229128}
230129
231130CODA_OSS_API std::wstring toWString (const std::string&); // platform determines Windows-1252 or UTF-8 input and output encoding
@@ -234,6 +133,7 @@ CODA_OSS_API std::wstring toWString(const str::W1252string&); // platform determ
234133
235134CODA_OSS_API coda_oss::u8string u8FromWString (const std::wstring&); // platform determines UTF16 or UTF-32 input
236135
136+
237137template <typename T>
238138T toType (const std::string& s)
239139{
0 commit comments