View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001256 | OpenMPT | General | public | 2019-08-25 15:56 | 2019-09-06 11:34 |
Reporter | manx | Assigned To | manx | ||
Priority | normal | Severity | minor | Reproducibility | have not tried |
Status | resolved | Resolution | fixed | ||
Product Version | OpenMPT 1.29.00.* (old testing) | ||||
Target Version | OpenMPT 1.29.01.00 / libopenmpt 0.5.0 (upgrade first) | Fixed in Version | OpenMPT 1.29.01.00 / libopenmpt 0.5.0 (upgrade first) | ||
Summary | 0001256: require C++17 | ||||
Description | Requiring C++17 would remove most ancient compilers for which we currently implement work-arounds due to incomplete standard library implementations. In particular, custom implementations of
Additionally,
| ||||
Additional Information | current distro compilers:
| ||||
Tags | No tags attached. | ||||
Attached Files | require-cpp17-v1.patch (40,965 bytes)
Index: build/autotools/configure.ac =================================================================== --- build/autotools/configure.ac (revision 11987) +++ build/autotools/configure.ac (working copy) @@ -288,13 +288,14 @@ AC_PROG_CC_STDC #AC_PROG_CC_C99 -# We need C++14 support -AX_CXX_COMPILE_STDCXX(17, [noext], [optional]) -AS_IF([test "x$HAVE_CXX17" != "x1"], - [ - AX_CXX_COMPILE_STDCXX(14, [noext], [mandatory]) - ],[] -) +# We need C++17 support +#AX_CXX_COMPILE_STDCXX(20, [noext], [optional]) +#AS_IF([test "x$HAVE_CXX20" != "x1"], +# [ +# AX_CXX_COMPILE_STDCXX(17, [noext], [mandatory]) +# ],[] +#) +AX_CXX_COMPILE_STDCXX(17, [noext], [mandatory]) AC_LANG_PUSH([C]) AX_CHECK_COMPILE_FLAG([-fvisibility=hidden], [CFLAGS="$CFLAGS -fvisibility=hidden"]) Index: build/make/config-afl.mk =================================================================== --- build/make/config-afl.mk (revision 11987) +++ build/make/config-afl.mk (working copy) @@ -9,12 +9,8 @@ else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17) CXXFLAGS_STDCXX = -std=c++17 -else -ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14) -CXXFLAGS_STDCXX = -std=c++14 endif endif -endif CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-djgpp.mk =================================================================== --- build/make/config-djgpp.mk (revision 11987) +++ build/make/config-djgpp.mk (working copy) @@ -6,7 +6,7 @@ # Note that we are using GNU extensions instead of 100% standards-compliant # mode, because otherwise DJGPP-specific headers/functions are unavailable. -CXXFLAGS_STDCXX = -std=gnu++14 +CXXFLAGS_STDCXX = -std=gnu++17 CFLAGS_STDC = -std=gnu99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-emscripten.mk =================================================================== --- build/make/config-emscripten.mk (revision 11987) +++ build/make/config-emscripten.mk (working copy) @@ -11,12 +11,8 @@ else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17) CXXFLAGS_STDCXX = -std=c++17 -else -ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14) -CXXFLAGS_STDCXX = -std=c++14 endif endif -endif CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-gcc.mk =================================================================== --- build/make/config-gcc.mk (revision 11987) +++ build/make/config-gcc.mk (working copy) @@ -9,12 +9,8 @@ else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17) CXXFLAGS_STDCXX = -std=c++17 -else -ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14) -CXXFLAGS_STDCXX = -std=c++14 endif endif -endif CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-generic.mk =================================================================== --- build/make/config-generic.mk (revision 11987) +++ build/make/config-generic.mk (working copy) @@ -4,7 +4,7 @@ LD ?= c++ AR = ar -CXXFLAGS_STDCXX = -std=c++14 +CXXFLAGS_STDCXX = -std=c++17 CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-mingw64-win32.mk =================================================================== --- build/make/config-mingw64-win32.mk (revision 11987) +++ build/make/config-mingw64-win32.mk (working copy) @@ -4,7 +4,7 @@ LD = i686-w64-mingw32-g++$(MINGW_FLAVOUR) AR = i686-w64-mingw32-ar$(MINGW_FLAVOUR) -CXXFLAGS_STDCXX = -std=c++14 +CXXFLAGS_STDCXX = -std=c++17 CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-mingw64-win64.mk =================================================================== --- build/make/config-mingw64-win64.mk (revision 11987) +++ build/make/config-mingw64-win64.mk (working copy) @@ -4,7 +4,7 @@ LD = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR) AR = x86_64-w64-mingw32-ar$(MINGW_FLAVOUR) -CXXFLAGS_STDCXX = -std=c++14 +CXXFLAGS_STDCXX = -std=c++17 CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-mingw64-winrt-amd64.mk =================================================================== --- build/make/config-mingw64-winrt-amd64.mk (revision 11987) +++ build/make/config-mingw64-winrt-amd64.mk (working copy) @@ -4,7 +4,7 @@ LD = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR) AR = x86_64-w64-mingw32-ar$(MINGW_FLAVOUR) -CXXFLAGS_STDCXX = -std=c++14 +CXXFLAGS_STDCXX = -std=c++17 CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-mingw64-winrt-x86.mk =================================================================== --- build/make/config-mingw64-winrt-x86.mk (revision 11987) +++ build/make/config-mingw64-winrt-x86.mk (working copy) @@ -4,7 +4,7 @@ LD = i686-w64-mingw32-g++$(MINGW_FLAVOUR) AR = i686-w64-mingw32-ar$(MINGW_FLAVOUR) -CXXFLAGS_STDCXX = -std=c++14 +CXXFLAGS_STDCXX = -std=c++17 CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/make/config-standard.mk =================================================================== --- build/make/config-standard.mk (revision 11987) +++ build/make/config-standard.mk (working copy) @@ -4,7 +4,7 @@ LD ?= c++ AR = ar -CXXFLAGS_STDCXX = -std=c++14 +CXXFLAGS_STDCXX = -std=c++17 CFLAGS_STDC = -std=c99 CXXFLAGS += $(CXXFLAGS_STDCXX) CFLAGS += $(CFLAGS_STDC) Index: build/pch/PCH.h =================================================================== --- build/pch/PCH.h (revision 11987) +++ build/pch/PCH.h (working copy) @@ -111,9 +111,7 @@ #include <thread> #include <type_traits> #include <utility> -#if MPT_CXX_AT_LEAST(17) #include <variant> -#endif // C++17 #include <vector> Index: common/BuildSettings.h =================================================================== --- common/BuildSettings.h (revision 11987) +++ common/BuildSettings.h (working copy) @@ -530,11 +530,7 @@ #define MPT_ENABLE_TEMPFILE #endif -#if MPT_CXX_AT_LEAST(17) && defined(MPT_CHARSET_CODECVTUTF8) -#undef MPT_CHARSET_CODECVTUTF8 // std::codecvt_utf8 is deprecated in c++17 -#endif - -#if !defined(MPT_CHARSET_WIN32) && !defined(MPT_CHARSET_ICONV) && !defined(MPT_CHARSET_CODECVTUTF8) && !defined(MPT_CHARSET_INTERNAL) +#if !defined(MPT_CHARSET_WIN32) && !defined(MPT_CHARSET_ICONV) && !defined(MPT_CHARSET_INTERNAL) #define MPT_CHARSET_INTERNAL #endif @@ -741,15 +737,13 @@ // standard library quirks -#if MPT_CXX_AT_LEAST(17) #if (MPT_COMPILER_GCC || MPT_COMPILER_CLANG) // we need to detect the standard library via macro __GLIBCXX__ #include <vector> #endif -#if MPT_COMPILER_MSVC || MPT_GCC_BEFORE(8,1,0) || MPT_CLANG_BEFORE(5,0,0) || (MPT_COMPILER_GCC && defined(__GLIBCXX__) && (defined(__MINGW32__) || defined(__MINGW64__))) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__)) || (MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) || MPT_OS_OPENBSD || MPT_OS_EMSCRIPTEN || MPT_OS_HAIKU || (defined(__clang__) && defined(_MSC_VER)) +#if MPT_COMPILER_MSVC || MPT_GCC_BEFORE(8,1,0) || (MPT_COMPILER_GCC && defined(__GLIBCXX__) && (defined(__MINGW32__) || defined(__MINGW64__))) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__)) || (MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) || MPT_OS_OPENBSD || MPT_OS_EMSCRIPTEN || MPT_OS_HAIKU || (defined(__clang__) && defined(_MSC_VER)) #define MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC #endif -#endif Index: common/CompilerDetect.h =================================================================== --- common/CompilerDetect.h (revision 11987) +++ common/CompilerDetect.h (working copy) @@ -34,8 +34,8 @@ #define MPT_CLANG_AT_LEAST(major,minor,patch) (MPT_COMPILER_CLANG_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) #define MPT_CLANG_BEFORE(major,minor,patch) (MPT_COMPILER_CLANG_VERSION < MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) -#if MPT_CLANG_BEFORE(3,8,0) -#error "clang version 3.8 required" +#if MPT_CLANG_BEFORE(5,0,0) +#error "clang version 5 required" #endif #if defined(__clang_analyzer__) @@ -51,8 +51,8 @@ #define MPT_GCC_AT_LEAST(major,minor,patch) (MPT_COMPILER_GCC_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) #define MPT_GCC_BEFORE(major,minor,patch) (MPT_COMPILER_GCC_VERSION < MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch))) -#if MPT_GCC_BEFORE(5,1,0) -#error "GCC version 5.1 required" +#if MPT_GCC_BEFORE(7,1,0) +#error "GCC version 7.1 required" #endif #elif defined(_MSC_VER) @@ -139,10 +139,8 @@ #if (__cplusplus >= 201703) #define MPT_CXX 17 -#elif (__cplusplus >= 201402) -#define MPT_CXX 14 #else -#define MPT_CXX 14 +#define MPT_CXX 17 #endif #elif MPT_COMPILER_MSVC @@ -149,15 +147,13 @@ #if (_MSVC_LANG >= 201703) #define MPT_CXX 17 -#elif (_MSVC_LANG >= 201402) -#define MPT_CXX 14 #else -#define MPT_CXX 14 +#define MPT_CXX 17 #endif #else -#define MPT_CXX 14 +#define MPT_CXX 17 #endif @@ -308,11 +304,6 @@ #endif -#if MPT_GCC_BEFORE(6,1,0) -#define MPT_COMPILER_QUIRK_NO_CONSTEXPR14_THROW -#endif - - #if defined(__arm__) #if defined(__SOFTFP__) Index: common/mptAlloc.cpp =================================================================== --- common/mptAlloc.cpp (revision 11987) +++ common/mptAlloc.cpp (working copy) @@ -39,28 +39,9 @@ -#if MPT_CXX_AT_LEAST(17) -#else -void* align(std::size_t alignment, std::size_t size, void* &ptr, std::size_t &space) noexcept -{ - std::size_t offset = static_cast<std::size_t>(reinterpret_cast<std::uintptr_t>(ptr) & (alignment - 1)); - if(offset != 0) - { - offset = alignment - offset; - } - if((space < offset) || ((space - offset) < size)) - { - return nullptr; - } - ptr = static_cast<mpt::byte*>(ptr) + offset; - space -= offset; - return ptr; -} -#endif - aligned_raw_memory aligned_alloc_impl(std::size_t size, std::size_t count, std::size_t alignment) { - #if MPT_CXX_AT_LEAST(17) && !defined(MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC) + #if !defined(MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC) std::size_t space = count * size; void* mem = std::aligned_alloc(alignment, space); if(!mem) @@ -86,7 +67,7 @@ MPT_EXCEPTION_THROW_OUT_OF_MEMORY(); } void* aligned_mem = mem; - void* aligned = mpt::align(alignment, size * count, aligned_mem, space); + void* aligned = std::align(alignment, size * count, aligned_mem, space); if(!aligned) { MPT_EXCEPTION_THROW_OUT_OF_MEMORY(); @@ -107,7 +88,7 @@ void aligned_free(aligned_raw_memory raw) { - #if MPT_CXX_AT_LEAST(17) && !defined(MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC) + #if !defined(MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC) std::free(raw.mem); #elif MPT_COMPILER_MSVC || (defined(__clang__) && defined(_MSC_VER)) _aligned_free(raw.mem); Index: common/mptAlloc.h =================================================================== --- common/mptAlloc.h (revision 11987) +++ common/mptAlloc.h (working copy) @@ -88,7 +88,7 @@ -#if MPT_CXX_AT_LEAST(17) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) +#if !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) using std::launder; #else template <class T> @@ -99,15 +99,7 @@ #endif -#if MPT_CXX_AT_LEAST(17) -using std::align; -#else -// pre-C++17, std::align does not support over-alignement -void* align(std::size_t alignment, std::size_t size, void* &ptr, std::size_t &space) noexcept; -#endif - - struct aligned_raw_memory { void* aligned; Index: common/mptAssert.h =================================================================== --- common/mptAssert.h (revision 11987) +++ common/mptAssert.h (working copy) @@ -138,11 +138,7 @@ #define MPT_CONSTEXPR11_ASSERT MPT_STATIC_ASSERT #define MPT_CONSTEXPR14_ASSERT MPT_STATIC_ASSERT -#if MPT_CXX_AT_LEAST(17) #define MPT_CONSTEXPR17_ASSERT MPT_STATIC_ASSERT -#else -#define MPT_CONSTEXPR17_ASSERT MPT_ASSERT -#endif Index: common/mptBaseMacros.h =================================================================== --- common/mptBaseMacros.h (revision 11987) +++ common/mptBaseMacros.h (working copy) @@ -29,11 +29,7 @@ // Compile time assert. -#if MPT_CXX_AT_LEAST(17) #define MPT_STATIC_ASSERT static_assert -#else -#define MPT_STATIC_ASSERT(expr) static_assert((expr), "compile time assertion failed: " #expr) -#endif // legacy #define STATIC_ASSERT(x) MPT_STATIC_ASSERT(x) @@ -58,62 +54,22 @@ #define MPT_CONSTEXPR11_VAR constexpr #define MPT_CONSTEXPR14_FUN constexpr MPT_FORCEINLINE #define MPT_CONSTEXPR14_VAR constexpr -#if MPT_CXX_AT_LEAST(17) #define MPT_CONSTEXPR17_FUN constexpr MPT_FORCEINLINE #define MPT_CONSTEXPR17_VAR constexpr -#else -#define MPT_CONSTEXPR17_FUN MPT_FORCEINLINE -#define MPT_CONSTEXPR17_VAR const -#endif namespace mpt { -#if MPT_CXX_AT_LEAST(17) template <auto V> struct constant_value { static constexpr decltype(V) value() { return V; } }; #define MPT_FORCE_CONSTEXPR(expr) (mpt::constant_value<( expr )>::value()) -#else -template <typename T, T V> struct constant_value_helper { static constexpr T value() { return V; } }; -#define MPT_FORCE_CONSTEXPR(expr) (mpt::constant_value_helper<decltype( expr ), ( expr )>::value()) -#endif } // namespace mpt // C++17 std::size and std::data -#if MPT_CXX_AT_LEAST(17) namespace mpt { using std::size; using std::data; } // namespace mpt -#else -namespace mpt { -template <typename T> -MPT_CONSTEXPR11_FUN auto size(const T & v) -> decltype(v.size()) -{ - return v.size(); -} -template <typename T, std::size_t N> -MPT_CONSTEXPR11_FUN std::size_t size(const T(&)[N]) noexcept -{ - return N; -} -template <typename T> -MPT_CONSTEXPR11_FUN auto data(const T & v) -> decltype(v.data()) -{ - return v.data(); -} -template <typename T> -MPT_CONSTEXPR11_FUN auto data(T & v) -> decltype(v.data()) -{ - return v.data(); -} -template <typename T, std::size_t N> -MPT_CONSTEXPR11_FUN T* data(T(&a)[N]) noexcept -{ - return a; -} -} // namespace mpt -#endif // legacy #if MPT_COMPILER_MSVC OPENMPT_NAMESPACE_END @@ -137,29 +93,14 @@ -#if MPT_CXX_AT_LEAST(17) -#define MPT_NODISCARD [[nodiscard]] +#define MPT_ATTR_NODISCARD [[nodiscard]] #define MPT_DISCARD(expr) static_cast<void>(expr) -#else -#define MPT_NODISCARD -#define MPT_DISCARD(expr) expr -#endif -#if MPT_CXX_AT_LEAST(17) #define MPT_CONSTANT_IF if constexpr -#endif #if MPT_COMPILER_MSVC -#if !defined(MPT_CONSTANT_IF) -#define MPT_CONSTANT_IF(x) \ - __pragma(warning(push)) \ - __pragma(warning(disable:4127)) \ - if(x) \ - __pragma(warning(pop)) \ -/**/ -#endif #define MPT_MAYBE_CONSTANT_IF(x) \ __pragma(warning(push)) \ __pragma(warning(disable:4127)) \ @@ -188,11 +129,6 @@ /**/ #endif -#if !defined(MPT_CONSTANT_IF) -// MPT_CONSTANT_IF disables compiler warnings for conditions that are either always true or always false for some reason (dependent on template arguments for example) -#define MPT_CONSTANT_IF(x) if(x) -#endif - #if !defined(MPT_MAYBE_CONSTANT_IF) // MPT_MAYBE_CONSTANT_IF disables compiler warnings for conditions that may in some case be either always false or always true (this may turn out to be useful in ASSERTions in some cases). #define MPT_MAYBE_CONSTANT_IF(x) if(x) @@ -228,23 +164,7 @@ // Macro for marking intentional fall-throughs in switch statements - can be used for static analysis if supported. -#if MPT_CXX_AT_LEAST(17) - #define MPT_FALLTHROUGH [[fallthrough]] -#elif MPT_COMPILER_MSVC - #define MPT_FALLTHROUGH __fallthrough -#elif MPT_COMPILER_CLANG - #define MPT_FALLTHROUGH [[clang::fallthrough]] -#elif MPT_COMPILER_GCC && MPT_GCC_AT_LEAST(7,1,0) - #define MPT_FALLTHROUGH __attribute__((fallthrough)) -#elif defined(__has_cpp_attribute) - #if __has_cpp_attribute(fallthrough) - #define MPT_FALLTHROUGH [[fallthrough]] - #else - #define MPT_FALLTHROUGH MPT_DO { } MPT_WHILE_0 - #endif -#else - #define MPT_FALLTHROUGH MPT_DO { } MPT_WHILE_0 -#endif +#define MPT_FALLTHROUGH [[fallthrough]] Index: common/mptBaseTypes.h =================================================================== --- common/mptBaseTypes.h (revision 11987) +++ common/mptBaseTypes.h (working copy) @@ -191,20 +191,10 @@ MPT_STATIC_ASSERT(sizeof(char) == 1); -#if MPT_CXX_AT_LEAST(17) namespace mpt { using byte = std::byte; } // namespace mpt #define MPT_BYTE_IS_STD_BYTE 1 -#else -// In C++11 and C++14, a C++17 compatible definition of byte would not be required to be allowed to alias other types, -// thus just use a typedef for unsigned char which is guaranteed to be allowed to alias. -//enum class byte : unsigned char { }; -namespace mpt { -using byte = unsigned char; -} // namespace mpt -#define MPT_BYTE_IS_STD_BYTE 0 -#endif MPT_STATIC_ASSERT(sizeof(mpt::byte) == 1); MPT_STATIC_ASSERT(alignof(mpt::byte) == 1); Index: common/mptBaseUtils.h =================================================================== --- common/mptBaseUtils.h (revision 11987) +++ common/mptBaseUtils.h (working copy) @@ -67,9 +67,7 @@ namespace mpt { -// Work-around for GCC5, which does not allow throw statements in constexpr functions, but only throw expressions inside ternary ? operator. -// And also work-around for a simpler, MPT_COMPILER_QUIRK_NO_CONSTEXPR14_THROW-dependent work-around, which would have thrown in a separate constexpr function, -// which however is not allowed due to the requirement of at least 1 non-throwing function argument combination in C++ (14,17,2a) (and thus all other compilers). +// Work-around for the requirement of at least 1 non-throwing function argument combination in C++ (17,2a). template <typename Exception> MPT_CONSTEXPR14_FUN bool constexpr_throw_helper(Exception && e, bool really = true) { @@ -432,29 +430,8 @@ namespace mpt { - // C++17 clamp - -#if MPT_CXX_AT_LEAST(17) - using std::clamp; - -#else - -template<typename T, typename Compare> -MPT_CONSTEXPR11_FUN const T & clamp(const T & v, const T & lo, const T & hi, Compare comp) -{ - return comp(v, lo) ? lo : comp(hi, v) ? hi : v; -} - -template<typename T> -MPT_CONSTEXPR11_FUN const T & clamp(const T & v, const T & lo, const T & hi) -{ - return mpt::clamp(v, lo, hi, std::less<T>()); -} - -#endif - } // namespace mpt @@ -706,54 +683,8 @@ namespace mpt { - -#if MPT_CXX_AT_LEAST(17) - using std::gcd; using std::lcm; - -#else - - // Greatest Common Divisor. Always returns non-negative number. - // compatible with C++17 std::gcd - template <typename A, typename B> - inline typename std::common_type<A, B>::type gcd(A a_, B b_) - { - typename std::common_type<A, B>::type a = a_; - typename std::common_type<A, B>::type b = b_; - if(a < 0) - a = -a; - if(b < 0) - b = -b; - for(;;) - { - if(a == 0) - return b; - b %= a; - if(b == 0) - return a; - a %= b; - } - } - - // Least Common Multiple. Always returns non-negative number. - // compatible with C++17 std::lcm - template <typename A, typename B> - inline typename std::common_type<A, B>::type lcm(A a_, B b_) - { - typename std::common_type<A, B>::type a = a_; - typename std::common_type<A, B>::type b = b_; - if(a < 0) - a = -a; - if(b < 0) - b = -b; - if((a | b) == 0) - return 0; - return a / mpt::gcd(a, b) * b; - } - -#endif - } // namespace mpt Index: common/mptString.cpp =================================================================== --- common/mptString.cpp (revision 11987) +++ common/mptString.cpp (working copy) @@ -12,9 +12,6 @@ #include "Endianness.h" -#if defined(MPT_CHARSET_CODECVTUTF8) -#include <codecvt> -#endif #if defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) #include <cstdlib> #endif @@ -332,7 +329,7 @@ }; */ -#if defined(MPT_CHARSET_CODECVTUTF8) || defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) +#if defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) static const uint32 CharsetTableISO8859_15[256] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, @@ -391,7 +388,7 @@ 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 }; -#endif // MPT_CHARSET_CODECVTUTF8 || MPT_CHARSET_INTERNAL || MPT_CHARSET_WIN32 +#endif // MPT_CHARSET_INTERNAL || MPT_CHARSET_WIN32 #define C(x) (static_cast<uint8>((x))) @@ -510,7 +507,7 @@ return res; } -#if defined(MPT_CHARSET_CODECVTUTF8) || defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) +#if defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) static widestring FromAscii(const std::string &str, widechar replacement = wide_default_replacement) { @@ -828,26 +825,8 @@ #endif // MPT_ENABLE_CHARSET_LOCALE && !MPT_LOCALE_ASSUME_CHARSET -#endif // MPT_CHARSET_CODECVTUTF8 || MPT_CHARSET_INTERNAL || MPT_CHARSET_WIN32 +#endif // MPT_CHARSET_INTERNAL || MPT_CHARSET_WIN32 -#if defined(MPT_CHARSET_CODECVTUTF8) - -static std::wstring FromUTF8(const std::string &str, wchar_t replacement = L'\uFFFD') -{ - MPT_UNREFERENCED_PARAMETER(replacement); - std::wstring_convert<std::codecvt_utf8<wchar_t> > conv; - return conv.from_bytes(str); -} - -static std::string ToUTF8(const std::wstring &str, char replacement = '?') -{ - MPT_UNREFERENCED_PARAMETER(replacement); - std::wstring_convert<std::codecvt_utf8<wchar_t> > conv; - return conv.to_bytes(str); -} - -#endif // MPT_CHARSET_CODECVTUTF8 - #if defined(MPT_CHARSET_INTERNAL) || defined(MPT_CHARSET_WIN32) static widestring FromUTF8(const std::string &str, widechar replacement = wide_default_replacement) @@ -1175,16 +1154,10 @@ { return Tdststring(); } - #if MPT_CXX_AT_LEAST(17) - Tdststring encoded_string(required_size, char()); - WideCharToMultiByte(codepage, 0, src.c_str(), -1, encoded_string.data(), required_size, nullptr, nullptr); - encoded_string.resize(encoded_string.size() - 1); // remove \0 - return encoded_string; - #else - std::vector<CHAR> encoded_string(required_size); - WideCharToMultiByte(codepage, 0, src.c_str(), -1, encoded_string.data(), required_size, nullptr, nullptr); - return reinterpret_cast<const typename Tdststring::value_type*>(encoded_string.data()); - #endif + Tdststring encoded_string(required_size, char()); + WideCharToMultiByte(codepage, 0, src.c_str(), -1, encoded_string.data(), required_size, nullptr, nullptr); + encoded_string.resize(encoded_string.size() - 1); // remove \0 + return encoded_string; #elif defined(MPT_CHARSET_ICONV) iconv_t conv = iconv_t(); conv = iconv_open(CharsetToStringTranslit(charset), Charset_wchar_t()); @@ -1302,16 +1275,10 @@ { return widestring(); } - #if MPT_CXX_AT_LEAST(17) - widestring decoded_string(required_size, widechar()); - MultiByteToWideChar(codepage, 0, reinterpret_cast<const char*>(src.c_str()), -1, decoded_string.data(), required_size); - decoded_string.resize(decoded_string.size() - 1); // remove \0 - return decoded_string; - #else - std::vector<WCHAR> decoded_string(required_size); - MultiByteToWideChar(codepage, 0, reinterpret_cast<const char*>(src.c_str()), -1, decoded_string.data(), required_size); - return decoded_string.data(); - #endif + widestring decoded_string(required_size, widechar()); + MultiByteToWideChar(codepage, 0, reinterpret_cast<const char*>(src.c_str()), -1, decoded_string.data(), required_size); + decoded_string.resize(decoded_string.size() - 1); // remove \0 + return decoded_string; #elif defined(MPT_CHARSET_ICONV) iconv_t conv = iconv_t(); conv = iconv_open(Charset_wchar_t(), CharsetToString(charset)); @@ -1725,16 +1692,10 @@ { return mpt::ustring(); } - #if MPT_CXX_AT_LEAST(17) - std::wstring decoded_string(required_size, wchar_t()); - MultiByteToWideChar(codepage, 0, src.c_str(), -1, decoded_string.data(), required_size); - decoded_string.resize(decoded_string.size() - 1); // remove \0 - return mpt::ToUnicode(decoded_string); - #else - std::vector<WCHAR> decoded_string(required_size); - MultiByteToWideChar(codepage, 0, src.c_str(), -1, decoded_string.data(), required_size); - return mpt::ToUnicode(std::wstring(decoded_string.data())); - #endif + std::wstring decoded_string(required_size, wchar_t()); + MultiByteToWideChar(codepage, 0, src.c_str(), -1, decoded_string.data(), required_size); + decoded_string.resize(decoded_string.size() - 1); // remove \0 + return mpt::ToUnicode(decoded_string); } #endif // MPT_OS_WINDOWS Index: common/mptStringFormat.cpp =================================================================== --- common/mptStringFormat.cpp (revision 11987) +++ common/mptStringFormat.cpp (working copy) @@ -10,7 +10,7 @@ #include "stdafx.h" #include "mptStringFormat.h" -#if MPT_CXX_AT_LEAST(17) && MPT_COMPILER_MSVC +#if MPT_COMPILER_MSVC #define MPT_FORMAT_CXX17_INT 1 #else #define MPT_FORMAT_CXX17_INT 0 Index: common/version.cpp =================================================================== --- common/version.cpp (revision 11987) +++ common/version.cpp (working copy) @@ -323,9 +323,6 @@ #if defined(MPT_CHARSET_ICONV) UL_(" +ICONV") #endif - #if defined(MPT_CHARSET_CODECVTUTF8) - UL_(" +CODECVTUTF8") - #endif #if defined(MPT_CHARSET_INTERNAL) UL_(" +INTERNALCHARSETS") #endif Index: doc/backporting_patches.md =================================================================== --- doc/backporting_patches.md (revision 11987) +++ doc/backporting_patches.md (working copy) @@ -10,7 +10,18 @@ OpenMPT 1.28 / libopenmpt 0.4 ----------------------------- + * Replace `std::abs` by `mpt::abs`. + * Replace `std::byte` by `mpt::byte`. + * Replace `std::clamp` by `mpt::clamp`. + * Replace `std::data` by `mpt::data`. + * Replace `std::gcd` by `mpt::gcd`. + * Replace `std::lcm` by `mpt::lcm`. * Replace `std::make_unique` by `mpt::make_unique`. + * Replace `std::size` by `mpt::size`. + * Replace `if constexpr` by `MPT_CONSTANT_IF`. + * Replace `static_assert` by `MPT_STATIC_ASSERT`. + * Replace `[[discard]]` by `MPT_DISCARD`. + * Replace `[[fallthrough]]` by `MPT_FALLTHROUGH`. OpenMPT 1.27 / libopenmpt 0.3 ----------------------------- Index: libopenmpt/dox/changelog.md =================================================================== --- libopenmpt/dox/changelog.md (revision 11987) +++ libopenmpt/dox/changelog.md (working copy) @@ -15,10 +15,11 @@ * [**Regression**] foo_openmpt: foo_openmpt is discontinued. Please use Kode54's fork foo_openmpt54: <https://www.foobar2000.org/components/view/foo_openmpt54>. - * [**Regression**] Support for C++11 has been removed. C++14 is now required. + * [**Regression**] Support for C++11 and C++14 has been removed. C++17 is now + required. * [**Regression**] Support for Visual Studio 2015 has been removed. - * [**Regression**] Support for GCC 4.8, 4.9 has been removed. - * [**Regression**] Support for Clang 3.6, 3.7 has been removed. + * [**Regression**] Support for GCC 4.8, 4.9, 5, 6 has been removed. + * [**Regression**] Support for Clang 3.6, 3.7, 3.8, 3.9, 4 has been removed. ### libopenmpt 0.4.0 Index: libopenmpt/dox/dependencies.md =================================================================== --- libopenmpt/dox/dependencies.md (revision 11987) +++ libopenmpt/dox/dependencies.md (working copy) @@ -11,14 +11,14 @@ * Supported compilers for building libopenmpt: * **Microsoft Visual Studio 2017** or higher, running on a x86-64 build system (other target systems are supported) - * **GCC 5.1** or higher - * **Clang 3.8** or higher - * **MinGW-W64 5.1** or higher (it is recommended to preferably use + * **GCC 7.1** or higher + * **Clang 5** or higher + * **MinGW-W64 7.1** or higher (it is recommended to preferably use posix threading model as opposed to win32 threading model, or at least have mingw-std-threads available otherwise) * **emscripten 1.38.5** or higher * **DJGPP GCC 7.2** or higher - * any other **C++14 compliant** compiler (full standard compliant mode is + * any other **C++17 compliant** compiler (full standard compliant mode is known to work with GCC >= 5.1 and Clang >= 3.8) libopenmpt makes the following assumptions about the C++ implementation @@ -73,11 +73,11 @@ * Supported compilers for building openmpt123: * **Microsoft Visual Studio 2017** or higher, running on a x86-64 build system (other target systems are supported) - * **GCC 5.1** or higher - * **Clang 3.8** or higher - * **MinGW-W64 5.1** or higher + * **GCC 7.1** or higher + * **Clang 5** or higher + * **MinGW-W64 7.1** or higher * **DJGPP GCC 7.2** or higher - * any **C++14 compliant** compiler + * any **C++17 compliant** compiler * Live sound output requires one of: * **PulseAudio** * **SDL 2** Index: libopenmpt/dox/quickstart.md =================================================================== --- libopenmpt/dox/quickstart.md (revision 11987) +++ libopenmpt/dox/quickstart.md (working copy) @@ -7,7 +7,7 @@ 1. Grab a `libopenmpt-VERSION.autotools.tar.gz` tarball. 2. Get dependencies: - - **gcc >= 5.1** or **clang >= 3.8** + - **gcc >= 7.1** or **clang >= 5** - **pkg-config >= 0.24** - **zlib** - **libogg**, **libvorbis**, **libvorbisfile** Index: mptrack/ExceptionHandler.cpp =================================================================== --- mptrack/ExceptionHandler.cpp (revision 11987) +++ mptrack/ExceptionHandler.cpp (working copy) @@ -50,17 +50,11 @@ bool ExceptionHandler::useImplicitFallbackSEH = false; bool ExceptionHandler::useExplicitSEH = false; bool ExceptionHandler::handleStdTerminate = false; -#if MPT_CXX_BEFORE(17) -bool ExceptionHandler::handleStdUnexpected = false; -#endif bool ExceptionHandler::handleMfcExceptions = false; static LPTOP_LEVEL_EXCEPTION_FILTER g_OriginalUnhandledExceptionFilter = nullptr; static std::terminate_handler g_OriginalTerminateHandler = nullptr; -#if MPT_CXX_BEFORE(17) -static std::unexpected_handler g_OriginalUnexpectedHandler = nullptr; -#endif static UINT g_OriginalErrorMode = 0; @@ -658,12 +652,6 @@ { g_OriginalTerminateHandler = std::set_terminate(&mpt_terminate_handler); } -#if MPT_CXX_BEFORE(17) - if(handleStdUnexpected) - { - g_OriginalUnexpectedHandler = std::set_unexpected(&mpt_unexpected_handler); - } -#endif } @@ -699,13 +687,6 @@ void ExceptionHandler::Unregister() { -#if MPT_CXX_BEFORE(17) - if(handleStdUnexpected) - { - std::set_unexpected(g_OriginalUnexpectedHandler); - g_OriginalUnexpectedHandler = nullptr; - } -#endif if(handleStdTerminate) { std::set_terminate(g_OriginalTerminateHandler); @@ -719,27 +700,6 @@ } -#if MPT_CXX_BEFORE(17) -static void mpt_unexpected_handler() -{ - DebugReporter(DumpModeCrash, nullptr).ReportError(U_("An unexpected C++ exception occured: std::unexpected() called.")); - // We disable the call to std::terminate() as that would re-renter the crash - // handler another time, but with less information available. -#if 1 - std::abort(); -#else - if(g_OriginalUnexpectedHandler) - { - g_OriginalUnexpectedHandler(); - } else - { - std::terminate(); - } -#endif -} -#endif - - static void mpt_terminate_handler() { DebugReporter(DumpModeCrash, nullptr).ReportError(U_("A C++ runtime crash occurred: std::terminate() called.")); Index: mptrack/Mptrack.cpp =================================================================== --- mptrack/Mptrack.cpp (revision 11987) +++ mptrack/Mptrack.cpp (working copy) @@ -832,9 +832,6 @@ ExceptionHandler::useImplicitFallbackSEH = false; ExceptionHandler::useExplicitSEH = true; ExceptionHandler::handleStdTerminate = true; - #if MPT_CXX_BEFORE(17) - ExceptionHandler::handleStdUnexpected = true; - #endif ExceptionHandler::handleMfcExceptions = true; ExceptionHandler::debugExceptionHandler = true; } else if(IsDebuggerPresent() || cmdInfo.m_noCrashHandler) @@ -843,9 +840,6 @@ ExceptionHandler::useImplicitFallbackSEH = false; ExceptionHandler::useExplicitSEH = false; ExceptionHandler::handleStdTerminate = false; - #if MPT_CXX_BEFORE(17) - ExceptionHandler::handleStdUnexpected = false; - #endif ExceptionHandler::handleMfcExceptions = false; ExceptionHandler::debugExceptionHandler = false; } else @@ -854,9 +848,6 @@ ExceptionHandler::useImplicitFallbackSEH = true; ExceptionHandler::useExplicitSEH = true; ExceptionHandler::handleStdTerminate = true; - #if MPT_CXX_BEFORE(17) - ExceptionHandler::handleStdUnexpected = true; - #endif ExceptionHandler::handleMfcExceptions = true; ExceptionHandler::debugExceptionHandler = false; } Index: mptrack/Settings.cpp =================================================================== --- mptrack/Settings.cpp (revision 11987) +++ mptrack/Settings.cpp (working copy) @@ -62,9 +62,6 @@ } -#if MPT_CXX_AT_LEAST(17) - - mpt::ustring SettingValue::FormatValueAsString() const { switch(GetType()) @@ -118,65 +115,6 @@ } -#else - - -mpt::ustring SettingValue::FormatValueAsString() const -{ - switch(GetType()) - { - case SettingTypeBool: - return mpt::ufmt::val(valueBool); - break; - case SettingTypeInt: - return mpt::ufmt::val(valueInt); - break; - case SettingTypeFloat: - return mpt::ufmt::val(valueFloat); - break; - case SettingTypeString: - return valueString; - break; - case SettingTypeBinary: - return Util::BinToHex(mpt::as_span(valueBinary)); - break; - case SettingTypeNone: - default: - return mpt::ustring(); - break; - } -} - - -void SettingValue::SetFromString(const AnyStringLocale &newVal) -{ - switch(GetType()) - { - case SettingTypeBool: - valueBool = ConvertStrTo<bool>(newVal); - break; - case SettingTypeInt: - valueInt = ConvertStrTo<int32>(newVal); - break; - case SettingTypeFloat: - valueFloat = ConvertStrTo<double>(newVal); - break; - case SettingTypeString: - valueString = newVal; - break; - case SettingTypeBinary: - valueBinary = Util::HexToBin(newVal); - break; - case SettingTypeNone: - default: - break; - } -} - - -#endif - - SettingValue SettingsContainer::BackendsReadSetting(const SettingPath &path, const SettingValue &def) const { return backend->ReadSetting(path, def); Index: mptrack/Settings.h =================================================================== --- mptrack/Settings.h (revision 11987) +++ mptrack/Settings.h (working copy) @@ -19,9 +19,7 @@ #include <map> #include <set> -#if MPT_CXX_AT_LEAST(17) #include <variant> -#endif OPENMPT_NAMESPACE_BEGIN @@ -40,7 +38,6 @@ // SettingValue is a variant type that stores any type that can natively be represented in a config backend. // Any other type that should be stored must provide a matching ToSettingValue and FromSettingValue. // Other types can optionally also set a type tag which would get checked in debug builds. -#if MPT_CXX_AT_LEAST(17) class SettingValue { private: @@ -190,185 +187,6 @@ mpt::ustring FormatValueAsString() const; void SetFromString(const AnyStringLocale &newVal); }; -#else -class SettingValue -{ -private: - bool valueBool; - int32 valueInt; - double valueFloat; - mpt::ustring valueString; - std::vector<mpt::byte> valueBinary; - SettingType type; - std::string typeTag; - void Init() - { - valueBool = false; - valueInt = 0; - valueFloat = 0.0; - valueString = mpt::ustring(); - valueBinary.clear(); - type = SettingTypeNone; - typeTag = std::string(); - } -public: - bool operator == (const SettingValue &other) const - { - return type == other.type - && typeTag == other.typeTag - && valueBool == other.valueBool - && valueInt == other.valueInt - && valueFloat == other.valueFloat - && valueString == other.valueString - && valueBinary == other.valueBinary - ; - } - bool operator != (const SettingValue &other) const - { - return !(*this == other); - } - SettingValue() - { - Init(); - } - SettingValue(const SettingValue &other) - { - Init(); - *this = other; - } - SettingValue & operator = (const SettingValue &other) - { - if(this == &other) - { - return *this; - } - MPT_ASSERT(type == SettingTypeNone || (type == other.type && typeTag == other.typeTag)); - type = other.type; - valueBool = other.valueBool; - valueInt = other.valueInt; - valueFloat = other.valueFloat; - valueString = other.valueString; - valueBinary = other.valueBinary; - typeTag = other.typeTag; - return *this; - } - SettingValue(bool val) - { - Init(); - type = SettingTypeBool; - valueBool = val; - } - SettingValue(int32 val) - { - Init(); - type = SettingTypeInt; - valueInt = val; - } - SettingValue(double val) - { - Init(); - type = SettingTypeFloat; - valueFloat = val; - } - SettingValue(const mpt::ustring &val) - { - Init(); - type = SettingTypeString; - valueString = val; - } - SettingValue(const std::vector<mpt::byte> &val) - { - Init(); - type = SettingTypeBinary; - valueBinary = val; - } - SettingValue(bool val, const std::string &typeTag_) - { - Init(); - type = SettingTypeBool; - typeTag = typeTag_; - valueBool = val; - } - SettingValue(int32 val, const std::string &typeTag_) - { - Init(); - type = SettingTypeInt; - typeTag = typeTag_; - valueInt = val; - } - SettingValue(double val, const std::string &typeTag_) - { - Init(); - type = SettingTypeFloat; - typeTag = typeTag_; - valueFloat = val; - } - SettingValue(const mpt::ustring &val, const std::string &typeTag_) - { - Init(); - type = SettingTypeString; - typeTag = typeTag_; - valueString = val; - } - SettingValue(const std::vector<mpt::byte> &val, const std::string &typeTag_) - { - Init(); - type = SettingTypeBinary; - typeTag = typeTag_; - valueBinary = val; - } - // these need to be explicitly deleted because otherwise the bool overload will catch the pointers - SettingValue(const char *val) = delete; - SettingValue(const wchar_t *val) = delete; - SettingValue(const char *val, const std::string &typeTag_) = delete; - SettingValue(const wchar_t *val, const std::string &typeTag_) = delete; - SettingType GetType() const - { - return type; - } - bool HasTypeTag() const - { - return !typeTag.empty(); - } - std::string GetTypeTag() const - { - return typeTag; - } - template <typename T> - T as() const - { - return *this; - } - operator bool () const - { - MPT_ASSERT(type == SettingTypeBool); - return valueBool; - } - operator int32 () const - { - MPT_ASSERT(type == SettingTypeInt); - return valueInt; - } - operator double () const - { - MPT_ASSERT(type == SettingTypeFloat); - return valueFloat; - } - operator mpt::ustring () const - { - MPT_ASSERT(type == SettingTypeString); - return valueString; - } - operator std::vector<mpt::byte> () const - { - MPT_ASSERT(type == SettingTypeBinary); - return valueBinary; - } - mpt::ustring FormatTypeAsString() const; - mpt::ustring FormatValueAsString() const; - void SetFromString(const AnyStringLocale &newVal); -}; -#endif template<typename T> Index: README.md =================================================================== --- README.md (revision 11987) +++ README.md (working copy) @@ -172,9 +172,9 @@ The minimum required compiler versions are: - - gcc 5 + - gcc 7 - - clang 3.8 + - clang 5 The Makefile requires pkg-config for native builds. For sound output in openmpt123, PortAudio or SDL is required. Index: soundlib/Load_mdl.cpp =================================================================== --- soundlib/Load_mdl.cpp (revision 11987) +++ soundlib/Load_mdl.cpp (working copy) @@ -598,14 +598,7 @@ if(sampleHeader.smpNum == 0) continue; #if 1 - #if MPT_GCC_BEFORE(6,1,0) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wtype-limits" - #endif STATIC_ASSERT((mpt::limits<decltype(sampleHeader.smpNum)>::max)() < MAX_SAMPLES); - #if MPT_GCC_BEFORE(6,1,0) - #pragma GCC diagnostic pop - #endif #else MPT_MAYBE_CONSTANT_IF(sampleHeader.smpNum >= MAX_SAMPLES) continue; | ||||
Has the bug occurred in previous versions? | |||||
Tested code revision (in case you know it) | |||||
Date Modified | Username | Field | Change |
---|---|---|---|
2019-08-25 15:56 | manx | New Issue | |
2019-08-25 15:56 | manx | Status | new => assigned |
2019-08-25 15:56 | manx | Assigned To | => manx |
2019-08-25 15:56 | manx | Relationship added | related to 0001183 |
2019-08-25 15:57 | manx | Relationship added | related to 0001135 |
2019-08-25 16:01 | manx | Additional Information Updated | |
2019-08-25 16:02 | manx | Additional Information Updated | |
2019-09-05 12:02 | manx | Description Updated | |
2019-09-05 13:10 | manx | Relationship added | related to 0001240 |
2019-09-05 15:20 | manx | File Added: require-cpp17-v1.patch | |
2019-09-05 18:44 | manx | Target Version | OpenMPT 1.?? (long term goals) => OpenMPT 1.29.01.00 / libopenmpt 0.5.0 (upgrade first) |
2019-09-06 11:34 | manx | Status | assigned => resolved |
2019-09-06 11:34 | manx | Resolution | open => fixed |
2019-09-06 11:34 | manx | Fixed in Version | => OpenMPT 1.29.01.00 / libopenmpt 0.5.0 (upgrade first) |
2019-09-06 11:34 | manx | Note Added: 0004042 |