diff --git a/externals/coda-oss/modules/c++/str/include/str/Convert.h b/externals/coda-oss/modules/c++/str/include/str/Convert.h index dcb5e9139..83afad5b7 100644 --- a/externals/coda-oss/modules/c++/str/include/str/Convert.h +++ b/externals/coda-oss/modules/c++/str/include/str/Convert.h @@ -25,6 +25,7 @@ #define CODA_OSS_str_Convert_h_INCLUDED_ #include +#include #include #include #include @@ -33,7 +34,6 @@ #include #include #include -#include #include "config/Exports.h" #include "coda_oss/string.h" @@ -52,112 +52,17 @@ template int getPrecision(const std::complex&); template int getPrecision(const types::ComplexInteger&); #endif -namespace details -{ - // Templating (and then specializing) toString() creates all kinds of weird name-look - // problems; avoid trying to work-around all that by just not doing it. - // - // The preferred approach is to make a a toString() free function. - template - inline std::string default_toString(const T& value) - { - // Use operator<<() to generate a string value; this may not be quite - // 100% kosher, but it's been long-standing practice in this codebase. - // - // Note that std::to_string() doesn't necessarily generate the same - // output as writing to std::cout; see - // https://en.cppreference.com/w/cpp/string/basic_string/to_string - std::ostringstream buf; - buf.precision(getPrecision(value)); - buf << std::boolalpha << value; - return buf.str(); - } - - // https://stackoverflow.com/a/73594999/19912380 - template struct priority : priority {}; - template<> struct priority<0> {}; - - template - inline auto toString_imp(const T& obj, priority<2>) -> decltype(obj.toString(), std::string()) - { - return obj.toString(); // member-function - } - - template - inline auto toString_imp(const T& obj, priority<1>) -> decltype(toString(obj), std::string()) - { - return toString(obj); // free function - } - - template - inline auto toString_imp(const T& obj, priority<0>) -> decltype(default_toString(obj), std::string()) - { - return details::default_toString(obj); // our default utility which uses operator<<() - } - - // In order, try to call 1) obj.toString() (highest priority), 2) toString(obj), - // and finally 3) toString_(obj) (lowest priority). - template - inline auto toString_(const T& obj) -> decltype(toString_imp(obj, priority<2>{}), std::string()) - { - return details::toString_imp(obj, priority<2>{}); - } -} +// Note that std::to_string() doesn't necessarily generate the same output as writing +// to std::cout; see https://en.cppreference.com/w/cpp/string/basic_string/to_string template -inline std::string toString(const T& value) // no dectype() noise here, leave that in details::toString_() -{ - // This breaks the Windows-CMake build on GitHub (when building as an "external" in NITRO) - // ... different compilers or compile-options? - //return details::toString_(value); - - return details::default_toString(value); -} - -// C++11 has a bunch of overloads, do the same. -// https://en.cppreference.com/w/cpp/string/basic_string/to_string -inline std::string toString(int value) -{ - return details::default_toString(value); -} -inline std::string toString(long value) +std::string toString(const T& value) { - return details::default_toString(value); -} -inline std::string toString(long long value) -{ - return details::default_toString(value); -} -inline std::string toString(unsigned value) -{ - return details::default_toString(value); -} -inline std::string toString(unsigned long value) -{ - return details::default_toString(value); -} -inline std::string toString(unsigned long long value) -{ - return details::default_toString(value); -} -inline std::string toString(float value) -{ - return details::default_toString(value); -} -inline std::string toString(double value) -{ - return details::default_toString(value); -} -inline std::string toString(long double value) -{ - return details::default_toString(value); + std::ostringstream buf; + buf.precision(getPrecision(value)); + buf << std::boolalpha << value; + return buf.str(); } -// C++ doesn't have these ... -// https://en.cppreference.com/w/cpp/string/basic_string/to_string -inline std::string toString(bool value) -{ - return details::default_toString(value); -} inline std::string toString(uint8_t value) { return toString(gsl::narrow(value)); @@ -213,19 +118,13 @@ template inline std::string toString(const coda_oss::optional& value) { // TODO: handle empty/NULL optional? - return details::default_toString(value.value()); + return toString(value.value()); } -template +template inline std::string toString(const T& real, const T& imag) { - return details::default_toString(std::complex(real, imag)); -} - -template -inline std::string toString(const T* ptr) -{ - return details::default_toString(ptr); + return toString(std::complex(real, imag)); } CODA_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 CODA_OSS_API coda_oss::u8string u8FromWString(const std::wstring&); // platform determines UTF16 or UTF-32 input + template T toType(const std::string& s) {