From 51f7862e00ea8df0e674487c23b95287e8a46c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 5 Apr 2022 11:51:26 +0200 Subject: [PATCH] ShaderTools,Trade: return Optional> from converter plugins. Consistently with changes done to Utility::Path, this enforces proper error handling on user side. Originally I didn't want to do this and instead wanted to have a special Array instance devoted for an error state, but that still would allow the error state be errorneously treated as a successful but empty array. --- src/Magnum/ShaderTools/AbstractConverter.cpp | 124 ++++-- src/Magnum/ShaderTools/AbstractConverter.h | 80 +++- .../Test/AbstractConverterTest.cpp | 147 ++++--- src/Magnum/Trade/AbstractImageConverter.cpp | 389 +++++++++++++----- src/Magnum/Trade/AbstractImageConverter.h | 217 ++++++++-- src/Magnum/Trade/AbstractSceneConverter.cpp | 25 +- src/Magnum/Trade/AbstractSceneConverter.h | 31 +- .../Trade/Test/AbstractImageConverterTest.cpp | 204 +++++---- .../Trade/Test/AbstractSceneConverterTest.cpp | 10 +- .../AnyImageConverter/AnyImageConverter.cpp | 2 +- .../AnySceneConverter/AnySceneConverter.cpp | 2 +- .../AnyShaderConverter/AnyConverter.cpp | 7 +- .../AnyShaderConverter/AnyConverter.h | 4 +- .../MagnumFontConverter.cpp | 1 + .../TgaImageConverter/TgaImageConverter.cpp | 10 +- .../TgaImageConverter/TgaImageConverter.h | 2 +- 16 files changed, 871 insertions(+), 384 deletions(-) diff --git a/src/Magnum/ShaderTools/AbstractConverter.cpp b/src/Magnum/ShaderTools/AbstractConverter.cpp index 3d46fe7d1..eadd94507 100644 --- a/src/Magnum/ShaderTools/AbstractConverter.cpp +++ b/src/Magnum/ShaderTools/AbstractConverter.cpp @@ -61,7 +61,7 @@ using namespace Containers::Literals; Containers::StringView AbstractConverter::pluginInterface() { return /* [interface] */ -"cz.mosra.magnum.ShaderTools.AbstractConverter/0.1"_s +"cz.mosra.magnum.ShaderTools.AbstractConverter/0.1.1"_s /* [interface] */ ; } @@ -272,18 +272,29 @@ std::pair AbstractConverter::doValidateFile(const Stag } } -Containers::Array AbstractConverter::convertDataToData(const Stage stage, const Containers::ArrayView data) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::OptionalButAlsoArray +#endif +AbstractConverter::convertDataToData(const Stage stage, const Containers::ArrayView data) { CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, "ShaderTools::AbstractConverter::convertDataToData(): feature not supported", {}); /* Cast to a non-void type for more convenience */ - Containers::Array out = doConvertDataToData(stage, Containers::arrayCast(data)); - CORRADE_ASSERT(!out.deleter(), + Containers::Optional> out = doConvertDataToData(stage, Containers::arrayCast(data)); + CORRADE_ASSERT(!out || !out->deleter(), "ShaderTools::AbstractConverter::convertDataToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::OptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractConverter::doConvertDataToData(Stage, Containers::ArrayView) { +Containers::Optional> AbstractConverter::doConvertDataToData(Stage, Containers::ArrayView) { CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::convertDataToData(): feature advertised but not implemented", {}); } @@ -294,10 +305,10 @@ bool AbstractConverter::convertDataToFile(const Stage stage, const Containers::A /** @todo this needs expansion once output callbacks are supported as well */ /* Cast to a non-void type for more convenience */ - const Containers::Array out = doConvertDataToData(stage, Containers::arrayCast(data)); + const Containers::Optional> out = doConvertDataToData(stage, Containers::arrayCast(data)); if(!out) return false; - if(!Utility::Path::write(filename, out)) { + if(!Utility::Path::write(filename, *out)) { Error{} << "ShaderTools::AbstractConverter::convertDataToFile(): cannot write to file" << filename; return false; } @@ -305,13 +316,13 @@ bool AbstractConverter::convertDataToFile(const Stage stage, const Containers::A return true; } -Containers::Array AbstractConverter::convertDataToDataUsingInputFileCallbacks(const char* const prefix, const Stage stage, const Containers::StringView filename) { +Containers::Optional> AbstractConverter::convertDataToDataUsingInputFileCallbacks(const char* const prefix, const Stage stage, const Containers::StringView filename) { const Containers::Optional> data = _inputFileCallback(filename, InputFileCallbackPolicy::LoadTemporary, _inputFileCallbackUserData); if(!data) { Error{} << prefix << "cannot open file" << filename; return {}; } - Containers::Array out = doConvertDataToData(stage, *data); + Containers::Optional> out = doConvertDataToData(stage, *data); _inputFileCallback(filename, InputFileCallbackPolicy::Close, _inputFileCallbackUserData); return out; } @@ -341,10 +352,10 @@ bool AbstractConverter::convertFileToFile(const Stage stage, const Containers::S actual file loading to the default implementation (callback used in the base doConvertFileToFile() implementation, because this branch is never taken in that case) */ - const Containers::Array out = convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToFile():", stage, from); + const Containers::Optional> out = convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToFile():", stage, from); if(!out) return false; - if(!Utility::Path::write(to, out)) { + if(!Utility::Path::write(to, *out)) { Error{} << "ShaderTools::AbstractConverter::convertFileToFile(): cannot write to file" << to; return false; } @@ -359,7 +370,7 @@ bool AbstractConverter::doConvertFileToFile(const Stage stage, const Containers: CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, "ShaderTools::AbstractConverter::convertFileToFile(): feature advertised but not implemented", {}); /** @todo this needs expansion once output callbacks are supported as well */ - Containers::Array out; + Containers::Optional> out; /* If callbacks are set, use them. This is the same implementation as in convertFileToFile(), see the comment there for details. */ @@ -379,7 +390,7 @@ bool AbstractConverter::doConvertFileToFile(const Stage stage, const Containers: if(!out) return false; - if(!Utility::Path::write(to, out)) { + if(!Utility::Path::write(to, *out)) { Error{} << "ShaderTools::AbstractConverter::convertFileToFile(): cannot write to file" << to; return false; } @@ -387,11 +398,16 @@ bool AbstractConverter::doConvertFileToFile(const Stage stage, const Containers: return true; } -Containers::Array AbstractConverter::convertFileToData(const Stage stage, const Containers::StringView filename) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::OptionalButAlsoArray +#endif +AbstractConverter::convertFileToData(const Stage stage, const Containers::StringView filename) { CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, "ShaderTools::AbstractConverter::convertFileToData(): feature not supported", {}); - Containers::Array out; + Containers::Optional> out; /* If input file callbacks are not set or the converter supports handling them directly, call into the implementation */ @@ -415,12 +431,18 @@ Containers::Array AbstractConverter::convertFileToData(const Stage stage, out = convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToData():", stage, filename); } - CORRADE_ASSERT(!out.deleter(), + CORRADE_ASSERT(!out || !out->deleter(), "ShaderTools::AbstractConverter::convertFileToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::OptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractConverter::doConvertFileToData(const Stage stage, const Containers::StringView filename) { +Containers::Optional> AbstractConverter::doConvertFileToData(const Stage stage, const Containers::StringView filename) { /* If callbacks are set, use them. This is the same implementation as in convertFileToFile(), see the comment there for details. */ if(_inputFileCallback) { @@ -438,7 +460,12 @@ Containers::Array AbstractConverter::doConvertFileToData(const Stage stage } } -Containers::Array AbstractConverter::linkDataToData(const Containers::ArrayView>> data) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::OptionalButAlsoArray +#endif +AbstractConverter::linkDataToData(const Containers::ArrayView>> data) { CORRADE_ASSERT(features() >= ConverterFeature::LinkData, "ShaderTools::AbstractConverter::linkDataToData(): feature not supported", {}); CORRADE_ASSERT(!(_flags & ConverterFlag::PreprocessOnly), @@ -447,17 +474,28 @@ Containers::Array AbstractConverter::linkDataToData(const Containers::Arra "ShaderTools::AbstractConverter::linkDataToData(): no data passed", {}); /* Cast to a non-void type for more convenience */ - Containers::Array out = doLinkDataToData(Containers::arrayCast>>(data)); - CORRADE_ASSERT(!out.deleter(), + Containers::Optional> out = doLinkDataToData(Containers::arrayCast>>(data)); + CORRADE_ASSERT(!out || !out->deleter(), "ShaderTools::AbstractConverter::linkDataToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::OptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractConverter::linkDataToData(const std::initializer_list>> data) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::OptionalButAlsoArray +#endif +AbstractConverter::linkDataToData(const std::initializer_list>> data) { return linkDataToData(Containers::arrayView(data)); } -Containers::Array AbstractConverter::doLinkDataToData(Containers::ArrayView>>) { +Containers::Optional> AbstractConverter::doLinkDataToData(Containers::ArrayView>>) { CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::linkDataToData(): feature advertised but not implemented", {}); } @@ -472,10 +510,10 @@ bool AbstractConverter::linkDataToFile(const Containers::ArrayView out = doLinkDataToData(Containers::arrayCast>>(data)); + const Containers::Optional> out = doLinkDataToData(Containers::arrayCast>>(data)); if(!out) return false; - if(!Utility::Path::write(filename, out)) { + if(!Utility::Path::write(filename, *out)) { Error{} << "ShaderTools::AbstractConverter::linkDataToFile(): cannot write to file" << filename; return false; } @@ -487,7 +525,7 @@ bool AbstractConverter::linkDataToFile(const std::initializer_list AbstractConverter::linkDataToDataUsingInputFileCallbacks(const char* const prefix, const Containers::ArrayView> filenames) { +Containers::Optional> AbstractConverter::linkDataToDataUsingInputFileCallbacks(const char* const prefix, const Containers::ArrayView> filenames) { Containers::Array>> data{NoInit, filenames.size()}; /* First load all files. Remember how many of these succeeded so we can @@ -502,7 +540,7 @@ Containers::Array AbstractConverter::linkDataToDataUsingInputFileCallbacks } /* If all input files loaded successfully, process */ - Containers::Array out; + Containers::Optional> out; if(i == filenames.size()) out = doLinkDataToData(data); /* Close again all input files that loaded successfully */ @@ -551,10 +589,10 @@ bool AbstractConverter::linkFilesToFile(const Containers::ArrayView out = linkDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::linkFilesToFile():", from); + const Containers::Optional> out = linkDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::linkFilesToFile():", from); if(!out) return false; - if(!Utility::Path::write(to, out)) { + if(!Utility::Path::write(to, *out)) { Error{} << "ShaderTools::AbstractConverter::linkFilesToFile(): cannot write to file" << to; return false; } @@ -573,7 +611,7 @@ bool AbstractConverter::doLinkFilesToFile(const Containers::ArrayView= ConverterFeature::LinkData, "ShaderTools::AbstractConverter::linkFilesToFile(): feature advertised but not implemented", {}); /** @todo this needs expansion once output callbacks are supported as well */ - Containers::Array out; + Containers::Optional> out; /* If callbacks are set, use them. This is the same implementation as in convertFileToFile(), see the comment there for details. */ @@ -606,7 +644,7 @@ bool AbstractConverter::doLinkFilesToFile(const Containers::ArrayView AbstractConverter::linkFilesToData(const Containers::ArrayView> filenames) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::OptionalButAlsoArray +#endif +AbstractConverter::linkFilesToData(const Containers::ArrayView> filenames) { CORRADE_ASSERT(features() >= ConverterFeature::LinkData, "ShaderTools::AbstractConverter::linkFilesToData(): feature not supported", {}); CORRADE_ASSERT(!(_flags & ConverterFlag::PreprocessOnly), @@ -622,7 +665,7 @@ Containers::Array AbstractConverter::linkFilesToData(const Containers::Arr CORRADE_ASSERT(!filenames.isEmpty(), "ShaderTools::AbstractConverter::linkFilesToData(): no files passed", {}); - Containers::Array out; + Containers::Optional> out; /* If input file callbacks are not set or the converter supports handling them directly, call into the implementation */ @@ -646,16 +689,27 @@ Containers::Array AbstractConverter::linkFilesToData(const Containers::Arr out = linkDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::linkFilesToData():", filenames); } - CORRADE_ASSERT(!out.deleter(), + CORRADE_ASSERT(!out || !out->deleter(), "ShaderTools::AbstractConverter::linkFilesToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::OptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractConverter::linkFilesToData(const std::initializer_list> filenames) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::OptionalButAlsoArray +#endif +AbstractConverter::linkFilesToData(const std::initializer_list> filenames) { return linkFilesToData(Containers::arrayView(filenames)); } -Containers::Array AbstractConverter::doLinkFilesToData(const Containers::ArrayView> filenames) { +Containers::Optional> AbstractConverter::doLinkFilesToData(const Containers::ArrayView> filenames) { /* If callbacks are set, use them. This is the same implementation as in linkFilesToFile(), see the comment there for details. */ if(_inputFileCallback) { diff --git a/src/Magnum/ShaderTools/AbstractConverter.h b/src/Magnum/ShaderTools/AbstractConverter.h index e284a9e7d..7672bfcaa 100644 --- a/src/Magnum/ShaderTools/AbstractConverter.h +++ b/src/Magnum/ShaderTools/AbstractConverter.h @@ -38,6 +38,9 @@ #include "Magnum/ShaderTools/visibility.h" #ifdef MAGNUM_BUILD_DEPRECATED +/* For *ToData() APIs that used to return just an Array before */ +#include + #include "Magnum/ShaderTools/Stage.h" #endif @@ -269,6 +272,23 @@ enum class Format: UnsignedInt { */ MAGNUM_SHADERTOOLS_EXPORT Debug& operator<<(Debug& debug, Format value); +#ifdef MAGNUM_BUILD_DEPRECATED +namespace Implementation { + /* Could be a concrete type as it's always only char, but that would mean + I'd need to include Optional and Array here. There's a copy of this + class for Trade::AbstractSceneConverter and AbstractImageConverter as + introducing a common header containing just deprecated functionality + seems silly. */ + template struct OptionalButAlsoArray: Containers::Optional> { + /*implicit*/ OptionalButAlsoArray() = default; + /*implicit*/ OptionalButAlsoArray(Containers::Optional>&& optional): Containers::Optional>{std::move(optional)} {} + CORRADE_DEPRECATED("use Containers::Optional> instead") /*implicit*/ operator Containers::Array() && { + return *this ? Containers::Array{std::move(**this)} : nullptr; + } + }; +} +#endif + /** @brief Base for shader converter plugins @m_since_latest @@ -790,7 +810,12 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * @see @ref features(), @ref convertDataToFile(), * @ref convertFileToData(), @ref convertFileToFile() */ - Containers::Array convertDataToData(Stage stage, Containers::ArrayView data); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::OptionalButAlsoArray + #endif + convertDataToData(Stage stage, Containers::ArrayView data); /** * @brief Convert shader data to a file @@ -823,26 +848,41 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * * Available only if @ref ConverterFeature::ConvertData is supported. * On failure prints a message to @relativeref{Magnum,Error} and - * returns @cpp nullptr @ce. + * returns @ref Containers::NullOpt. * @see @ref features(), @ref convertFileToFile(), * @ref convertDataToFile(), @ref convertDataToData() */ - Containers::Array convertFileToData(Stage stage, Containers::StringView filename); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::OptionalButAlsoArray + #endif + convertFileToData(Stage stage, Containers::StringView filename); /** * @brief Link shader data together to a data * * Available only if @ref ConverterFeature::LinkData is supported. On * failure prints a message to @relativeref{Magnum,Error} and returns - * @cpp nullptr @ce. Can't be called if + * @ref Containers::NullOpt. Can't be called if * @ref ConverterFlag::PreprocessOnly is set --- in that case * @ref convertDataToData() has to be used instead. * @see @ref features() @ref linkDataToFile(), @ref linkFilesToFile() */ - Containers::Array linkDataToData(Containers::ArrayView>> data); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::OptionalButAlsoArray + #endif + linkDataToData(Containers::ArrayView>> data); /** @overload */ - Containers::Array linkDataToData(std::initializer_list>> data); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::OptionalButAlsoArray + #endif + linkDataToData(std::initializer_list>> data); /** * @brief Link shader data together to a file @@ -884,16 +924,26 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * * Available only if @ref ConverterFeature::LinkData is supported. On * failure prints a message to @relativeref{Magnum,Error} and returns - * @cpp nullptr @ce. Can't be called if + * @ref Containers::NullOpt. Can't be called if * @ref ConverterFlag::PreprocessOnly is set --- in that case * @ref convertFileToData() has to be used instead. * @see @ref features(), @ref linkFilesToFile(), @ref linkDataToFile(), * @ref linkDataToData() */ - Containers::Array linkFilesToData(Containers::ArrayView> filenames); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::OptionalButAlsoArray + #endif + linkFilesToData(Containers::ArrayView> filenames); /** @overload */ - Containers::Array linkFilesToData(std::initializer_list> filenames); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::OptionalButAlsoArray + #endif + linkFilesToData(std::initializer_list> filenames); protected: /** @@ -945,7 +995,7 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * is not supported --- instead, file is loaded though the callback and * data passed through to @ref doConvertDataToData(). */ - virtual Containers::Array doConvertFileToData(Stage stage, Containers::StringView filename); + virtual Containers::Optional> doConvertFileToData(Stage stage, Containers::StringView filename); /** * @brief Implementation for @ref linkFilesToFile() @@ -979,7 +1029,7 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * is not supported --- instead, file is loaded though the callback and * data passed through to @ref doConvertDataToData(). */ - virtual Containers::Array doLinkFilesToData(Containers::ArrayView> filenames); + virtual Containers::Optional> doLinkFilesToData(Containers::ArrayView> filenames); private: /** @@ -1090,7 +1140,7 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac /* Used by convertFileToFile(), doConvertFileToFile(), convertFileToData() and doConvertFileToData() */ - MAGNUM_SHADERTOOLS_LOCAL Containers::Array convertDataToDataUsingInputFileCallbacks(const char* prefix, const Stage stage, Containers::StringView filename); + MAGNUM_SHADERTOOLS_LOCAL Containers::Optional> convertDataToDataUsingInputFileCallbacks(const char* prefix, const Stage stage, Containers::StringView filename); /** * @brief Implementation for @ref convertDataToData() @@ -1100,11 +1150,11 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * in order to accept any type, this function gets it cast to * @cpp char @ce for more convenience. */ - virtual Containers::Array doConvertDataToData(Stage stage, Containers::ArrayView data); + virtual Containers::Optional> doConvertDataToData(Stage stage, Containers::ArrayView data); /* Used by linkFilesToFile(), doLinkFilesToFile(), linkFilesToData() and doLinkFilesToData() */ - MAGNUM_SHADERTOOLS_LOCAL Containers::Array linkDataToDataUsingInputFileCallbacks(const char* prefix, Containers::ArrayView> filenames); + MAGNUM_SHADERTOOLS_LOCAL Containers::Optional> linkDataToDataUsingInputFileCallbacks(const char* prefix, Containers::ArrayView> filenames); /** * @brief Implementation for @ref linkDataToData() @@ -1114,7 +1164,7 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac * order to accept any type, this function gets it cast to * @cpp char @ce for more convenience. */ - virtual Containers::Array doLinkDataToData(Containers::ArrayView>> data); + virtual Containers::Optional> doLinkDataToData(Containers::ArrayView>> data); ConverterFlags _flags; diff --git a/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp b/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp index 8a58c1836..775177afa 100644 --- a/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp +++ b/src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp @@ -934,7 +934,7 @@ void AbstractConverterTest::convertDataToData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView data) override { return Containers::array({data.back(), data.front()}); } } converter; @@ -996,7 +996,7 @@ void AbstractConverterTest::convertDataToDataCustomDeleter() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t){}}; } } converter; @@ -1015,7 +1015,7 @@ void AbstractConverterTest::convertDataToFileThroughData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView data) override { return Containers::array({data.back(), data.front()}); } } converter; @@ -1039,7 +1039,7 @@ void AbstractConverterTest::convertDataToFileThroughDataFailed() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { return {}; } } converter; @@ -1066,7 +1066,7 @@ void AbstractConverterTest::convertDataToFileThroughDataNotWritable() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { return Containers::Array{1}; } } converter; @@ -1152,7 +1152,7 @@ void AbstractConverterTest::convertFileToFileThroughData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView data) override { return Containers::array({data.back(), data.front()}); } } converter; @@ -1175,7 +1175,7 @@ void AbstractConverterTest::convertFileToFileThroughDataNotFound() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } @@ -1198,7 +1198,7 @@ void AbstractConverterTest::convertFileToFileThroughDataFailed() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { return {}; } } converter; @@ -1225,7 +1225,7 @@ void AbstractConverterTest::convertFileToFileThroughDataNotWritable() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { return Containers::Array{1}; } } converter; @@ -1284,7 +1284,7 @@ void AbstractConverterTest::convertFileToData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage, const Containers::StringView from) override { + Containers::Optional> doConvertFileToData(Stage, const Containers::StringView from) override { Containers::Optional> data = Utility::Path::read(from); CORRADE_VERIFY(data); return Containers::array({data->back(), data->front()}); @@ -1306,7 +1306,7 @@ void AbstractConverterTest::convertFileToDataAsData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView data) override { return Containers::array({data.back(), data.front()}); } } converter; @@ -1324,7 +1324,7 @@ void AbstractConverterTest::convertFileToDataAsDataNotFound() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } @@ -1390,7 +1390,7 @@ void AbstractConverterTest::convertFileToDataCustomDeleter() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage, const Containers::StringView) override { + Containers::Optional> doConvertFileToData(Stage, const Containers::StringView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t){}}; } } converter; @@ -1409,7 +1409,7 @@ void AbstractConverterTest::linkDataToData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -1518,7 +1518,7 @@ void AbstractConverterTest::linkDataToDataCustomDeleter() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { return Containers::Array{nullptr, 0, [](char*, std::size_t){}}; } } converter; @@ -1538,7 +1538,7 @@ void AbstractConverterTest::linkDataToFileThroughData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -1568,7 +1568,7 @@ void AbstractConverterTest::linkDataToFileThroughDataFailed() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { return {}; } } converter; @@ -1596,7 +1596,7 @@ void AbstractConverterTest::linkDataToFileThroughDataNotWritable() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { return Containers::Array{1}; } } converter; @@ -1732,7 +1732,7 @@ void AbstractConverterTest::linkFilesToFileThroughData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -1762,7 +1762,7 @@ void AbstractConverterTest::linkFilesToFileThroughDataNotFound() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } @@ -1788,7 +1788,7 @@ void AbstractConverterTest::linkFilesToFileThroughDataFailed() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { return {}; } } converter; @@ -1817,7 +1817,7 @@ void AbstractConverterTest::linkFilesToFileThroughDataNotWritable() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { return Containers::Array{1}; } } converter; @@ -1918,7 +1918,7 @@ void AbstractConverterTest::linkFilesToData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView> from) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView> from) override { CORRADE_COMPARE(from.size(), 2); Containers::Optional> first = Utility::Path::read(from[0].second); Containers::Optional> second = Utility::Path::read(from[1].second); @@ -1949,7 +1949,7 @@ void AbstractConverterTest::linkFilesToDataAsData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -1976,7 +1976,7 @@ void AbstractConverterTest::linkFilesToDataAsDataNotFound() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } @@ -2086,7 +2086,7 @@ void AbstractConverterTest::linkFilesToDataCustomDeleter() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView>) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView>) override { return Containers::Array{nullptr, 0, [](char*, std::size_t){}}; } } converter; @@ -2428,7 +2428,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToFileDirectly() { return stage == Stage::Mesh && from == "file.dat" && to == "file.out" && inputFileCallback() && inputFileCallbackUserData(); } - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { CORRADE_VERIFY(!"this should not be reached"); return {}; } @@ -2460,7 +2460,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToFileThroughBaseImpl return AbstractConverter::doConvertFileToFile(stage, from, to); } - Containers::Array doConvertDataToData(Stage stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage stage, Containers::ArrayView data) override { if(stage == Stage::Geometry && data.size() == 1 && data[0] == '\xb0') return Containers::array({'y', 'e', 'p'}); return {}; @@ -2543,7 +2543,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToFileAsData() { return {}; } - Containers::Array doConvertDataToData(Stage stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage stage, Containers::ArrayView data) override { if(stage == Stage::RayAnyHit && data.size() == 1 && data[0] == '\xb0') return Containers::array({'y', 'e', 'p'}); return {}; @@ -2620,7 +2620,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToFileAsDataNotWritab return {}; } - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { return Containers::Array{1}; } } converter; @@ -2664,13 +2664,13 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataDirectly() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage stage, Containers::StringView from) override { + Containers::Optional> doConvertFileToData(Stage stage, Containers::StringView from) override { if(stage == Stage::Compute && from == "file.dat" && inputFileCallback() && inputFileCallbackUserData()) return Containers::array({'y', 'e', 'p'}); return {}; } - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { CORRADE_VERIFY(!"this should not be reached"); return {}; } @@ -2682,7 +2682,9 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataDirectly() { return Containers::Optional>{}; }, &a); - CORRADE_COMPARE_AS(converter.convertFileToData(Stage::Compute, "file.dat"), + Containers::Optional> out = converter.convertFileToData(Stage::Compute, "file.dat"); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, Containers::arrayView({'y', 'e', 'p'}), TestSuite::Compare::Container); } @@ -2695,7 +2697,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataThroughBaseImpl void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage stage, Containers::StringView from) override { + Containers::Optional> doConvertFileToData(Stage stage, Containers::StringView from) override { convertFileToDataCalled = true; if(stage != Stage::TessellationEvaluation || from != "file.dat" || !inputFileCallback() || !inputFileCallbackUserData()) @@ -2704,7 +2706,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataThroughBaseImpl return AbstractConverter::doConvertFileToData(stage, from); } - Containers::Array doConvertDataToData(Stage stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage stage, Containers::ArrayView data) override { if(stage == Stage::TessellationEvaluation && data.size() == 1 && data[0] == '\xb0') return Containers::array({'y', 'e', 'p'}); return {}; @@ -2734,7 +2736,9 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataThroughBaseImpl return {}; }, state); - CORRADE_COMPARE_AS(converter.convertFileToData(Stage::TessellationEvaluation, "file.dat"), + Containers::Optional> out = converter.convertFileToData(Stage::TessellationEvaluation, "file.dat"); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, Containers::arrayView({'y', 'e', 'p'}), TestSuite::Compare::Container); CORRADE_VERIFY(converter.convertFileToDataCalled); @@ -2750,7 +2754,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataThroughBaseImpl void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage stage, Containers::StringView from) override { + Containers::Optional> doConvertFileToData(Stage stage, Containers::StringView from) override { convertFileToDataCalled = true; return AbstractConverter::doConvertFileToData(stage, from); } @@ -2778,12 +2782,12 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataAsData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage, Containers::StringView) override { + Containers::Optional> doConvertFileToData(Stage, Containers::StringView) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } - Containers::Array doConvertDataToData(Stage stage, Containers::ArrayView data) override { + Containers::Optional> doConvertDataToData(Stage stage, Containers::ArrayView data) override { if(stage == Stage::RayGeneration && data.size() == 1 && data[0] == '\xb0') return Containers::array({'y', 'e', 'p'}); return {}; @@ -2811,7 +2815,9 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataAsData() { return {}; }, state); - CORRADE_COMPARE_AS(converter.convertFileToData(Stage::RayGeneration, "file.dat"), + Containers::Optional> out = converter.convertFileToData(Stage::RayGeneration, "file.dat"); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, Containers::arrayView({'y', 'e', 'p'}), TestSuite::Compare::Container); CORRADE_VERIFY(state.loaded); @@ -2826,7 +2832,7 @@ void AbstractConverterTest::setInputFileCallbackConvertFileToDataAsDataFailed() void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doConvertFileToData(Stage, Containers::StringView) override { + Containers::Optional> doConvertFileToData(Stage, Containers::StringView) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } @@ -2855,7 +2861,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToFileDirectly() { return from.size() == 2 && from[0].first == Stage::Vertex && from[0].second == "another.dat" && from[1].first == Stage::Fragment && from[1].second == "file.dat" && to == "file.out" && inputFileCallback() && inputFileCallbackUserData(); } - Containers::Array doConvertDataToData(Stage, Containers::ArrayView) override { + Containers::Optional> doConvertDataToData(Stage, Containers::ArrayView) override { CORRADE_VERIFY(!"this should not be reached"); return {}; } @@ -2890,7 +2896,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToFileThroughBaseImplem return AbstractConverter::doLinkFilesToFile(from, to); } - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -2956,7 +2962,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToFileThroughBaseImplem return AbstractConverter::doLinkFilesToFile(from, to); } - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { CORRADE_VERIFY(!"this shouldn't be called"); return {}; } @@ -3015,7 +3021,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToFileAsData() { return {}; } - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -3125,7 +3131,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToFileAsDataNotWritable return {}; } - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { return Containers::Array{1}; } } converter; @@ -3178,13 +3184,13 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataDirectly() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView> from) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView> from) override { if(from.size() == 2 && from[0].first == Stage::Vertex && from[0].second == "another.dat" && from[1].first == Stage::Fragment && from[1].second == "file.dat" && inputFileCallback() && inputFileCallbackUserData()) return Containers::array({'y', 'e', 'p'}); return {}; } - Containers::Array doLinkDataToData(Containers::ArrayView>>) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>>) override { CORRADE_VERIFY(!"this should not be reached"); return {}; } @@ -3196,10 +3202,13 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataDirectly() { return Containers::Optional>{}; }, &a); - CORRADE_COMPARE_AS(converter.linkFilesToData({ - {Stage::Vertex, "another.dat"}, - {Stage::Fragment, "file.dat"} - }), Containers::arrayView({'y', 'e', 'p'}), + Containers::Optional> out = converter.linkFilesToData({ + {Stage::Vertex, "another.dat"}, + {Stage::Fragment, "file.dat"} + }); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'y', 'e', 'p'}), TestSuite::Compare::Container); } @@ -3211,7 +3220,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataThroughBaseImplem void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView> from) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView> from) override { linkFilesToDataCalled = true; if(from.size() != 2 || from[0].first != Stage::Vertex || from[0].second != "another.dat" || from[1].first != Stage::Fragment || from[1].second != "file.dat" || !inputFileCallback() || !inputFileCallbackUserData()) @@ -3220,7 +3229,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataThroughBaseImplem return AbstractConverter::doLinkFilesToData(from); } - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -3255,10 +3264,13 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataThroughBaseImplem return {}; }, state); - CORRADE_COMPARE_AS(converter.linkFilesToData({ - {Stage::Vertex, "another.dat"}, - {Stage::Fragment, "file.dat"} - }), Containers::arrayView({'V', 'S'}), + Containers::Optional> out = converter.linkFilesToData({ + {Stage::Vertex, "another.dat"}, + {Stage::Fragment, "file.dat"} + }); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'V', 'S'}), TestSuite::Compare::Container); CORRADE_VERIFY(converter.linkFilesToDataCalled); CORRADE_COMPARE(state.operations, @@ -3276,7 +3288,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataThroughBaseImplem void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView> from) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView> from) override { linkFilesToDataCalled = true; return AbstractConverter::doLinkFilesToData(from); } @@ -3330,12 +3342,12 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataAsData() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView>) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView>) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } - Containers::Array doLinkDataToData(Containers::ArrayView>> data) override { + Containers::Optional> doLinkDataToData(Containers::ArrayView>> data) override { CORRADE_COMPARE(data.size(), 2); return Containers::array({ data[0].first == Stage::Vertex ? data[0].second[0] : ' ', @@ -3368,10 +3380,13 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataAsData() { return {}; }, state); - CORRADE_COMPARE_AS(converter.linkFilesToData({ - {Stage::Vertex, "another.dat"}, - {Stage::Fragment, "file.dat"} - }), Containers::arrayView({'V', 'S'}), + Containers::Optional> out = converter.linkFilesToData({ + {Stage::Vertex, "another.dat"}, + {Stage::Fragment, "file.dat"} + }); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'V', 'S'}), TestSuite::Compare::Container); CORRADE_COMPARE(state.operations, "loaded another.dat\n" @@ -3388,7 +3403,7 @@ void AbstractConverterTest::setInputFileCallbackLinkFilesToDataAsDataFailed() { void doSetInputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {} - Containers::Array doLinkFilesToData(Containers::ArrayView>) override { + Containers::Optional> doLinkFilesToData(Containers::ArrayView>) override { CORRADE_VERIFY(!"this shouldn't be reached"); return {}; } diff --git a/src/Magnum/Trade/AbstractImageConverter.cpp b/src/Magnum/Trade/AbstractImageConverter.cpp index e67505356..1a81b90a4 100644 --- a/src/Magnum/Trade/AbstractImageConverter.cpp +++ b/src/Magnum/Trade/AbstractImageConverter.cpp @@ -65,7 +65,7 @@ using namespace Containers::Literals; Containers::StringView AbstractImageConverter::pluginInterface() { return /* [interface] */ -"cz.mosra.magnum.Trade.AbstractImageConverter/0.3.1"_s +"cz.mosra.magnum.Trade.AbstractImageConverter/0.3.2"_s /* [interface] */ ; } @@ -290,9 +290,14 @@ template class View> bool c } #endif -Containers::Array AbstractImageConverter::convertToData(const ImageView1D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const ImageView1D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::Convert1DToData, - "Trade::AbstractImageConverter::convertToData(): 1D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): 1D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -300,21 +305,32 @@ Containers::Array AbstractImageConverter::convertToData(const ImageView1D& return {}; #endif - Containers::Array out = doConvertToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(image); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::doConvertToData(const ImageView1D& image) { +Containers::Optional> AbstractImageConverter::doConvertToData(const ImageView1D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels1DToData, - "Trade::AbstractImageConverter::convertToData(): 1D image conversion advertised but not implemented", nullptr); + "Trade::AbstractImageConverter::convertToData(): 1D image conversion advertised but not implemented", {}); return doConvertToData(Containers::arrayView({image})); } -Containers::Array AbstractImageConverter::convertToData(const ImageView2D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const ImageView2D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::Convert2DToData, - "Trade::AbstractImageConverter::convertToData(): 2D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): 2D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -322,14 +338,20 @@ Containers::Array AbstractImageConverter::convertToData(const ImageView2D& return {}; #endif - Containers::Array out = doConvertToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(image); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::doConvertToData(const ImageView2D& image) { +Containers::Optional> AbstractImageConverter::doConvertToData(const ImageView2D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels2DToData, - "Trade::AbstractImageConverter::convertToData(): 2D image conversion advertised but not implemented", nullptr); + "Trade::AbstractImageConverter::convertToData(): 2D image conversion advertised but not implemented", {}); return doConvertToData(Containers::arrayView({image})); } @@ -340,9 +362,14 @@ Containers::Array AbstractImageConverter::exportToData(const ImageView2D& } #endif -Containers::Array AbstractImageConverter::convertToData(const ImageView3D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const ImageView3D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::Convert3DToData, - "Trade::AbstractImageConverter::convertToData(): 3D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): 3D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -350,21 +377,32 @@ Containers::Array AbstractImageConverter::convertToData(const ImageView3D& return {}; #endif - Containers::Array out = doConvertToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(image); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::doConvertToData(const ImageView3D& image) { +Containers::Optional> AbstractImageConverter::doConvertToData(const ImageView3D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels3DToData, - "Trade::AbstractImageConverter::convertToData(): 3D image conversion advertised but not implemented", nullptr); + "Trade::AbstractImageConverter::convertToData(): 3D image conversion advertised but not implemented", {}); return doConvertToData(Containers::arrayView({image})); } -Containers::Array AbstractImageConverter::convertToData(const CompressedImageView1D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const CompressedImageView1D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed1DToData, - "Trade::AbstractImageConverter::convertToData(): compressed 1D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): compressed 1D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -372,21 +410,32 @@ Containers::Array AbstractImageConverter::convertToData(const CompressedIm return {}; #endif - Containers::Array out = doConvertToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(image); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::doConvertToData(const CompressedImageView1D& image) { +Containers::Optional> AbstractImageConverter::doConvertToData(const CompressedImageView1D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels1DToData, - "Trade::AbstractImageConverter::convertToData(): compressed 1D image conversion advertised but not implemented", nullptr); + "Trade::AbstractImageConverter::convertToData(): compressed 1D image conversion advertised but not implemented", {}); return doConvertToData(Containers::arrayView({image})); } -Containers::Array AbstractImageConverter::convertToData(const CompressedImageView2D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const CompressedImageView2D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed2DToData, - "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -394,14 +443,20 @@ Containers::Array AbstractImageConverter::convertToData(const CompressedIm return {}; #endif - Containers::Array out = doConvertToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(image); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::doConvertToData(const CompressedImageView2D& image) { +Containers::Optional> AbstractImageConverter::doConvertToData(const CompressedImageView2D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels2DToData, - "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion advertised but not implemented", nullptr); + "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion advertised but not implemented", {}); return doConvertToData(Containers::arrayView({image})); } @@ -412,9 +467,14 @@ Containers::Array AbstractImageConverter::exportToData(const CompressedIma } #endif -Containers::Array AbstractImageConverter::convertToData(const CompressedImageView3D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const CompressedImageView3D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed3DToData, - "Trade::AbstractImageConverter::convertToData(): compressed 3D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): compressed 3D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -422,23 +482,39 @@ Containers::Array AbstractImageConverter::convertToData(const CompressedIm return {}; #endif - Containers::Array out = doConvertToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(image); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::doConvertToData(const CompressedImageView3D& image) { +Containers::Optional> AbstractImageConverter::doConvertToData(const CompressedImageView3D& image) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels3DToData, - "Trade::AbstractImageConverter::convertToData(): compressed 3D image conversion advertised but not implemented", nullptr); + "Trade::AbstractImageConverter::convertToData(): compressed 3D image conversion advertised but not implemented", {}); return doConvertToData(Containers::arrayView({image})); } -Containers::Array AbstractImageConverter::convertToData(const ImageData1D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const ImageData1D& image) { return image.isCompressed() ? convertToData(CompressedImageView1D(image)) : convertToData(ImageView1D(image)); } -Containers::Array AbstractImageConverter::convertToData(const ImageData2D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const ImageData2D& image) { return image.isCompressed() ? convertToData(CompressedImageView2D(image)) : convertToData(ImageView2D(image)); } @@ -448,7 +524,12 @@ Containers::Array AbstractImageConverter::exportToData(const ImageData2D& } #endif -Containers::Array AbstractImageConverter::convertToData(const ImageData3D& image) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const ImageData3D& image) { return image.isCompressed() ? convertToData(CompressedImageView3D(image)) : convertToData(ImageView3D(image)); } @@ -501,9 +582,14 @@ template bool checkImageValidity(const char* const messa } #endif -Containers::Array AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels1DToData, - "Trade::AbstractImageConverter::convertToData(): multi-level 1D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): multi-level 1D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -511,22 +597,38 @@ Containers::Array AbstractImageConverter::convertToData(const Containers:: return {}; #endif - Containers::Array out = doConvertToData(imageLevels); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(imageLevels); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { return convertToData(Containers::arrayView(imageLevels)); } -Containers::Array AbstractImageConverter::doConvertToData(Containers::ArrayView) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level 1D image conversion advertised but not implemented", nullptr); +Containers::Optional> AbstractImageConverter::doConvertToData(Containers::ArrayView) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level 1D image conversion advertised but not implemented", {}); } -Containers::Array AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels2DToData, - "Trade::AbstractImageConverter::convertToData(): multi-level 2D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): multi-level 2D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -534,22 +636,38 @@ Containers::Array AbstractImageConverter::convertToData(const Containers:: return {}; #endif - Containers::Array out = doConvertToData(imageLevels); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(imageLevels); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { return convertToData(Containers::arrayView(imageLevels)); } -Containers::Array AbstractImageConverter::doConvertToData(Containers::ArrayView) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level 2D image conversion advertised but not implemented", nullptr); +Containers::Optional> AbstractImageConverter::doConvertToData(Containers::ArrayView) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level 2D image conversion advertised but not implemented", {}); } -Containers::Array AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels3DToData, - "Trade::AbstractImageConverter::convertToData(): multi-level 3D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): multi-level 3D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -557,22 +675,38 @@ Containers::Array AbstractImageConverter::convertToData(const Containers:: return {}; #endif - Containers::Array out = doConvertToData(imageLevels); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(imageLevels); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { return convertToData(Containers::arrayView(imageLevels)); } -Containers::Array AbstractImageConverter::doConvertToData(Containers::ArrayView) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level 3D image conversion advertised but not implemented", nullptr); +Containers::Optional> AbstractImageConverter::doConvertToData(Containers::ArrayView) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level 3D image conversion advertised but not implemented", {}); } -Containers::Array AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels1DToData, - "Trade::AbstractImageConverter::convertToData(): multi-level compressed 1D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): multi-level compressed 1D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -580,22 +714,38 @@ Containers::Array AbstractImageConverter::convertToData(const Containers:: return {}; #endif - Containers::Array out = doConvertToData(imageLevels); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(imageLevels); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { return convertToData(Containers::arrayView(imageLevels)); } -Containers::Array AbstractImageConverter::doConvertToData(Containers::ArrayView) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level compressed 1D image conversion advertised but not implemented", nullptr); +Containers::Optional> AbstractImageConverter::doConvertToData(Containers::ArrayView) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level compressed 1D image conversion advertised but not implemented", {}); } -Containers::Array AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels2DToData, - "Trade::AbstractImageConverter::convertToData(): multi-level compressed 2D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): multi-level compressed 2D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -603,22 +753,38 @@ Containers::Array AbstractImageConverter::convertToData(const Containers:: return {}; #endif - Containers::Array out = doConvertToData(imageLevels); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(imageLevels); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { return convertToData(Containers::arrayView(imageLevels)); } -Containers::Array AbstractImageConverter::doConvertToData(Containers::ArrayView) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level compressed 2D image conversion advertised but not implemented", nullptr); +Containers::Optional> AbstractImageConverter::doConvertToData(Containers::ArrayView) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level compressed 2D image conversion advertised but not implemented", {}); } -Containers::Array AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const Containers::ArrayView imageLevels) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels3DToData, - "Trade::AbstractImageConverter::convertToData(): multi-level compressed 3D image conversion not supported", nullptr); + "Trade::AbstractImageConverter::convertToData(): multi-level compressed 3D image conversion not supported", {}); #ifndef CORRADE_NO_ASSERT /* Explicitly return if checks fail for CORRADE_GRACEFUL_ASSERT builds */ @@ -626,17 +792,28 @@ Containers::Array AbstractImageConverter::convertToData(const Containers:: return {}; #endif - Containers::Array out = doConvertToData(imageLevels); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional> out = doConvertToData(imageLevels); + CORRADE_ASSERT(!out || !out->deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::ImageConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::ImageConverterOptionalButAlsoArray +#endif +AbstractImageConverter::convertToData(const std::initializer_list imageLevels) { return convertToData(Containers::arrayView(imageLevels)); } -Containers::Array AbstractImageConverter::doConvertToData(Containers::ArrayView) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level compressed 3D image conversion advertised but not implemented", nullptr); +Containers::Optional> AbstractImageConverter::doConvertToData(Containers::ArrayView) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): multi-level compressed 3D image conversion advertised but not implemented", {}); } bool AbstractImageConverter::convertToFile(const ImageView1D& image, const Containers::StringView filename) { @@ -661,11 +838,11 @@ bool AbstractImageConverter::doConvertToFile(const ImageView1D& image, const Con CORRADE_ASSERT(features() >= ImageConverterFeature::Convert1DToData, "Trade::AbstractImageConverter::convertToFile(): 1D image conversion advertised but not implemented", false); - const auto data = doConvertToData(image); + const Containers::Optional> data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -695,11 +872,11 @@ bool AbstractImageConverter::doConvertToFile(const ImageView2D& image, const Con CORRADE_ASSERT(features() >= ImageConverterFeature::Convert2DToData, "Trade::AbstractImageConverter::convertToFile(): 2D image conversion advertised but not implemented", false); - const auto data = doConvertToData(image); + const Containers::Optional> data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -735,11 +912,11 @@ bool AbstractImageConverter::doConvertToFile(const ImageView3D& image, const Con CORRADE_ASSERT(features() >= ImageConverterFeature::Convert3DToData, "Trade::AbstractImageConverter::convertToFile(): 3D image conversion advertised but not implemented", false); - const auto data = doConvertToData(image); + const Containers::Optional> data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -769,11 +946,11 @@ bool AbstractImageConverter::doConvertToFile(const CompressedImageView1D& image, CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed1DToData, "Trade::AbstractImageConverter::convertToFile(): compressed 1D image conversion advertised but not implemented", false); - const auto data = doConvertToData(image); + const Containers::Optional> data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -803,11 +980,11 @@ bool AbstractImageConverter::doConvertToFile(const CompressedImageView2D& image, CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed2DToData, "Trade::AbstractImageConverter::convertToFile(): compressed 2D image conversion advertised but not implemented", false); - const auto data = doConvertToData(image); + const Containers::Optional> data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -843,11 +1020,11 @@ bool AbstractImageConverter::doConvertToFile(const CompressedImageView3D& image, CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed3DToData, "Trade::AbstractImageConverter::convertToFile(): compressed 3D image conversion advertised but not implemented", false); - const auto data = doConvertToData(image); + const Containers::Optional> data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -893,11 +1070,11 @@ bool AbstractImageConverter::convertToFile(const std::initializer_list imageLevels, const Containers::StringView filename) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels1DToData, "Trade::AbstractImageConverter::convertToFile(): multi-level 1D image conversion advertised but not implemented", false); - const auto data = doConvertToData(imageLevels); + const Containers::Optional> data = doConvertToData(imageLevels); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -925,11 +1102,11 @@ bool AbstractImageConverter::convertToFile(const std::initializer_list imageLevels, const Containers::StringView filename) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels2DToData, "Trade::AbstractImageConverter::convertToFile(): multi-level 2D image conversion advertised but not implemented", false); - const auto data = doConvertToData(imageLevels); + const Containers::Optional> data = doConvertToData(imageLevels); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -957,11 +1134,11 @@ bool AbstractImageConverter::convertToFile(const std::initializer_list imageLevels, const Containers::StringView filename) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertLevels3DToData, "Trade::AbstractImageConverter::convertToFile(): multi-level 3D image conversion advertised but not implemented", false); - const auto data = doConvertToData(imageLevels); + const Containers::Optional> data = doConvertToData(imageLevels); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -989,11 +1166,11 @@ bool AbstractImageConverter::convertToFile(const std::initializer_list imageLevels, Containers::StringView filename) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels1DToData, "Trade::AbstractImageConverter::convertToFile(): multi-level compressed 1D image conversion advertised but not implemented", false); - const auto data = doConvertToData(imageLevels); + const Containers::Optional> data = doConvertToData(imageLevels); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -1021,11 +1198,11 @@ bool AbstractImageConverter::convertToFile(const std::initializer_list imageLevels, Containers::StringView filename) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels2DToData, "Trade::AbstractImageConverter::convertToFile(): multi-level compressed 2D image conversion advertised but not implemented", false); - const auto data = doConvertToData(imageLevels); + const Containers::Optional> data = doConvertToData(imageLevels); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } @@ -1053,11 +1230,11 @@ bool AbstractImageConverter::convertToFile(const std::initializer_list imageLevels, Containers::StringView filename) { CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedLevels3DToData, "Trade::AbstractImageConverter::convertToFile(): multi-level compressed 3D image conversion advertised but not implemented", false); - const auto data = doConvertToData(imageLevels); + const Containers::Optional> data = doConvertToData(imageLevels); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } diff --git a/src/Magnum/Trade/AbstractImageConverter.h b/src/Magnum/Trade/AbstractImageConverter.h index 8066b08fa..ef0b85d5a 100644 --- a/src/Magnum/Trade/AbstractImageConverter.h +++ b/src/Magnum/Trade/AbstractImageConverter.h @@ -36,6 +36,9 @@ #include "Magnum/Trade/visibility.h" #ifdef MAGNUM_BUILD_DEPRECATED +/* For *ToData() APIs that used to return just an Array before */ +#include + /* So deprecated APIs taking a std::string don't fail to compile */ /** @todo remove once they are gone */ #include @@ -405,6 +408,23 @@ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFlag value); */ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFlags value); +#ifdef MAGNUM_BUILD_DEPRECATED +namespace Implementation { + /* Could be a concrete type as it's always only char, but that would mean + I'd need to include Optional and Array here. It's named like this + because AbstractSceneConverter and ShaderTools::AbstractConverter each + have its own and introducing a common header containing just deprecated + functionality seems silly. */ + template struct ImageConverterOptionalButAlsoArray: Containers::Optional> { + /*implicit*/ ImageConverterOptionalButAlsoArray() = default; + /*implicit*/ ImageConverterOptionalButAlsoArray(Containers::Optional>&& optional): Containers::Optional>{std::move(optional)} {} + CORRADE_DEPRECATED("use Containers::Optional> instead") /*implicit*/ operator Containers::Array() && { + return *this ? Containers::Array{std::move(**this)} : nullptr; + } + }; +} +#endif + /** @brief Base for image converter plugins @@ -864,12 +884,17 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * @ref ImageConverterFeature::ConvertLevels1DToData is supported. The * image view is expected to not be @cpp nullptr @ce and to have a * non-zero size. On failure prints a message to - * @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(const CompressedImageView1D&), * @ref convertToData(const ImageData1D&), @ref convert(), * @ref convertToFile() */ - Containers::Array convertToData(const ImageView1D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const ImageView1D& image); /** * @brief Convert a 2D image to a raw data @@ -879,12 +904,17 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * @ref ImageConverterFeature::ConvertLevels2DToData is supported. The * image view is expected to not be @cpp nullptr @ce and to have a * non-zero size in all dimensions. On failure prints a message to - * @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(const CompressedImageView2D&), * @ref convertToData(const ImageData2D&), @ref convert(), * @ref convertToFile() */ - Containers::Array convertToData(const ImageView2D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const ImageView2D& image); #ifdef MAGNUM_BUILD_DEPRECATED /** @@ -903,12 +933,17 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * @ref ImageConverterFeature::ConvertLevels3DToData is supported. The * image view is expected to not be @cpp nullptr @ce and to have a * non-zero size in all dimensions. On failure prints a message to - * @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(const CompressedImageView3D&), * @ref convertToData(const ImageData3D&), @ref convert(), * @ref convertToFile() */ - Containers::Array convertToData(const ImageView3D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const ImageView3D& image); /** * @brief Convert a compressed 1D image to a raw data @@ -918,12 +953,17 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * or @ref ImageConverterFeature::ConvertCompressedLevels1DToData is * supported. The image view is expected to not be @cpp nullptr @ce and * to have a non-zero size. On failure prints a message to - * @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(const ImageView1D&), * @ref convertToData(const ImageData1D&), @ref convert(), * @ref convertToFile() */ - Containers::Array convertToData(const CompressedImageView1D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const CompressedImageView1D& image); /** * @brief Convert a compressed 2D image to a raw data @@ -933,12 +973,18 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * or @ref ImageConverterFeature::ConvertCompressedLevels2DToData is * supported. The image view is expected to not be @cpp nullptr @ce and * to have a non-zero size in all dimensions. On failure prints a - * message to @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * message to @relativeref{Magnum,Error} and returns + * @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(const ImageView2D&), * @ref convertToData(const ImageData2D&), @ref convert(), * @ref convertToFile() */ - Containers::Array convertToData(const CompressedImageView2D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const CompressedImageView2D& image); #ifdef MAGNUM_BUILD_DEPRECATED /** @@ -957,12 +1003,18 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * or @ref ImageConverterFeature::ConvertCompressedLevels3DToData is * supported. The image view is expected to not be @cpp nullptr @ce and * to have a non-zero size in all dimensions. On failure prints a - * message to @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * message to @relativeref{Magnum,Error} and returns + * @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(const ImageView3D&), * @ref convertToData(const ImageData3D&), @ref convert(), * @ref convertToFile() */ - Containers::Array convertToData(const CompressedImageView3D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const CompressedImageView3D& image); /** * @brief Convert a 1D image data to a raw data @@ -974,7 +1026,12 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * of these two functions for details. * @see @ref ImageData::isCompressed() */ - Containers::Array convertToData(const ImageData1D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const ImageData1D& image); /** * @brief Convert a 2D image data to a raw data @@ -986,7 +1043,12 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * of these two functions for details. * @see @ref ImageData::isCompressed() */ - Containers::Array convertToData(const ImageData2D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const ImageData2D& image); #ifdef MAGNUM_BUILD_DEPRECATED /** @@ -1007,7 +1069,12 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * of these two functions for details. * @see @ref ImageData::isCompressed() */ - Containers::Array convertToData(const ImageData3D& image); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(const ImageData3D& image); /** * @brief Convert a set of 1D image levels to a raw data @@ -1020,13 +1087,23 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * that certain converters may impose additional size and order * restrictions on the images, see documentation of a particular plugin * for more information. On failure prints a message to - * @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(Containers::ArrayView), * @ref convert(), @ref convertToFile() */ - Containers::Array convertToData(Containers::ArrayView imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(Containers::ArrayView imageLevels); /** @overload */ - Containers::Array convertToData(std::initializer_list imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(std::initializer_list imageLevels); /** * @brief Convert a set of 2D image levels to a raw data @@ -1039,13 +1116,23 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * pixel format. Note that certain converters may impose additional * size and order restrictions on the images, see documentation of a * particular plugin for more information. On failure prints a message - * to @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * to @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(Containers::ArrayView), * @ref convert(), @ref convertToFile() */ - Containers::Array convertToData(Containers::ArrayView imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(Containers::ArrayView imageLevels); /** @overload */ - Containers::Array convertToData(std::initializer_list imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(std::initializer_list imageLevels); /** * @brief Convert a set of 3D image levels to a raw data @@ -1058,13 +1145,23 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * pixel format. Note that certain converters may impose additional * size and order restrictions on the images, see documentation of a * particular plugin for more information. On failure prints a message - * to @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * to @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(Containers::ArrayView), * @ref convert(), @ref convertToFile() */ - Containers::Array convertToData(Containers::ArrayView imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(Containers::ArrayView imageLevels); /** @overload */ - Containers::Array convertToData(std::initializer_list imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(std::initializer_list imageLevels); /** * @brief Convert a set of compressed 1D image levels to a raw data @@ -1077,13 +1174,23 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * that certain converters may impose additional size and order * restrictions on the images, see documentation of a particular plugin * for more information. On failure prints a message to - * @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(Containers::ArrayView), * @ref convert(), @ref convertToFile() */ - Containers::Array convertToData(Containers::ArrayView imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(Containers::ArrayView imageLevels); /** @overload */ - Containers::Array convertToData(std::initializer_list imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(std::initializer_list imageLevels); /** * @brief Convert a set of compressed 2D image levels to a raw data @@ -1096,13 +1203,23 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * pixel format. Note that certain converters may impose additional * size and order restrictions on the images, see documentation of a * particular plugin for more information. On failure prints a message - * to @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * to @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(Containers::ArrayView), * @ref convert(), @ref convertToFile() */ - Containers::Array convertToData(Containers::ArrayView imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(Containers::ArrayView imageLevels); /** @overload */ - Containers::Array convertToData(std::initializer_list imageLevels); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(std::initializer_list imageLevels); /** * @brief Convert a set of compressed 3D image levels to a raw data @@ -1115,13 +1232,23 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * pixel format. Note that certain converters may impose additional * size and order restrictions on the images, see documentation of a * particular plugin for more information. On failure prints a message - * to @relativeref{Magnum,Error} and returns @cpp nullptr @ce. + * to @relativeref{Magnum,Error} and returns @ref Containers::NullOpt. * @see @ref features(), @ref convertToData(Containers::ArrayView), * @ref convert(), @ref convertToFile() */ - Containers::Array convertToData(Containers::ArrayView images); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(Containers::ArrayView images); /** @overload */ - Containers::Array convertToData(std::initializer_list images); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::ImageConverterOptionalButAlsoArray + #endif + convertToData(std::initializer_list images); /** * @brief Convert a 1D image to a file @@ -1648,7 +1775,7 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * default implementation calls @ref doConvertToData(Containers::ArrayView) * with just the single @p image and propagates the result back. */ - virtual Containers::Array doConvertToData(const ImageView1D& image); + virtual Containers::Optional> doConvertToData(const ImageView1D& image); /** * @brief Implementation for @ref convertToData(const ImageView2D&) @@ -1658,7 +1785,7 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * default implementation calls @ref doConvertToData(Containers::ArrayView) * with just the single @p image and propagates the result back. */ - virtual Containers::Array doConvertToData(const ImageView2D& image); + virtual Containers::Optional> doConvertToData(const ImageView2D& image); /** * @brief Implementation for @ref convertToData(const ImageView3D&) @@ -1668,7 +1795,7 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * default implementation calls @ref doConvertToData(Containers::ArrayView) * with just the single @p image and propagates the result back. */ - virtual Containers::Array doConvertToData(const ImageView3D& image); + virtual Containers::Optional> doConvertToData(const ImageView3D& image); /** * @brief Implementation for @ref convertToData(const CompressedImageView1D&) @@ -1679,7 +1806,7 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * @ref doConvertToData(Containers::ArrayView) * with just the single @p image and propagates the result back. */ - virtual Containers::Array doConvertToData(const CompressedImageView1D& image); + virtual Containers::Optional> doConvertToData(const CompressedImageView1D& image); /** * @brief Implementation for @ref convertToData(const CompressedImageView2D&) @@ -1690,7 +1817,7 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * @ref doConvertToData(Containers::ArrayView) * with just the single @p image and propagates the result back. */ - virtual Containers::Array doConvertToData(const CompressedImageView2D& image); + virtual Containers::Optional> doConvertToData(const CompressedImageView2D& image); /** * @brief Implementation for @ref convertToData(const CompressedImageView3D&) @@ -1701,43 +1828,43 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract * @ref doConvertToData(Containers::ArrayView) * with just the single @p image and propagates the result back. */ - virtual Containers::Array doConvertToData(const CompressedImageView3D& image); + virtual Containers::Optional> doConvertToData(const CompressedImageView3D& image); /** * @brief Implementation for @ref convertToData(Containers::ArrayView) * @m_since_latest */ - virtual Containers::Array doConvertToData(Containers::ArrayView imageLevels); + virtual Containers::Optional> doConvertToData(Containers::ArrayView imageLevels); /** * @brief Implementation for @ref convertToData(Containers::ArrayView) * @m_since_latest */ - virtual Containers::Array doConvertToData(Containers::ArrayView imageLevels); + virtual Containers::Optional> doConvertToData(Containers::ArrayView imageLevels); /** * @brief Implementation for @ref convertToData(Containers::ArrayView) * @m_since_latest */ - virtual Containers::Array doConvertToData(Containers::ArrayView imageLevels); + virtual Containers::Optional> doConvertToData(Containers::ArrayView imageLevels); /** * @brief Implementation for @ref convertToData(Containers::ArrayView) * @m_since_latest */ - virtual Containers::Array doConvertToData(Containers::ArrayView imageLevels); + virtual Containers::Optional> doConvertToData(Containers::ArrayView imageLevels); /** * @brief Implementation for @ref convertToData(Containers::ArrayView) * @m_since_latest */ - virtual Containers::Array doConvertToData(Containers::ArrayView imageLevels); + virtual Containers::Optional> doConvertToData(Containers::ArrayView imageLevels); /** * @brief Implementation for @ref convertToData(Containers::ArrayView) * @m_since_latest */ - virtual Containers::Array doConvertToData(Containers::ArrayView imageLevels); + virtual Containers::Optional> doConvertToData(Containers::ArrayView imageLevels); ImageConverterFlags _flags; }; diff --git a/src/Magnum/Trade/AbstractSceneConverter.cpp b/src/Magnum/Trade/AbstractSceneConverter.cpp index a0664eb7e..71ba441ef 100644 --- a/src/Magnum/Trade/AbstractSceneConverter.cpp +++ b/src/Magnum/Trade/AbstractSceneConverter.cpp @@ -65,7 +65,7 @@ using namespace Containers::Literals; Containers::StringView AbstractSceneConverter::pluginInterface() { return /* [interface] */ -"cz.mosra.magnum.Trade.AbstractSceneConverter/0.1.1"_s +"cz.mosra.magnum.Trade.AbstractSceneConverter/0.1.2"_s /* [interface] */ ; } @@ -148,17 +148,28 @@ bool AbstractSceneConverter::doConvertInPlace(MeshData&) { CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::convertInPlace(): mesh conversion advertised but not implemented", {}); } -Containers::Array AbstractSceneConverter::convertToData(const MeshData& mesh) { +#ifndef MAGNUM_BUILD_DEPRECATED +Containers::Optional> +#else +Implementation::SceneConverterOptionalButAlsoArray +#endif +AbstractSceneConverter::convertToData(const MeshData& mesh) { CORRADE_ASSERT(features() & SceneConverterFeature::ConvertMeshToData, "Trade::AbstractSceneConverter::convertToData(): mesh conversion not supported", {}); - Containers::Array out = doConvertToData(mesh); - CORRADE_ASSERT(!out || !out.deleter() || out.deleter() == static_cast(Implementation::nonOwnedArrayDeleter) || out.deleter() == ArrayAllocator::deleter, + Containers::Optional> out = doConvertToData(mesh); + CORRADE_ASSERT(!out || !out->deleter() || out->deleter() == static_cast(Implementation::nonOwnedArrayDeleter) || out->deleter() == ArrayAllocator::deleter, "Trade::AbstractSceneConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); + + /* GCC 4.8 and Clang 3.8 need an explicit conversion here */ + #ifdef MAGNUM_BUILD_DEPRECATED + return Implementation::SceneConverterOptionalButAlsoArray{std::move(out)}; + #else return out; + #endif } -Containers::Array AbstractSceneConverter::doConvertToData(const MeshData&) { +Containers::Optional> AbstractSceneConverter::doConvertToData(const MeshData&) { CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::convertToData(): mesh conversion advertised but not implemented", {}); } @@ -178,11 +189,11 @@ bool AbstractSceneConverter::convertToFile(const std::string& filename, const Me bool AbstractSceneConverter::doConvertToFile(const MeshData& mesh, const Containers::StringView filename) { CORRADE_ASSERT(features() >= SceneConverterFeature::ConvertMeshToData, "Trade::AbstractSceneConverter::convertToFile(): mesh conversion advertised but not implemented", false); - const auto data = doConvertToData(mesh); + const Containers::Optional> data = doConvertToData(mesh); /* No deleter checks as it doesn't matter here */ if(!data) return false; - if(!Utility::Path::write(filename, data)) { + if(!Utility::Path::write(filename, *data)) { Error() << "Trade::AbstractSceneConverter::convertToFile(): cannot write to file" << filename; return false; } diff --git a/src/Magnum/Trade/AbstractSceneConverter.h b/src/Magnum/Trade/AbstractSceneConverter.h index cb3f46d97..fc97d946d 100644 --- a/src/Magnum/Trade/AbstractSceneConverter.h +++ b/src/Magnum/Trade/AbstractSceneConverter.h @@ -37,6 +37,9 @@ #include "Magnum/Trade/visibility.h" #ifdef MAGNUM_BUILD_DEPRECATED +/* For *ToData() APIs that used to return just an Array before */ +#include + /* So deprecated APIs taking a std::string don't fail to compile */ /** @todo remove once they are gone */ #include @@ -135,6 +138,23 @@ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, SceneConverterFlag value); */ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, SceneConverterFlags value); +#ifdef MAGNUM_BUILD_DEPRECATED +namespace Implementation { + /* Could be a concrete type as it's always only char, but that would mean + I'd need to include Optional and Array here. It's named like this + because AbstractImageConverter and ShaderTools::AbstractConverter each + have its own and introducing a common header containing just deprecated + functionality seems silly. */ + template struct SceneConverterOptionalButAlsoArray: Containers::Optional> { + /*implicit*/ SceneConverterOptionalButAlsoArray() = default; + /*implicit*/ SceneConverterOptionalButAlsoArray(Containers::Optional>&& optional): Containers::Optional>{std::move(optional)} {} + CORRADE_DEPRECATED("use Containers::Optional> instead") /*implicit*/ operator Containers::Array() && { + return *this ? Containers::Array{std::move(**this)} : nullptr; + } + }; +} +#endif + /** @brief Base for scene converter plugins @m_since{2020,06} @@ -380,10 +400,15 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * can be saved to disk. Available only if * @ref SceneConverterFeature::ConvertMeshToData is supported. On * failure prints a message to @relativeref{Magnum,Error} and returns - * @cpp nullptr @ce. + * @ref Containers::NullOpt. * @see @ref features(), @ref convertToFile() */ - Containers::Array convertToData(const MeshData& mesh); + #if !defined(MAGNUM_BUILD_DEPRECATED) || defined(DOXYGEN_GENERATING_OUTPUT) + Containers::Optional> + #else + Implementation::SceneConverterOptionalButAlsoArray + #endif + convertToData(const MeshData& mesh); /** * @brief Convert a mesh to a file @@ -449,7 +474,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract virtual bool doConvertInPlace(MeshData& mesh); /** @brief Implementation for @ref convertToData(const MeshData&) */ - virtual Containers::Array doConvertToData(const MeshData& mesh); + virtual Containers::Optional> doConvertToData(const MeshData& mesh); SceneConverterFlags _flags; }; diff --git a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp index 7908add4e..2c76f0b8d 100644 --- a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp @@ -987,7 +987,7 @@ void AbstractImageConverterTest::convertImageData3D() { void AbstractImageConverterTest::convert1DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } - Containers::Array doConvertToData(const ImageView1D& image) override { + Containers::Optional> doConvertToData(const ImageView1D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; @@ -1000,7 +1000,7 @@ void AbstractImageConverterTest::convert1DToData() { void AbstractImageConverterTest::convert2DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doConvertToData(const ImageView2D& image) override { + Containers::Optional> doConvertToData(const ImageView2D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; @@ -1013,7 +1013,7 @@ void AbstractImageConverterTest::convert2DToData() { void AbstractImageConverterTest::convert3DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData; } - Containers::Array doConvertToData(const ImageView3D& image) override { + Containers::Optional> doConvertToData(const ImageView3D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; @@ -1139,7 +1139,7 @@ void AbstractImageConverterTest::convert1DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } - Containers::Array doConvertToData(const ImageView1D&) override { + Containers::Optional> doConvertToData(const ImageView1D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1158,7 +1158,7 @@ void AbstractImageConverterTest::convert2DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doConvertToData(const ImageView2D&) override { + Containers::Optional> doConvertToData(const ImageView2D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1177,7 +1177,7 @@ void AbstractImageConverterTest::convert3DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData; } - Containers::Array doConvertToData(const ImageView3D&) override { + Containers::Optional> doConvertToData(const ImageView3D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1192,7 +1192,7 @@ void AbstractImageConverterTest::convert3DToDataCustomDeleter() { void AbstractImageConverterTest::convertCompressed1DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed1DToData; } - Containers::Array doConvertToData(const CompressedImageView1D& image) override { + Containers::Optional> doConvertToData(const CompressedImageView1D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; @@ -1205,7 +1205,7 @@ void AbstractImageConverterTest::convertCompressed1DToData() { void AbstractImageConverterTest::convertCompressed2DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doConvertToData(const CompressedImageView2D& image) override { + Containers::Optional> doConvertToData(const CompressedImageView2D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; @@ -1218,7 +1218,7 @@ void AbstractImageConverterTest::convertCompressed2DToData() { void AbstractImageConverterTest::convertCompressed3DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed3DToData; } - Containers::Array doConvertToData(const CompressedImageView3D& image) override { + Containers::Optional> doConvertToData(const CompressedImageView3D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; @@ -1328,7 +1328,7 @@ void AbstractImageConverterTest::convertCompressed1DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed1DToData; } - Containers::Array doConvertToData(const CompressedImageView1D&) override { + Containers::Optional> doConvertToData(const CompressedImageView1D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1347,7 +1347,7 @@ void AbstractImageConverterTest::convertCompressed2DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doConvertToData(const CompressedImageView2D&) override { + Containers::Optional> doConvertToData(const CompressedImageView2D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1366,7 +1366,7 @@ void AbstractImageConverterTest::convertCompressed3DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed3DToData; } - Containers::Array doConvertToData(const CompressedImageView3D&) override { + Containers::Optional> doConvertToData(const CompressedImageView3D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1383,11 +1383,11 @@ class ImageData1DConverter: public Trade::AbstractImageConverter { private: ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData|ImageConverterFeature::ConvertCompressed1DToData; } - Containers::Array doConvertToData(const ImageView1D&) override { + Containers::Optional> doConvertToData(const ImageView1D&) override { return Containers::array({'B'}); }; - Containers::Array doConvertToData(const CompressedImageView1D&) override { + Containers::Optional> doConvertToData(const CompressedImageView1D&) override { return Containers::array({'C'}); }; }; @@ -1395,11 +1395,11 @@ class ImageData2DConverter: public Trade::AbstractImageConverter { private: ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData|ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doConvertToData(const ImageView2D&) override { + Containers::Optional> doConvertToData(const ImageView2D&) override { return Containers::array({'B'}); }; - Containers::Array doConvertToData(const CompressedImageView2D&) override { + Containers::Optional> doConvertToData(const CompressedImageView2D&) override { return Containers::array({'C'}); }; }; @@ -1407,11 +1407,11 @@ class ImageData3DConverter: public Trade::AbstractImageConverter { private: ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData|ImageConverterFeature::ConvertCompressed3DToData; } - Containers::Array doConvertToData(const ImageView3D&) override { + Containers::Optional> doConvertToData(const ImageView3D&) override { return Containers::array({'B'}); }; - Containers::Array doConvertToData(const CompressedImageView3D&) override { + Containers::Optional> doConvertToData(const CompressedImageView3D&) override { return Containers::array({'C'}); }; }; @@ -1420,48 +1420,72 @@ void AbstractImageConverterTest::convertImageData1DToData() { ImageData1DConverter converter; /* Should get "B" when converting uncompressed */ - CORRADE_COMPARE_AS(converter.convertToData(ImageData1D{PixelFormat::RGBA8Unorm, 1, Containers::Array{4}}), - Containers::arrayView({'B'}), - TestSuite::Compare::Container); + { + Containers::Optional> out = converter.convertToData(ImageData1D{PixelFormat::RGBA8Unorm, 1, Containers::Array{4}}); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'B'}), + TestSuite::Compare::Container); + } /* Should get "C" when converting compressed */ - CORRADE_COMPARE_AS(converter.convertToData(ImageData1D{CompressedPixelFormat::Bc1RGBUnorm, 4, Containers::Array{8}}), - Containers::arrayView({'C'}), - TestSuite::Compare::Container); + { + Containers::Optional> out = converter.convertToData(ImageData1D{CompressedPixelFormat::Bc1RGBUnorm, 4, Containers::Array{8}}); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'C'}), + TestSuite::Compare::Container); + } } void AbstractImageConverterTest::convertImageData2DToData() { ImageData2DConverter converter; /* Should get "B" when converting uncompressed */ - CORRADE_COMPARE_AS(converter.convertToData(ImageData2D{PixelFormat::RGBA8Unorm, {1, 1}, Containers::Array{4}}), - Containers::arrayView({'B'}), - TestSuite::Compare::Container); + { + Containers::Optional> out = converter.convertToData(ImageData2D{PixelFormat::RGBA8Unorm, {1, 1}, Containers::Array{4}}); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'B'}), + TestSuite::Compare::Container); + } /* Should get "C" when converting compressed */ - CORRADE_COMPARE_AS(converter.convertToData(ImageData2D{CompressedPixelFormat::Bc1RGBUnorm, {4, 4}, Containers::Array{4}}), - Containers::arrayView({'C'}), - TestSuite::Compare::Container); + { + Containers::Optional> out = converter.convertToData(ImageData2D{CompressedPixelFormat::Bc1RGBUnorm, {4, 4}, Containers::Array{4}}); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'C'}), + TestSuite::Compare::Container); + } } void AbstractImageConverterTest::convertImageData3DToData() { ImageData3DConverter converter; /* Should get "B" when converting uncompressed */ - CORRADE_COMPARE_AS(converter.convertToData(ImageData3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, Containers::Array{4}}), - Containers::arrayView({'B'}), - TestSuite::Compare::Container); + { + Containers::Optional> out = converter.convertToData(ImageData3D{PixelFormat::RGBA8Unorm, {1, 1, 1}, Containers::Array{4}}); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'B'}), + TestSuite::Compare::Container); + } /* Should get "C" when converting compressed */ - CORRADE_COMPARE_AS(converter.convertToData(ImageData3D{CompressedPixelFormat::Bc1RGBUnorm, {4, 4, 1}, Containers::Array{4}}), - Containers::arrayView({'C'}), - TestSuite::Compare::Container); + { + Containers::Optional> out = converter.convertToData(ImageData3D{CompressedPixelFormat::Bc1RGBUnorm, {4, 4, 1}, Containers::Array{4}}); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(*out, + Containers::arrayView({'C'}), + TestSuite::Compare::Container); + } } void AbstractImageConverterTest::convertLevels1DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -1479,7 +1503,7 @@ void AbstractImageConverterTest::convertLevels1DToData() { void AbstractImageConverterTest::convertLevels2DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -1497,7 +1521,7 @@ void AbstractImageConverterTest::convertLevels2DToData() { void AbstractImageConverterTest::convertLevels3DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -1690,7 +1714,7 @@ void AbstractImageConverterTest::convertLevels1DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1709,7 +1733,7 @@ void AbstractImageConverterTest::convertLevels2DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1728,7 +1752,7 @@ void AbstractImageConverterTest::convertLevels3DToDataCustomDeleter() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1743,7 +1767,7 @@ void AbstractImageConverterTest::convertLevels3DToDataCustomDeleter() { void AbstractImageConverterTest::convertCompressedLevels1DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -1761,7 +1785,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToData() { void AbstractImageConverterTest::convertCompressedLevels2DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -1779,7 +1803,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToData() { void AbstractImageConverterTest::convertCompressedLevels3DToData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -1952,7 +1976,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToDataCustomDeleter() struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1971,7 +1995,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToDataCustomDeleter() struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -1990,7 +2014,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToDataCustomDeleter() struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; @@ -2005,7 +2029,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToDataCustomDeleter() void AbstractImageConverterTest::convert1DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -2018,7 +2042,7 @@ void AbstractImageConverterTest::convert1DToDataThroughLevels() { void AbstractImageConverterTest::convert2DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -2031,7 +2055,7 @@ void AbstractImageConverterTest::convert2DToDataThroughLevels() { void AbstractImageConverterTest::convert3DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -2044,7 +2068,7 @@ void AbstractImageConverterTest::convert3DToDataThroughLevels() { void AbstractImageConverterTest::convertCompressed1DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -2057,7 +2081,7 @@ void AbstractImageConverterTest::convertCompressed1DToDataThroughLevels() { void AbstractImageConverterTest::convertCompressed2DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -2070,7 +2094,7 @@ void AbstractImageConverterTest::convertCompressed2DToDataThroughLevels() { void AbstractImageConverterTest::convertCompressed3DToDataThroughLevels() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::Array{nullptr, std::size_t(imageLevels[0].size().product()*imageLevels.size())}; } } converter; @@ -2141,7 +2165,7 @@ void AbstractImageConverterTest::convert1DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } - Containers::Array doConvertToData(const ImageView1D& image) override { + Containers::Optional> doConvertToData(const ImageView1D& image) override { return Containers::array({char(image.size()[0])}); }; } converter; @@ -2161,7 +2185,7 @@ void AbstractImageConverterTest::convert2DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doConvertToData(const ImageView2D& image) override { + Containers::Optional> doConvertToData(const ImageView2D& image) override { return Containers::array({char(image.size().x()), char(image.size().y())}); }; } converter; @@ -2181,7 +2205,7 @@ void AbstractImageConverterTest::convert3DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData; } - Containers::Array doConvertToData(const ImageView3D& image) override { + Containers::Optional> doConvertToData(const ImageView3D& image) override { return Containers::array({char(image.size().x()), char(image.size().y()), char(image.size().z())}); }; } converter; @@ -2201,7 +2225,7 @@ void AbstractImageConverterTest::convert1DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } - Containers::Array doConvertToData(const ImageView1D&) override { + Containers::Optional> doConvertToData(const ImageView1D&) override { return {}; }; } converter; @@ -2226,7 +2250,7 @@ void AbstractImageConverterTest::convert2DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doConvertToData(const ImageView2D&) override { + Containers::Optional> doConvertToData(const ImageView2D&) override { return {}; }; } converter; @@ -2251,7 +2275,7 @@ void AbstractImageConverterTest::convert3DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData; } - Containers::Array doConvertToData(const ImageView3D&) override { + Containers::Optional> doConvertToData(const ImageView3D&) override { return {}; }; } converter; @@ -2276,7 +2300,7 @@ void AbstractImageConverterTest::convert1DToFileThroughDataNotWritable() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert1DToData; } - Containers::Array doConvertToData(const ImageView1D&) override { + Containers::Optional> doConvertToData(const ImageView1D&) override { return Containers::array({'\x00'}); }; } converter; @@ -2294,7 +2318,7 @@ void AbstractImageConverterTest::convert2DToFileThroughDataNotWritable() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doConvertToData(const ImageView2D&) override { + Containers::Optional> doConvertToData(const ImageView2D&) override { return Containers::array({'\x00'}); }; } converter; @@ -2312,7 +2336,7 @@ void AbstractImageConverterTest::convert3DToFileThroughDataNotWritable() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert3DToData; } - Containers::Array doConvertToData(const ImageView3D&) override { + Containers::Optional> doConvertToData(const ImageView3D&) override { return Containers::array({'\x00'}); }; } converter; @@ -2480,7 +2504,7 @@ void AbstractImageConverterTest::convertCompressed1DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed1DToData; } - Containers::Array doConvertToData(const CompressedImageView1D& image) override { + Containers::Optional> doConvertToData(const CompressedImageView1D& image) override { return Containers::array({char(image.size()[0])}); }; } converter; @@ -2500,7 +2524,7 @@ void AbstractImageConverterTest::convertCompressed2DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doConvertToData(const CompressedImageView2D& image) override { + Containers::Optional> doConvertToData(const CompressedImageView2D& image) override { return Containers::array({char(image.size().x()), char(image.size().y())}); }; } converter; @@ -2520,7 +2544,7 @@ void AbstractImageConverterTest::convertCompressed3DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed3DToData; } - Containers::Array doConvertToData(const CompressedImageView3D& image) override { + Containers::Optional> doConvertToData(const CompressedImageView3D& image) override { return Containers::array({char(image.size().x()), char(image.size().y()), char(image.size().z())}); }; } converter; @@ -2540,7 +2564,7 @@ void AbstractImageConverterTest::convertCompressed1DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed1DToData; } - Containers::Array doConvertToData(const CompressedImageView1D&) override { + Containers::Optional> doConvertToData(const CompressedImageView1D&) override { return {}; }; } converter; @@ -2565,7 +2589,7 @@ void AbstractImageConverterTest::convertCompressed2DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doConvertToData(const CompressedImageView2D&) override { + Containers::Optional> doConvertToData(const CompressedImageView2D&) override { return {}; }; } converter; @@ -2590,7 +2614,7 @@ void AbstractImageConverterTest::convertCompressed3DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed3DToData; } - Containers::Array doConvertToData(const CompressedImageView3D&) override { + Containers::Optional> doConvertToData(const CompressedImageView3D&) override { return {}; }; } converter; @@ -2615,7 +2639,7 @@ void AbstractImageConverterTest::convertCompressed1DToFileThroughDataNotWritable struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed1DToData; } - Containers::Array doConvertToData(const CompressedImageView1D&) override { + Containers::Optional> doConvertToData(const CompressedImageView1D&) override { return Containers::array({'\x00'}); }; } converter; @@ -2633,7 +2657,7 @@ void AbstractImageConverterTest::convertCompressed2DToFileThroughDataNotWritable struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doConvertToData(const CompressedImageView2D&) override { + Containers::Optional> doConvertToData(const CompressedImageView2D&) override { return Containers::array({'\x00'}); }; } converter; @@ -2651,7 +2675,7 @@ void AbstractImageConverterTest::convertCompressed3DToFileThroughDataNotWritable struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed3DToData; } - Containers::Array doConvertToData(const CompressedImageView3D&) override { + Containers::Optional> doConvertToData(const CompressedImageView3D&) override { return Containers::array({'\x00'}); }; } converter; @@ -2876,7 +2900,7 @@ void AbstractImageConverterTest::convertLevels1DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::array({char(imageLevels[0].size()[0]), char(imageLevels.size())}); }; } converter; @@ -2902,7 +2926,7 @@ void AbstractImageConverterTest::convertLevels2DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::array({char(imageLevels[0].size().x()), char(imageLevels[0].size().y()), char(imageLevels.size())}); }; } converter; @@ -2927,7 +2951,7 @@ void AbstractImageConverterTest::convertLevels3DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::array({char(imageLevels[0].size().x()), char(imageLevels[0].size().y()), char(imageLevels[0].size().z()), char(imageLevels.size())}); }; } converter; @@ -2952,7 +2976,7 @@ void AbstractImageConverterTest::convertLevels1DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return {}; }; } converter; @@ -2977,7 +3001,7 @@ void AbstractImageConverterTest::convertLevels2DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return {}; }; } converter; @@ -3002,7 +3026,7 @@ void AbstractImageConverterTest::convertLevels3DToFileThroughDataFailed() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return {}; }; } converter; @@ -3026,7 +3050,7 @@ void AbstractImageConverterTest::convertLevels3DToFileThroughDataFailed() { void AbstractImageConverterTest::convertLevels1DToFileThroughDataNotWritable() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::array({'\x00'}); }; } converter; @@ -3044,7 +3068,7 @@ void AbstractImageConverterTest::convertLevels2DToFileThroughDataNotWritable() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::array({'\x00'}); }; } converter; @@ -3062,7 +3086,7 @@ void AbstractImageConverterTest::convertLevels3DToFileThroughDataNotWritable() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::array({'\x00'}); }; } converter; @@ -3242,7 +3266,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::array({char(imageLevels[0].size()[0]), char(imageLevels.size())}); }; } converter; @@ -3267,7 +3291,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::array({char(imageLevels[0].size().x()), char(imageLevels[0].size().y()), char(imageLevels.size())}); }; } converter; @@ -3292,7 +3316,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileThroughData() { struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView imageLevels) override { + Containers::Optional> doConvertToData(Containers::ArrayView imageLevels) override { return Containers::array({char(imageLevels[0].size().x()), char(imageLevels[0].size().y()), char(imageLevels[0].size().z()), char(imageLevels.size())}); }; } converter; @@ -3317,7 +3341,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileThroughDataFaile struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return {}; }; } converter; @@ -3342,7 +3366,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileThroughDataFaile struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return {}; }; } converter; @@ -3367,7 +3391,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileThroughDataFaile struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return {}; }; } converter; @@ -3392,7 +3416,7 @@ void AbstractImageConverterTest::convertCompressedLevels1DToFileThroughDataNotWr struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels1DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::array({'\x00'}); }; } converter; @@ -3410,7 +3434,7 @@ void AbstractImageConverterTest::convertCompressedLevels2DToFileThroughDataNotWr struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels2DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::array({'\x00'}); }; } converter; @@ -3428,7 +3452,7 @@ void AbstractImageConverterTest::convertCompressedLevels3DToFileThroughDataNotWr struct: AbstractImageConverter { ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedLevels3DToData; } - Containers::Array doConvertToData(Containers::ArrayView) override { + Containers::Optional> doConvertToData(Containers::ArrayView) override { return Containers::array({'\x00'}); }; } converter; diff --git a/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp b/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp index 9a03f3444..2ea782fa0 100644 --- a/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp @@ -396,7 +396,7 @@ void AbstractSceneConverterTest::convertMeshToData() { struct: AbstractSceneConverter { SceneConverterFeatures doFeatures() const override { return SceneConverterFeature::ConvertMeshToData; } - Containers::Array doConvertToData(const MeshData& mesh) override { + Containers::Optional> doConvertToData(const MeshData& mesh) override { return Containers::Array{nullptr, mesh.vertexCount()}; } } converter; @@ -428,7 +428,7 @@ void AbstractSceneConverterTest::convertMeshToDataCustomDeleter() { struct: AbstractSceneConverter { SceneConverterFeatures doFeatures() const override { return SceneConverterFeature::ConvertMeshToData; } - Containers::Array doConvertToData(const MeshData&) override { + Containers::Optional> doConvertToData(const MeshData&) override { return Containers::Array{data, 1, [](char*, std::size_t) {}}; } @@ -464,7 +464,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughData() { struct: AbstractSceneConverter { SceneConverterFeatures doFeatures() const override { return SceneConverterFeature::ConvertMeshToData; } - Containers::Array doConvertToData(const MeshData& mesh) override { + Containers::Optional> doConvertToData(const MeshData& mesh) override { return Containers::array({char(mesh.vertexCount())}); } } converter; @@ -484,7 +484,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughDataFailed() { struct: AbstractSceneConverter { SceneConverterFeatures doFeatures() const override { return SceneConverterFeature::ConvertMeshToData; } - Containers::Array doConvertToData(const MeshData&) override { + Containers::Optional> doConvertToData(const MeshData&) override { return {}; } } converter; @@ -507,7 +507,7 @@ void AbstractSceneConverterTest::convertMeshToFileThroughDataNotWritable() { struct: AbstractSceneConverter { SceneConverterFeatures doFeatures() const override { return SceneConverterFeature::ConvertMeshToData; } - Containers::Array doConvertToData(const MeshData& mesh) override { + Containers::Optional> doConvertToData(const MeshData& mesh) override { return Containers::array({char(mesh.vertexCount())}); } } converter; diff --git a/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp b/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp index 05007dc5f..cfed001a7 100644 --- a/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp +++ b/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp @@ -625,4 +625,4 @@ bool AnyImageConverter::doConvertToFile(const Containers::ArrayView +#include #include #include #include @@ -375,7 +376,7 @@ bool AnyConverter::doConvertFileToFile(const Stage stage, const Containers::Stri return converter->convertFileToFile(stage, from, to); } -Containers::Array AnyConverter::doConvertFileToData(const Stage stage, const Containers::StringView filename) { +Containers::Optional> AnyConverter::doConvertFileToData(const Stage stage, const Containers::StringView filename) { CORRADE_INTERNAL_ASSERT(manager()); /* Prefer the explicitly set input format. If not set, fall back to @@ -460,7 +461,7 @@ Containers::Array AnyConverter::doConvertFileToData(const Stage stage, con return converter->convertFileToData(stage, filename); } -Containers::Array AnyConverter::doConvertDataToData(const Stage stage, const Containers::ArrayView from) { +Containers::Optional> AnyConverter::doConvertDataToData(const Stage stage, const Containers::ArrayView from) { CORRADE_INTERNAL_ASSERT(manager()); /* Decide on a plugin name based on the format. This might result in @@ -546,4 +547,4 @@ Containers::Array AnyConverter::doConvertDataToData(const Stage stage, con }} CORRADE_PLUGIN_REGISTER(AnyShaderConverter, Magnum::ShaderTools::AnyConverter, - "cz.mosra.magnum.ShaderTools.AbstractConverter/0.1") + "cz.mosra.magnum.ShaderTools.AbstractConverter/0.1.1") diff --git a/src/MagnumPlugins/AnyShaderConverter/AnyConverter.h b/src/MagnumPlugins/AnyShaderConverter/AnyConverter.h index a2040c31c..0c3ea0160 100644 --- a/src/MagnumPlugins/AnyShaderConverter/AnyConverter.h +++ b/src/MagnumPlugins/AnyShaderConverter/AnyConverter.h @@ -162,8 +162,8 @@ class MAGNUM_ANYSHADERCONVERTER_EXPORT AnyConverter: public AbstractConverter { MAGNUM_ANYSHADERCONVERTER_LOCAL std::pair doValidateFile(Stage stage, Containers::StringView filename) override; MAGNUM_ANYSHADERCONVERTER_LOCAL std::pair doValidateData(Stage stage, Containers::ArrayView data) override; MAGNUM_ANYSHADERCONVERTER_LOCAL bool doConvertFileToFile(Stage stage, Containers::StringView from, Containers::StringView to) override; - MAGNUM_ANYSHADERCONVERTER_LOCAL Containers::Array doConvertFileToData(Magnum::ShaderTools::Stage stage, Containers::StringView filename) override; - MAGNUM_ANYSHADERCONVERTER_LOCAL Containers::Array doConvertDataToData(Magnum::ShaderTools::Stage stage, Containers::ArrayView data) override; + MAGNUM_ANYSHADERCONVERTER_LOCAL Containers::Optional> doConvertFileToData(Magnum::ShaderTools::Stage stage, Containers::StringView filename) override; + MAGNUM_ANYSHADERCONVERTER_LOCAL Containers::Optional> doConvertDataToData(Magnum::ShaderTools::Stage stage, Containers::ArrayView data) override; struct State; Containers::Pointer _state; diff --git a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp index c3a498e22..6dbfe1809 100644 --- a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp @@ -28,6 +28,7 @@ #include /* std::sort() */ #include #include +#include #include #include #include diff --git a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp index 6fba4e5f6..2dea0757e 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,7 @@ TgaImageConverter::TgaImageConverter(PluginManager::AbstractManager& manager, co ImageConverterFeatures TgaImageConverter::doFeatures() const { return ImageConverterFeature::Convert2DToData; } -Containers::Array TgaImageConverter::doConvertToData(const ImageView2D& image) { +Containers::Optional> TgaImageConverter::doConvertToData(const ImageView2D& image) { /* Initialize data buffer */ const auto pixelSize = UnsignedByte(image.pixelSize()); Containers::Array data{ValueInit, sizeof(Implementation::TgaHeader) + pixelSize*image.size().product()}; @@ -62,7 +63,7 @@ Containers::Array TgaImageConverter::doConvertToData(const ImageView2D& im break; default: Error() << "Trade::TgaImageConverter::convertToData(): unsupported pixel format" << image.format(); - return nullptr; + return {}; } header->bpp = pixelSize*8; header->width = UnsignedShort(Utility::Endianness::littleEndian(image.size().x())); @@ -85,10 +86,11 @@ Containers::Array TgaImageConverter::doConvertToData(const ImageView2D& im pixel = Math::gather<'b', 'g', 'r', 'a'>(pixel); } - return data; + /* GCC 4.8 and Clang 3.8 needs extra help here */ + return Containers::optional(std::move(data)); } }} CORRADE_PLUGIN_REGISTER(TgaImageConverter, Magnum::Trade::TgaImageConverter, - "cz.mosra.magnum.Trade.AbstractImageConverter/0.3.1") + "cz.mosra.magnum.Trade.AbstractImageConverter/0.3.2") diff --git a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h index e377708e7..8b1f58011 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h @@ -104,7 +104,7 @@ class MAGNUM_TGAIMAGECONVERTER_EXPORT TgaImageConverter: public AbstractImageCon private: ImageConverterFeatures MAGNUM_TGAIMAGECONVERTER_LOCAL doFeatures() const override; - Containers::Array MAGNUM_TGAIMAGECONVERTER_LOCAL doConvertToData(const ImageView2D& image) override; + Containers::Optional> MAGNUM_TGAIMAGECONVERTER_LOCAL doConvertToData(const ImageView2D& image) override; }; }}