From: <man...@us...> - 2014-10-02 12:28:32
|
Revision: 4356 http://sourceforge.net/p/modplug/code/4356 Author: manxorist Date: 2014-10-02 12:28:17 +0000 (Thu, 02 Oct 2014) Log Message: ----------- [Ref] Completely disable mpt::ToWide in libopenmpt non-Windows builds via MPT_WSTRING_CONVERT macro. [Ref] Document the mpt::ustring and std::wstring related macros in BuildSettings.h . [Ref] Update documentation comments in mptString.h . [Ref] Small related cleanups. Modified Paths: -------------- trunk/OpenMPT/common/BuildSettings.h trunk/OpenMPT/common/Logging.cpp trunk/OpenMPT/common/Logging.h trunk/OpenMPT/common/mptPathString.h trunk/OpenMPT/common/mptString.cpp trunk/OpenMPT/common/mptString.h trunk/OpenMPT/test/test.cpp Modified: trunk/OpenMPT/common/BuildSettings.h =================================================================== --- trunk/OpenMPT/common/BuildSettings.h 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/common/BuildSettings.h 2014-10-02 12:28:17 UTC (rev 4356) @@ -231,6 +231,60 @@ +#if MPT_COMPILER_MSVC + + // Use wide strings for MSVC because this is the native encoding on + // microsoft platforms. + #define MPT_USTRING_MODE_WIDE 1 + #define MPT_USTRING_MODE_UTF8 0 + +#else // !MPT_COMPILER_MSVC + + #define MPT_USTRING_MODE_WIDE 0 + #define MPT_USTRING_MODE_UTF8 1 + +#endif // MPT_COMPILER_MSVC + +#if MPT_USTRING_MODE_UTF8 + + // MPT_USTRING_MODE_UTF8 mpt::ustring is implemented via mpt::u8string + #define MPT_WITH_U8STRING 1 + +#else + + #define MPT_WITH_U8STRING 0 + +#endif + +#if defined(MODPLUG_TRACKER) || MPT_USTRING_MODE_WIDE + + // mpt::ToWString, mpt::wfmt, mpt::String::PrintW, ConvertStrTo<std::wstring> + // Required by the tracker to ease interfacing with WinAPI. + // Required by MPT_USTRING_MODE_WIDE to ease type tunneling in mpt::String::Print. + #define MPT_WSTRING_FORMAT 1 + +#else + + #define MPT_WSTRING_FORMAT 0 + +#endif + +#if MPT_OS_WINDOWS || MPT_USTRING_MODE_WIDE || MPT_WSTRING_FORMAT + + // mpt::ToWide + // Required on Windows by mpt::PathString. + // Required by MPT_USTRING_MODE_WIDE as they share the conversion functions. + // Required by MPT_WSTRING_FORMAT because of std::string<->std::wstring conversion in mpt::ToString and mpt::ToWString. + #define MPT_WSTRING_CONVERT 1 + +#else + + #define MPT_WSTRING_CONVERT 0 + +#endif + + + // fixing stuff up #if !defined(ENABLE_MMX) && !defined(NO_REVERB) @@ -250,21 +304,6 @@ #define NO_MINIZ #endif -#if MPT_COMPILER_MSVC -#define MPT_WITH_U8STRING 0 -#define MPT_USTRING_MODE_WIDE 1 -#define MPT_USTRING_MODE_UTF8 0 -#else // !MPT_COMPILER_MSVC -#define MPT_WITH_U8STRING 1 -#define MPT_USTRING_MODE_WIDE 0 -#define MPT_USTRING_MODE_UTF8 1 -#endif // MPT_COMPILER_MSVC -#if defined(MODPLUG_TRACKER) || MPT_USTRING_MODE_WIDE -#define MPT_WSTRING_FORMAT 1 -#else -#define MPT_WSTRING_FORMAT 0 -#endif - #if !defined(MPT_CHARSET_WIN32) && !defined(MPT_CHARSET_ICONV) && !defined(MPT_CHARSET_CODECVTUTF8) && !defined(MPT_CHARSET_INTERNAL) #define MPT_CHARSET_INTERNAL #endif Modified: trunk/OpenMPT/common/Logging.cpp =================================================================== --- trunk/OpenMPT/common/Logging.cpp 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/common/Logging.cpp 2014-10-02 12:28:17 UTC (rev 4356) @@ -193,7 +193,7 @@ #endif } -#if !(MPT_USTRING_MODE_WIDE) +#if MPT_WSTRING_CONVERT && !(MPT_USTRING_MODE_WIDE) void Logger::operator () (const std::wstring &text) //------------------------------------------------- { Modified: trunk/OpenMPT/common/Logging.h =================================================================== --- trunk/OpenMPT/common/Logging.h 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/common/Logging.h 2014-10-02 12:28:17 UTC (rev 4356) @@ -77,7 +77,7 @@ void MPT_PRINTF_FUNC(2,3) operator () (const char *format, ...); void operator () (const mpt::ustring &text); void operator () (const std::string &text); -#if !(MPT_USTRING_MODE_WIDE) +#if MPT_WSTRING_CONVERT && !(MPT_USTRING_MODE_WIDE) void operator () (const std::wstring &text); #endif }; @@ -94,7 +94,7 @@ inline void MPT_PRINTF_FUNC(2,3) operator () (const char * /*format*/, ...) {} inline void operator () (const mpt::ustring & /*text*/ ) {} inline void operator () (const std::string & /*text*/ ) {} -#if !(MPT_USTRING_MODE_WIDE) +#if MPT_WSTRING_CONVERT && !(MPT_USTRING_MODE_WIDE) inline void operator () (const std::wstring & /*text*/ ) {} #endif }; Modified: trunk/OpenMPT/common/mptPathString.h =================================================================== --- trunk/OpenMPT/common/mptPathString.h 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/common/mptPathString.h 2014-10-02 12:28:17 UTC (rev 4356) @@ -134,6 +134,9 @@ #if MPT_OS_WINDOWS +#if !(MPT_WSTRING_CONVERT) +#error "mpt::PathString on Windows depends on MPT_WSTRING_CONVERT)" +#endif // conversions #if defined(MPT_WITH_CHARSET_LOCALE) MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::ToLocale(path); } @@ -175,20 +178,28 @@ #if defined(MPT_WITH_CHARSET_LOCALE) std::string ToLocale() const { return path; } std::string ToUTF8() const { return mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetLocale, path); } +#if MPT_WSTRING_CONVERT std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetLocale, path); } +#endif mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::CharsetLocale, path); } static PathString FromLocale(const std::string &path) { return PathString(path); } static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, mpt::CharsetUTF8, path)); } +#if MPT_WSTRING_CONVERT static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, path)); } +#endif static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, path)); } RawPathString AsNative() const { return path; } static PathString FromNative(const RawPathString &path) { return PathString(path); } #else std::string ToUTF8() const { return path; } +#if MPT_WSTRING_CONVERT std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetUTF8, path); } +#endif mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::CharsetUTF8, path); } static PathString FromUTF8(const std::string &path) { return path; } +#if MPT_WSTRING_CONVERT static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::CharsetUTF8, path)); } +#endif static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::CharsetUTF8, path)); } RawPathString AsNative() const { return path; } static PathString FromNative(const RawPathString &path) { return PathString(path); } Modified: trunk/OpenMPT/common/mptString.cpp =================================================================== --- trunk/OpenMPT/common/mptString.cpp 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/common/mptString.cpp 2014-10-02 12:28:17 UTC (rev 4356) @@ -1009,15 +1009,19 @@ } // namespace String +#if MPT_WSTRING_CONVERT std::wstring ToWide(Charset from, const std::string &str) { return String::DecodeImpl(from, str); } +#endif +#if MPT_WSTRING_CONVERT std::string ToCharset(Charset to, const std::wstring &str) { return String::EncodeImpl<std::string>(to, str); } +#endif std::string ToCharset(Charset to, Charset from, const std::string &str) { return String::ConvertImpl<std::string>(to, from, str); @@ -1127,10 +1131,12 @@ #if MPT_USTRING_MODE_WIDE // nothing, std::wstring overloads will catch all stuff #else // !MPT_USTRING_MODE_WIDE +#if MPT_WSTRING_CONVERT std::wstring ToWide(const mpt::ustring &str) { return String::DecodeImpl<mpt::ustring>(mpt::CharsetUTF8, str); } +#endif std::string ToCharset(Charset to, const mpt::ustring &str) { return String::ConvertImpl<std::string, mpt::ustring>(to, mpt::CharsetUTF8, str); @@ -1182,18 +1188,21 @@ } #endif +#if MPT_WSTRING_CONVERT #if defined(MPT_WITH_CHARSET_LOCALE) std::string ToString(const std::wstring & x) { return mpt::ToLocale(x); } std::string ToString(const wchar_t * const & x) { return mpt::ToLocale(x); } std::string ToString(const wchar_t & x) { return mpt::ToLocale(std::wstring(1, x)); } -#if MPT_USTRING_MODE_UTF8 -std::string ToString(const mpt::ustring & x) { return mpt::ToLocale(x); } -#endif #else std::string ToString(const std::wstring & x) { return mpt::ToCharset(mpt::CharsetUTF8, x); } std::string ToString(const wchar_t * const & x) { return mpt::ToCharset(mpt::CharsetUTF8, x); } std::string ToString(const wchar_t & x) { return mpt::ToCharset(mpt::CharsetUTF8, std::wstring(1, x)); } +#endif +#endif #if MPT_USTRING_MODE_UTF8 +#if defined(MPT_WITH_CHARSET_LOCALE) +std::string ToString(const mpt::ustring & x) { return mpt::ToLocale(x); } +#else std::string ToString(const mpt::ustring & x) { return mpt::ToCharset(mpt::CharsetUTF8, x); } #endif #endif Modified: trunk/OpenMPT/common/mptString.h =================================================================== --- trunk/OpenMPT/common/mptString.h 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/common/mptString.h 2014-10-02 12:28:17 UTC (rev 4356) @@ -190,12 +190,14 @@ #endif // MPT_WITH_U8STRING +#if MPT_WSTRING_CONVERT // Convert to a wide character string. // The wide encoding is UTF-16 or UTF-32, based on sizeof(wchar_t). // If str does not contain any invalid characters, this conversion is lossless. // Invalid source bytes will be replaced by some replacement character or string. static inline std::wstring ToWide(const std::wstring &str) { return str; } std::wstring ToWide(Charset from, const std::string &str); +#endif // Convert to a string encoded in the 'to'-specified character set. // If str does not contain any invalid characters, @@ -203,11 +205,16 @@ // 'to' is UTF8. // Invalid source bytes or characters that are not representable in the // destination charset will be replaced by some replacement character or string. +#if MPT_WSTRING_CONVERT std::string ToCharset(Charset to, const std::wstring &str); +#endif std::string ToCharset(Charset to, Charset from, const std::string &str); #if defined(_MFC_VER) +#if !(MPT_WSTRING_CONVERT) +#error "MFC depends on MPT_WSTRING_CONVERT)" +#endif // Convert to a MFC CString. The CString encoding depends on UNICODE. // This should also be used when converting to TCHAR strings. @@ -304,6 +311,9 @@ #endif // MPT_USTRING_MODE_UTF8 #if MPT_USTRING_MODE_WIDE +#if !(MPT_WSTRING_CONVERT) +#error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)" +#endif static inline mpt::ustring ToUnicode(const std::wstring &str) { return str; } static inline mpt::ustring ToUnicode(Charset from, const std::string &str) { return ToWide(from, str); } #if defined(_MFC_VER) @@ -326,9 +336,14 @@ #endif // MPT_USTRING_MODE_WIDE #if MPT_USTRING_MODE_WIDE +#if !(MPT_WSTRING_CONVERT) +#error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)" +#endif // nothing, std::wstring overloads will catch all stuff #else // !MPT_USTRING_MODE_WIDE +#if MPT_WSTRING_CONVERT std::wstring ToWide(const mpt::ustring &str); +#endif std::string ToCharset(Charset to, const mpt::ustring &str); #if defined(_MFC_VER) CString ToCString(const mpt::ustring &str); @@ -354,7 +369,7 @@ // The following section demands a rationale. -// 1. ToString() and ToWString() mimic the semantics of c++11 std::to_string() and std::to_wstring(). +// 1. ToString(), ToWString() an ToUString() mimic the semantics of c++11 std::to_string() and std::to_wstring(). // There is an important difference though. The c++11 versions are specified in terms of sprintf formatting which in turn // depend on the current C locale. This renders these functions unusable in a library context because the current // C locale is set by the library-using application and could be anything. There is no way a library can get reliable semantics @@ -363,7 +378,7 @@ // which results in "C" ASCII locale behavior. // 2. The full suite of printf-like or iostream like number formatting is generally not required. Instead, a sane subset functionality // is provided here. -// For convenience, mpt::Format().ParsePrintf(const char *).ToString(float) allows formatting a single floating point value with a +// For convenience, mpt::fmt::f(const char *, float) allows formatting a single floating point value with a // standard printf-like format string. This itself relies on iostream with classic() locale internally and is thus current locale // agnostic. // When formatting integers, it is recommended to use mpt::fmt::dec or mpt::fmt::hex. Appending a template argument '<n>' sets the width, @@ -375,13 +390,13 @@ // This mimics the behaviour of QString::arg() in QT4/5 or MFC AfxFormatString2(). C printf-like functions offer similar functionality // with a '%n$TYPE' syntax. In .NET, the syntax is '{n}'. This is useful to support localization strings that can change the parameter // ordering. -// 4. Every function is available for std::string and std::wstring. std::string makes no assumption about the encoding, which basically means, -// it should work for any 7-bit or 8-bit encoding, including for example ASCII, UTF8 or the current locale encoding. -// std::string std::wstring -// mpt::ToString mpt::ToWString -// mpt::FormatVal mpt::FormatValW -// mpt::fmt mpt::wfmt -// mpt::String::Print mpt::String::PrintW +// 4. Every function is available for std::string, std::wstring and mpt::ustring. std::string makes no assumption about the encoding, which +// basically means, it should work for any 7-bit or 8-bit encoding, including for example ASCII, UTF8 or the current locale encoding. +// std::string std::wstring mpt::ustring Tstring +// mpt::ToString mpt::ToWString mpt::ToUString mpt::ToStringT<Tstring> +// mpt::FormatVal mpt::FormatValW mpt::FormatValTFunctor<mpt::ustring>() mpt::FormatValTFunctor<Tstring>() +// mpt::fmt mpt::wfmt mpt::ufmt mpt::fmtT<Tstring> +// mpt::String::Print mpt::String::Print mpt::String::Print mpt::String::Print<Tstring> // 5. All functionality here delegates real work outside of the header file so that <sstream> and <locale> do not need to be included when // using this functionality. // Advantages: @@ -389,12 +404,12 @@ // - Faster compile times because <sstream> and <locale> (2 very complex headers) are not included everywhere. // Disadvantages: // - Slightly more c++ code is required for delegating work. -// - As the header does not use iostreams, custom types need to overload mpt::ToString and mpt::ToWstring instead of iostream -// operator << to allow for custom type formatting. -// - std::string and std::wstring are returned from somewhat deep cascades of helper functions. Where possible, code is written in such -// a way that return-value-optimization (RVO) or named-return-value-optimization (NRVO) should be able to eliminate almost all these -// copies. This should not be a problem for any decent modern compiler (and even less so for a c++11 compiler where move-semantics -// will kick in if RVO/NRVO fails). +// - As the header does not use iostreams, custom types need to overload mpt::ToString, mpt::ToWstring and mpt::ToUString instead of +// iostream operator << to allow for custom type formatting. +// - std::string, std::wstring and mpt::ustring are returned from somewhat deep cascades of helper functions. Where possible, code is +// written in such a way that return-value-optimization (RVO) or named-return-value-optimization (NRVO) should be able to eliminate +// almost all these copies. This should not be a problem for any decent modern compiler (and even less so for a c++11 compiler where +// move-semantics will kick in if RVO/NRVO fails). namespace mpt { @@ -406,9 +421,11 @@ static inline std::string ToString(const std::string & x) { return x; } static inline std::string ToString(const char * const & x) { return x; } MPT_DEPRECATED static inline std::string ToString(const char & x) { return std::string(1, x); } // deprecated to catch potential API mis-use, use std::string(1, x) instead +#if MPT_WSTRING_FORMAT MPT_DEPRECATED std::string ToString(const std::wstring & x); MPT_DEPRECATED std::string ToString(const wchar_t * const & x); MPT_DEPRECATED std::string ToString(const wchar_t & x); // deprecated to catch potential API mis-use, use std::wstring(1, x) instead +#endif #if MPT_USTRING_MODE_UTF8 MPT_DEPRECATED std::string ToString(const mpt::ustring & x); #endif @@ -459,7 +476,9 @@ { return mpt::ToUnicode(mpt::CharsetUTF8, ToString(x)); } +#if MPT_WSTRING_FORMAT static inline mpt::ustring ToUString(const std::wstring & x) { return mpt::ToUnicode(x); } +#endif #else template<typename T> mpt::ustring ToUString(const T & x) @@ -735,6 +754,15 @@ } } +template <typename T, typename Tformat> +static inline Tstring f(const Tformat & format, const T& x) +{ + #if defined(HAS_TYPE_TRAITS) + STATIC_ASSERT(std::is_floating_point<T>::value); + #endif + return FormatValTFunctor<Tstring>()(x, Format().ParsePrintf(format)); +} + }; // struct fmtT typedef fmtT<std::string> fmt; Modified: trunk/OpenMPT/test/test.cpp =================================================================== --- trunk/OpenMPT/test/test.cpp 2014-10-02 08:29:03 UTC (rev 4355) +++ trunk/OpenMPT/test/test.cpp 2014-10-02 12:28:17 UTC (rev 4356) @@ -336,6 +336,7 @@ return (str.rfind(match) == (str.length() - match.length())); } +#if MPT_WSTRING_CONVERT static bool BeginsWith(const std::wstring &str, const std::wstring &match) { return (str.find(match) == 0); @@ -344,6 +345,7 @@ { return (str.rfind(match) == (str.length() - match.length())); } +#endif #if MPT_USTRING_MODE_UTF8 static bool BeginsWith(const mpt::ustring &str, const mpt::ustring &match) @@ -714,6 +716,8 @@ VERIFY_EQUAL(MPT_UTF8("abc\xE5\xAE\xB6xyz"),mpt::ToUnicode(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz")); +#if MPT_WSTRING_CONVERT + // wide L"" version // Charset conversions (basic sanity checks) @@ -800,6 +804,9 @@ VERIFY_EQUAL(mpt::ToCharset(mpt::CharsetUTF8,L"abc\u5BB6xyz"),"abc\xE5\xAE\xB6xyz"); VERIFY_EQUAL(L"abc\u5BB6xyz",mpt::ToWide(mpt::CharsetUTF8,"abc\xE5\xAE\xB6xyz")); +#endif + + // Path conversions #ifdef MODPLUG_TRACKER const mpt::PathString exePath = MPT_PATHSTRING("C:\\OpenMPT\\"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |