View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001242 | OpenMPT | General | public | 2019-07-30 19:18 | 2023-04-11 09:00 |
Reporter | Saga Musix | Assigned To | manx | ||
Priority | normal | Severity | minor | Reproducibility | N/A |
Status | assigned | Resolution | won't fix | ||
Product Version | OpenMPT 1.29.00.* (old testing) | ||||
Target Version | OpenMPT 1.32 / libopenmpt 0.8 (goals) | ||||
Summary | 0001242: Eliminate unnecessary copies in charset conversion functions (std::string_view / no-ops) | ||||
Description |
| ||||
Tags | No tags attached. | ||||
Has the bug occurred in previous versions? | |||||
Tested code revision (in case you know it) | |||||
Using string_view before actually requiring C++17 results in either a ton of additional ifdef (which mptString.h and mptString.cpp already have plenty enough of anyway), or another zoo of additional string types named mpt::ustring_maybe_view for each and every string type that we have and still then result in strange const string_view & parameters (or again another set of ifdef). I would rather delay that until we require C++17. |
|
Using value parameters instead of const & for trivial iniline conversion functions pessimizes binary size for me: 4.447.744 bytes (before), 4.453.376 bytes (after) (VS2019 Win32 ReleaseShared). |
|
Let's wait for C++17 then. |
|
C++17 support is now required. We could try using |
|
The only way to fix this without breaking implicit conversions for this case would be to add |
|
Given that we now have |
|
This adds move support and forwarding to the outer layer of transcode-move-v1.patch (6,811 bytes)
Index: src/mpt/string/types.hpp =================================================================== --- src/mpt/string/types.hpp (revision 18621) +++ src/mpt/string/types.hpp (working copy) @@ -14,6 +14,7 @@ #include <string> #include <string_view> #include <type_traits> +#include <utility> #include <cstddef> @@ -504,11 +505,11 @@ template <typename T> -inline typename mpt::make_string_type<T>::type as_string(const T & str) { - if constexpr (std::is_pointer<typename std::remove_cv<T>::type>::value) { - return str ? typename mpt::make_string_type<T>::type{str} : typename mpt::make_string_type<T>::type{}; - } else if constexpr (mpt::is_string_view_type<T>::value) { - return typename mpt::make_string_type<T>::type{str}; +inline typename mpt::make_string_type<typename std::decay<T>::type>::type as_string(T && str) { + if constexpr (std::is_pointer<typename std::decay<T>::type>::value) { + return str ? typename mpt::make_string_type<typename std::decay<T>::type>::type{std::forward<T>(str)} : typename mpt::make_string_type<typename std::decay<T>::type>::type{}; + } else if constexpr (mpt::is_string_view_type<typename std::decay<T>::type>::value) { + return typename mpt::make_string_type<typename std::decay<T>::type>::type{std::forward<T>(str)}; } else { return str; } @@ -517,11 +518,11 @@ template <typename T> -inline typename mpt::make_string_view_type<T>::type as_string_view(const T & str) { - if constexpr (std::is_pointer<typename std::remove_cv<T>::type>::value) { - return str ? typename mpt::make_string_view_type<T>::type{str} : typename mpt::make_string_view_type<T>::type{}; - } else if constexpr (mpt::is_string_view_type<T>::value) { - return typename mpt::make_string_view_type<T>::type{str}; +inline typename mpt::make_string_view_type<typename std::decay<T>::type>::type as_string_view(T && str) { + if constexpr (std::is_pointer<typename std::decay<T>::type>::value) { + return str ? typename mpt::make_string_view_type<typename std::decay<T>::type>::type{std::forward<T>(str)} : typename mpt::make_string_view_type<typename std::decay<T>::type>::type{}; + } else if constexpr (mpt::is_string_view_type<typename std::decay<T>::type>::value) { + return typename mpt::make_string_view_type<typename std::decay<T>::type>::type{std::forward<T>(str)}; } else { return str; } Index: src/mpt/string_transcode/transcode.hpp =================================================================== --- src/mpt/string_transcode/transcode.hpp (revision 18621) +++ src/mpt/string_transcode/transcode.hpp (working copy) @@ -25,6 +25,7 @@ #if !defined(MPT_COMPILER_QUIRK_NO_WCHAR) #include <type_traits> #endif // !MPT_COMPILER_QUIRK_NO_WCHAR +#include <utility> #include <vector> #if MPT_OS_DJGPP @@ -1891,28 +1892,28 @@ #endif // MPT_DETECTED_MFC -template <typename Tdststring, typename Tsrcstring, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true> -inline Tdststring transcode(const Tsrcstring & src) { - if constexpr (std::is_same<Tdststring, typename mpt::make_string_type<Tsrcstring>::type>::value) { - return mpt::as_string(src); +template <typename Tdststring, typename Tsrcstring, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true> +inline Tdststring transcode(Tsrcstring && src) { + if constexpr (std::is_same<Tdststring, typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value) { + return mpt::as_string(std::forward<Tsrcstring>(src)); } else { - return string_transcoder<Tdststring>::encode(string_transcoder<decltype(mpt::as_string(src))>::decode(mpt::as_string(src))); + return string_transcoder<Tdststring>::encode(string_transcoder<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>::decode(mpt::as_string(std::forward<Tsrcstring>(src)))); } } -template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<Tdststring, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true> -inline Tdststring transcode(Tencoding to, const Tsrcstring & src) { - return mpt::encode<Tdststring>(to, string_transcoder<decltype(mpt::as_string(src))>::decode(mpt::as_string(src))); +template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<Tdststring, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true> +inline Tdststring transcode(Tencoding to, Tsrcstring && src) { + return mpt::encode<Tdststring>(to, string_transcoder<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>::decode(mpt::as_string(std::forward<Tsrcstring>(src)))); } -template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<typename mpt::make_string_type<Tsrcstring>::type, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true> -inline Tdststring transcode(Tencoding from, const Tsrcstring & src) { - return string_transcoder<Tdststring>::encode(mpt::decode<decltype(mpt::as_string(src))>(from, mpt::as_string(src))); +template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true> +inline Tdststring transcode(Tencoding from, Tsrcstring && src) { + return string_transcoder<Tdststring>::encode(mpt::decode<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>(from, mpt::as_string(std::forward<Tsrcstring>(src)))); } -template <typename Tdststring, typename Tsrcstring, typename Tto, typename Tfrom, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true> -inline Tdststring transcode(Tto to, Tfrom from, const Tsrcstring & src) { - return mpt::encode<Tdststring>(to, mpt::decode<decltype(mpt::as_string(src))>(from, mpt::as_string(src))); +template <typename Tdststring, typename Tsrcstring, typename Tto, typename Tfrom, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true> +inline Tdststring transcode(Tto to, Tfrom from, Tsrcstring && src) { + return mpt::encode<Tdststring>(to, mpt::decode<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>(from, mpt::as_string(std::forward<Tsrcstring>(src)))); } |
|
r18622 implements the trivial case for the no-op functions. mptString-avoid-noop-copies-v1.patch (2,815 bytes)
Index: common/mptString.h =================================================================== --- common/mptString.h (revision 18621) +++ common/mptString.h (working copy) @@ -127,7 +127,7 @@ // 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. -inline std::wstring ToWide(const std::wstring &str) { return str; } +inline std::wstring ToWide(std::wstring str) { return str; } inline std::wstring ToWide(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); } std::wstring ToWide(Charset from, const std::string &str); inline std::wstring ToWide(Charset from, const char * str) { return ToWide(from, str ? std::string(str) : std::string()); } @@ -159,7 +159,7 @@ #endif mpt::lstring ToLocale(Charset from, const std::string &str); inline mpt::lstring ToLocale(Charset from, const char * str) { return ToLocale(from, str ? std::string(str): std::string()); } -inline mpt::lstring ToLocale(const mpt::lstring &str) { return str; } +inline mpt::lstring ToLocale(mpt::lstring str) { return str; } #endif // MPT_ENABLE_CHARSET_LOCALE #if MPT_OS_WINDOWS @@ -180,7 +180,7 @@ // Convert to a MFC CString. The CString encoding depends on UNICODE. // This should also be used when converting to TCHAR strings. // If UNICODE is defined, this is a completely lossless operation. -inline CString ToCString(const CString &str) { return str; } +inline CString ToCString(CString str) { return str; } CString ToCString(const std::wstring &str); inline CString ToCString(const wchar_t * str) { return ToCString(str ? std::wstring(str) : std::wstring()); } CString ToCString(Charset from, const std::string &str); @@ -210,7 +210,7 @@ #if MPT_USTRING_MODE_WIDE -inline mpt::ustring ToUnicode(const std::wstring &str) { return str; } +inline mpt::ustring ToUnicode(std::wstring str) { return str; } inline mpt::ustring ToUnicode(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); } inline mpt::ustring ToUnicode(Charset from, const std::string &str) { return ToWide(from, str); } inline mpt::ustring ToUnicode(Charset from, const char * str) { return ToUnicode(from, str ? std::string(str) : std::string()); } @@ -221,7 +221,7 @@ inline mpt::ustring ToUnicode(const CString &str) { return ToWide(str); } #endif // MFC #else // !MPT_USTRING_MODE_WIDE -inline mpt::ustring ToUnicode(const mpt::ustring &str) { return str; } +inline mpt::ustring ToUnicode(mpt::ustring str) { return str; } #if MPT_WSTRING_CONVERT mpt::ustring ToUnicode(const std::wstring &str); inline mpt::ustring ToUnicode(const wchar_t * str) { return ToUnicode(str ? std::wstring(str) : std::wstring()); } |
|
r18624 implements transcode-move. |
|
|
|
Date Modified | Username | Field | Change |
---|---|---|---|
2019-07-30 19:18 | Saga Musix | New Issue | |
2019-07-31 12:08 | manx | Assigned To | => manx |
2019-07-31 12:08 | manx | Status | new => assigned |
2019-07-31 12:25 | manx | Note Added: 0003982 | |
2019-07-31 12:41 | manx | Note Added: 0003983 | |
2019-07-31 12:41 | manx | Product Version | => OpenMPT 1.29.00.* (old testing) |
2019-07-31 12:41 | manx | Target Version | => OpenMPT 1.?? (long term goals) |
2019-07-31 17:35 | Saga Musix | Note Added: 0003984 | |
2019-09-06 23:44 | Saga Musix | Note Added: 0004046 | |
2019-09-07 05:40 | manx | Target Version | OpenMPT 1.?? (long term goals) => OpenMPT 1.29.01.00 / libopenmpt 0.5.0 (upgrade first) |
2019-11-01 21:35 | manx | Note Added: 0004130 | |
2019-11-01 21:35 | manx | Target Version | OpenMPT 1.29.01.00 / libopenmpt 0.5.0 (upgrade first) => OpenMPT 2.0 (very long term goals) |
2019-11-01 21:35 | manx | Status | assigned => closed |
2019-11-01 21:35 | manx | Resolution | open => won't fix |
2023-01-25 15:01 | manx | Status | closed => assigned |
2023-01-25 15:01 | manx | Target Version | OpenMPT 2.0 (very long term goals) => OpenMPT 1.31.01.00 / libopenmpt 0.7.0 (upgrade first) |
2023-01-25 15:05 | manx | Note Added: 0005502 | |
2023-01-25 16:28 | manx | Note Added: 0005503 | |
2023-01-25 16:28 | manx | File Added: transcode-move-v1.patch | |
2023-01-25 16:40 | manx | Note Edited: 0005503 | |
2023-01-25 17:01 | manx | Note Added: 0005504 | |
2023-01-25 17:01 | manx | File Added: mptString-avoid-noop-copies-v1.patch | |
2023-01-26 07:41 | manx | Note Edited: 0005503 | |
2023-01-26 07:45 | manx | Note Added: 0005505 | |
2023-04-11 09:00 | manx | Note Added: 0005665 | |
2023-04-11 09:00 | manx | Target Version | OpenMPT 1.31.01.00 / libopenmpt 0.7.0 (upgrade first) => OpenMPT 1.32 / libopenmpt 0.8 (goals) |