From 02a0960d12d2f6dbb3c3776cea64c5a8814d1ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 6 Apr 2025 00:54:22 +0200 Subject: [PATCH] Convert all argument / return SFINAE into template argument SFINAE. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similarly as done in Aug 2024 in Corrade. When these were a part of the function signature, they ended up being encoded into the exported symbol. There are still cases of StridedArrayView slice() having enable_if in the signature, which amounts to about 18 kB symbols in all libMagnum*-d.so libraries, but apart from that this is the state before: $ strings libMagnum*-d.so | grep enable_if | grep -v slice | wc -c 29591 And this is after. All of those are coming from STL, thus from old or deprecated APIs that still use std::vector, std::tuple and such, and from the few std::sort() uses. $ strings libMagnum*-d.so | grep enable_if | grep -v slice | wc -c 4103 In a non-deprecated build it's just this, which is a 10x reduction. Can't really do much about these maybe exceĂșt for implementing my own swap() specializations (sigh?), but I think it's fine. $ strings libMagnum*-d.so | grep enable_if | grep -v slice | wc -c 2904 I also made it consistently use typename std::enable_if<..., int>::type = 0 instead of class = typename std::enable_if<...>::type because the former works correctly also in presence of overloads and having it used consistently everywhere makes it easier to grep & change later. All SFINAE is now also excluded from Doxygen output, because it doesn't make much sense there. It's better to just explain the restriction in words than with this nasty hack. --- src/Magnum/AbstractResourceLoader.h | 12 +- src/Magnum/Animation/Track.h | 6 +- src/Magnum/Array.h | 13 +- src/Magnum/GL/Attribute.h | 6 +- src/Magnum/GL/Context.h | 6 +- src/Magnum/GL/Mesh.h | 14 +- src/Magnum/GL/MultisampleTexture.h | 10 +- src/Magnum/GL/Shader.h | 3 +- src/Magnum/GL/Texture.h | 12 +- src/Magnum/GL/TextureArray.h | 4 +- src/Magnum/Image.h | 4 +- src/Magnum/ImageView.h | 40 +- src/Magnum/Math/Bezier.h | 6 +- src/Magnum/Math/BitVector.h | 27 +- src/Magnum/Math/Color.h | 64 ++-- src/Magnum/Math/CubicHermite.h | 17 +- src/Magnum/Math/Dual.h | 31 +- src/Magnum/Math/Functions.h | 116 ++++-- src/Magnum/Math/FunctionsBatch.h | 2 +- src/Magnum/Math/Packing.h | 10 +- src/Magnum/Math/Range.h | 8 +- src/Magnum/Math/Test/TypeTraitsTest.cpp | 4 +- src/Magnum/Math/TypeTraits.h | 12 +- src/Magnum/Math/Unit.h | 73 ++-- src/Magnum/Math/Vector.h | 342 ++++++++---------- src/Magnum/Math/Vector2.h | 16 +- src/Magnum/MeshTools/Interleave.h | 8 +- src/Magnum/Platform/ScreenedApplication.h | 4 +- src/Magnum/SceneGraph/AbstractFeature.h | 2 +- src/Magnum/SceneGraph/Animable.h | 2 +- src/Magnum/SceneGraph/Camera.h | 2 +- src/Magnum/SceneGraph/Drawable.h | 2 +- src/Magnum/Trade/MaterialData.h | 30 +- src/Magnum/Trade/MeshData.h | 72 +++- src/Magnum/Trade/SceneData.h | 66 +++- src/Magnum/Vk/Extensions.h | 12 +- .../Vk/Implementation/structureHelpers.h | 2 +- 37 files changed, 601 insertions(+), 459 deletions(-) diff --git a/src/Magnum/AbstractResourceLoader.h b/src/Magnum/AbstractResourceLoader.h index 5d84979ed..051aed47c 100644 --- a/src/Magnum/AbstractResourceLoader.h +++ b/src/Magnum/AbstractResourceLoader.h @@ -152,7 +152,11 @@ template class AbstractResourceLoader { } /** @overload */ - template::type, std::nullptr_t>::value>::type> void set(ResourceKey key, U&& data, ResourceDataState state, ResourcePolicy policy) { + template::type, std::nullptr_t>::value, int>::type = 0 + #endif + > void set(ResourceKey key, U&& data, ResourceDataState state, ResourcePolicy policy) { set(key, new typename std::decay::type(std::forward(data)), state, policy); } @@ -172,7 +176,11 @@ template class AbstractResourceLoader { } /** @overload */ - template::type, std::nullptr_t>::value>::type> void set(ResourceKey key, U&& data) { + template::type, std::nullptr_t>::value, int>::type = 0 + #endif + > void set(ResourceKey key, U&& data) { set(key, new typename std::decay::type(std::forward(data))); } diff --git a/src/Magnum/Animation/Track.h b/src/Magnum/Animation/Track.h index 34f97ca31..f8fe1001d 100644 --- a/src/Magnum/Animation/Track.h +++ b/src/Magnum/Animation/Track.h @@ -734,7 +734,11 @@ template::value && std::is_same::value>::type> /*implicit*/ TrackView(const TrackView& other) noexcept: TrackViewStorage{other._keys, other._values, other._interpolation, other._interpolator, other._before, other._after} {} + template::value && std::is_same::value, int>::type = 0 + #endif + > /*implicit*/ TrackView(const TrackView& other) noexcept: TrackViewStorage{other._keys, other._values, other._interpolation, other._interpolator, other._before, other._after} {} /** * @brief Interpolation function diff --git a/src/Magnum/Array.h b/src/Magnum/Array.h index 636f1eac2..deb0e95c3 100644 --- a/src/Magnum/Array.h +++ b/src/Magnum/Array.h @@ -82,11 +82,11 @@ template class CORRADE_DEPRECATED("use Math::Ve * @param first First value * @param next Next values */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr /*implicit*/ Array(T first, U... next); - #else - template::type> constexpr /*implicit*/ Array(T first, U... next): _data{first, next...} {} - #endif + template::type = 0 + #endif + > constexpr /*implicit*/ Array(T first, U... next): _data{first, next...} {} /** @brief Construct array with one value for all fields */ #ifdef DOXYGEN_GENERATING_OUTPUT @@ -95,8 +95,7 @@ template class CORRADE_DEPRECATED("use Math::Ve #ifdef CORRADE_TARGET_MSVC /* MSVC warns for the constructor delegation */ CORRADE_IGNORE_DEPRECATED_PUSH #endif - template::value && dimensions != 1, T>::type> - constexpr /*implicit*/ Array(U value): Array(typename Containers::Implementation::GenerateSequence::Type{}, value) {} + template::value && dimensions != 1, int>::type = 0> constexpr /*implicit*/ Array(U value): Array(typename Containers::Implementation::GenerateSequence::Type{}, value) {} #ifdef CORRADE_TARGET_MSVC CORRADE_IGNORE_DEPRECATED_POP #endif diff --git a/src/Magnum/GL/Attribute.h b/src/Magnum/GL/Attribute.h index 6700c64a9..3a59f9861 100644 --- a/src/Magnum/GL/Attribute.h +++ b/src/Magnum/GL/Attribute.h @@ -786,18 +786,18 @@ MAGNUM_GL_EXPORT bool hasVertexFormat(Magnum::VertexFormat format); namespace Implementation { -template constexpr DynamicAttribute::Kind kindFor(typename std::enable_if::ScalarType, Float>::value, typename GL::Attribute::DataOptions>::type options) { +template::ScalarType, Float>::value, int>::type = 0> constexpr DynamicAttribute::Kind kindFor(typename GL::Attribute::DataOptions options) { return options & GL::Attribute::DataOption::Normalized ? DynamicAttribute::Kind::GenericNormalized : DynamicAttribute::Kind::Generic; } #ifndef MAGNUM_TARGET_GLES2 -template constexpr DynamicAttribute::Kind kindFor(typename std::enable_if::ScalarType>::value, typename GL::Attribute::DataOptions>::type) { +template::ScalarType>::value, int>::type = 0> constexpr DynamicAttribute::Kind kindFor(typename GL::Attribute::DataOptions) { return DynamicAttribute::Kind::Integral; } #ifndef MAGNUM_TARGET_GLES -template constexpr DynamicAttribute::Kind kindFor(typename std::enable_if::ScalarType, Double>::value, typename GL::Attribute::DataOptions>::type) { +template::ScalarType, Double>::value, int>::type = 0> constexpr DynamicAttribute::Kind kindFor(typename GL::Attribute::DataOptions) { return DynamicAttribute::Kind::Long; } #endif diff --git a/src/Magnum/GL/Context.h b/src/Magnum/GL/Context.h index b4ababbab..5f7f95104 100644 --- a/src/Magnum/GL/Context.h +++ b/src/Magnum/GL/Context.h @@ -109,7 +109,11 @@ class MAGNUM_GL_EXPORT Extension { constexpr const char* string() const { return _string; } /** @brief Construct from a compile-time extension */ - template::value>::type> constexpr /*implicit*/ Extension(const E&): _index{E::Index}, _requiredVersion{E::requiredVersion()}, _coreVersion{E::coreVersion()}, _string{E::string()} {} + template::value, int>::type = 0 + #endif + > constexpr /*implicit*/ Extension(const E&): _index{E::Index}, _requiredVersion{E::requiredVersion()}, _coreVersion{E::coreVersion()}, _string{E::string()} {} private: std::size_t _index; diff --git a/src/Magnum/GL/Mesh.h b/src/Magnum/GL/Mesh.h index 9595dd515..3c8afb41a 100644 --- a/src/Magnum/GL/Mesh.h +++ b/src/Magnum/GL/Mesh.h @@ -911,7 +911,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { template::value>::type + , typename std::enable_if::value, int>::type = 0 #endif > Mesh& addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes) { addVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), 0, attributes...); @@ -952,7 +952,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { template::value>::type + , typename std::enable_if::value, int>::type = 0 #endif > Mesh& addVertexBufferInstanced(Buffer& buffer, UnsignedInt divisor, GLintptr offset, const T&... attributes) { addVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), divisor, attributes...); @@ -996,7 +996,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { template::value>::type + , typename std::enable_if::value, int>::type = 0 #endif > Mesh& addVertexBuffer(Buffer&& buffer, GLintptr offset, const T&... attributes) { addVertexBuffer(buffer, offset, attributes...); @@ -1015,7 +1015,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { template::value>::type + , typename std::enable_if::value, int>::type = 0 #endif > Mesh& addVertexBufferInstanced(Buffer&& buffer, UnsignedInt divisor, GLintptr offset, const T&... attributes) { addVertexBufferInstanced(buffer, divisor, offset, attributes...); @@ -1224,7 +1224,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { } void addVertexBufferInternal(Buffer&, GLintptr, GLsizei, GLuint) {} - template void addVertexAttribute(typename std::enable_if::ScalarType, Float>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + template::ScalarType, Float>::value, int>::type = 0> void addVertexAttribute(Buffer& buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { for(UnsignedInt i = 0; i != Attribute::Vectors; ++i) attributePointerInternal(buffer, location+i, @@ -1237,7 +1237,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { } #ifndef MAGNUM_TARGET_GLES2 - template void addVertexAttribute(typename std::enable_if::ScalarType>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + template::ScalarType>::value, int>::type = 0> void addVertexAttribute(Buffer& buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { attributePointerInternal(buffer, location, GLint(attribute.components()), @@ -1249,7 +1249,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { } #ifndef MAGNUM_TARGET_GLES - template void addVertexAttribute(typename std::enable_if::ScalarType, Double>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + template::ScalarType, Double>::value, int>::type = 0> void addVertexAttribute(Buffer& buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { for(UnsignedInt i = 0; i != Attribute::Vectors; ++i) attributePointerInternal(buffer, location+i, diff --git a/src/Magnum/GL/MultisampleTexture.h b/src/Magnum/GL/MultisampleTexture.h index a1f8a2040..d1000908b 100644 --- a/src/Magnum/GL/MultisampleTexture.h +++ b/src/Magnum/GL/MultisampleTexture.h @@ -165,7 +165,7 @@ MultisampleTexture: public AbstractTexture { * @gl_extension{EXT,texture_view} */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static MultisampleTexture view(MultisampleTexture2DArray& original, TextureFormat internalFormat, Int layer); @@ -186,7 +186,7 @@ MultisampleTexture: public AbstractTexture { * @gl_extension{EXT,texture_view} */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static MultisampleTexture view(MultisampleTexture2DArray& original, TextureFormat internalFormat, Int layerOffset, Int layerCount); @@ -252,7 +252,7 @@ MultisampleTexture: public AbstractTexture { * @requires_gl42 Extension @gl_extension{ARB,shader_image_load_store} */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif void bindImage(Int imageUnit, ImageAccess access, ImageFormat format) { bindImageInternal(imageUnit, 0, false, 0, access, format); @@ -279,7 +279,7 @@ MultisampleTexture: public AbstractTexture { * multisample 2D array textures. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif void bindImage(Int imageUnit, Int layer, ImageAccess access, ImageFormat format) { bindImageInternal(imageUnit, 0, false, layer, access, format); @@ -305,7 +305,7 @@ MultisampleTexture: public AbstractTexture { * multisample 2D array textures. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif void bindImageLayered(Int imageUnit, ImageAccess access, ImageFormat format) { bindImageInternal(imageUnit, 0, true, 0, access, format); diff --git a/src/Magnum/GL/Shader.h b/src/Magnum/GL/Shader.h index c6d2b0ad0..299ba8015 100644 --- a/src/Magnum/GL/Shader.h +++ b/src/Magnum/GL/Shader.h @@ -716,8 +716,7 @@ class MAGNUM_GL_EXPORT Shader: public AbstractObject { #else /* Otherwise passing a char* is ambiguous between this and the StringView overload. Sigh, C++. */ - template::value>::type> - Shader& addSource(U&& source) { + template::value, int>::type = 0> Shader& addSource(U&& source) { return addSourceInternal(Utility::move(source)); } #endif diff --git a/src/Magnum/GL/Texture.h b/src/Magnum/GL/Texture.h index 27da138ba..fb3f46a90 100644 --- a/src/Magnum/GL/Texture.h +++ b/src/Magnum/GL/Texture.h @@ -196,7 +196,7 @@ Texture: public AbstractTexture { * @requires_gles Texture views are not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static Texture view(TextureArray& original, TextureFormat internalFormat, Int levelOffset, Int levelCount, Int layer); @@ -217,7 +217,7 @@ Texture: public AbstractTexture { * @requires_gles Texture views are not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static Texture view(CubeMapTexture& original, TextureFormat internalFormat, Int levelOffset, Int levelCount, Int layer); @@ -238,7 +238,7 @@ Texture: public AbstractTexture { * @requires_gles Texture views are not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static Texture view(CubeMapTextureArray& original, TextureFormat internalFormat, Int levelOffset, Int levelCount, Int layer); #endif @@ -320,7 +320,7 @@ Texture: public AbstractTexture { * @requires_gles Shader image load/store is not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif void bindImage(Int imageUnit, Int level, ImageAccess access, ImageFormat format) { bindImageInternal(imageUnit, level, false, 0, access, format); @@ -348,7 +348,7 @@ Texture: public AbstractTexture { * @requires_gles Shader image load/store is not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif void bindImage(Int imageUnit, Int level, Int layer, ImageAccess access, ImageFormat format) { bindImageInternal(imageUnit, level, false, layer, access, format); @@ -375,7 +375,7 @@ Texture: public AbstractTexture { * @requires_gles Shader image load/store is not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif void bindImageLayered(Int imageUnit, Int level, ImageAccess access, ImageFormat format) { bindImageInternal(imageUnit, level, true, 0, access, format); diff --git a/src/Magnum/GL/TextureArray.h b/src/Magnum/GL/TextureArray.h index 652c90518..8219e82ca 100644 --- a/src/Magnum/GL/TextureArray.h +++ b/src/Magnum/GL/TextureArray.h @@ -199,7 +199,7 @@ TextureArray: public AbstractTexture { * @requires_gles Texture views are not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static TextureArray view(CubeMapTexture& original, TextureFormat internalFormat, Int levelOffset, Int levelCount, Int layerOffset, Int layerCount); @@ -220,7 +220,7 @@ TextureArray: public AbstractTexture { * @requires_gles Texture views are not available in WebGL. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif static TextureArray view(CubeMapTextureArray& original, TextureFormat internalFormat, Int levelOffset, Int levelCount, Int layerOffset, Int layerCount); #endif diff --git a/src/Magnum/Image.h b/src/Magnum/Image.h index e938c38dc..f362ed090 100644 --- a/src/Magnum/Image.h +++ b/src/Magnum/Image.h @@ -358,9 +358,9 @@ template class Image { template::value || std::is_integral::value>::type + , typename std::enable_if::value || std::is_integral::value, int>::type = 0 #endif - > /*implicit*/ Image(T format) noexcept: Image{{}, format} {} + > /*implicit*/ Image(T format) noexcept: Image{{}, format} {} /** @brief Copying is not allowed */ Image(const Image&) = delete; diff --git a/src/Magnum/ImageView.h b/src/Magnum/ImageView.h index ce1e9f112..7df1b75a5 100644 --- a/src/Magnum/ImageView.h +++ b/src/Magnum/ImageView.h @@ -424,13 +424,21 @@ template class ImageView { * there's no concept of 2D arrays of 1D images. Use the @p flags * parameter to add arbitrary other flags. */ - template::type> /*implicit*/ ImageView(const ImageView& other, ImageFlags flags = {}) noexcept; + template::type = 0 + #endif + > /*implicit*/ ImageView(const ImageView& other, ImageFlags flags = {}) noexcept; /** * @brief Convert a mutable view to a const one * @m_since{2019,10} */ - template::value && !std::is_const::value>::type> /*implicit*/ ImageView(const ImageView& other) noexcept; + template::value && !std::is_const::value, int>::type = 0 + #endif + > /*implicit*/ ImageView(const ImageView& other) noexcept; /** * @brief Layout flags @@ -830,13 +838,21 @@ template class CompressedImageView { * there's no concept of 2D arrays of 1D images. Use the @p flags * parameter to add arbitrary other flags. */ - template::type> /*implicit*/ CompressedImageView(const CompressedImageView& other, ImageFlags flags = {}) noexcept; + template::type = 0 + #endif + > /*implicit*/ CompressedImageView(const CompressedImageView& other, ImageFlags flags = {}) noexcept; /** * @brief Convert a mutable view to a const one * @m_since{2019,10} */ - template::value && !std::is_const::value>::type> /*implicit*/ CompressedImageView(const CompressedImageView& other) noexcept; + template::value && !std::is_const::value, int>::type = 0 + #endif + > /*implicit*/ CompressedImageView(const CompressedImageView& other) noexcept; /** * @brief Layout flags @@ -994,8 +1010,8 @@ template template inline ImageView template ImageView::ImageView(const ImageView& other, const ImageFlags flags) noexcept: +#ifndef DOXYGEN_GENERATING_OUTPUT +template template::type> ImageView::ImageView(const ImageView& other, const ImageFlags flags) noexcept: _storage{other._storage}, _format{other._format}, _formatExtra{other._formatExtra}, @@ -1004,9 +1020,9 @@ template template(UnsignedShort(other._flags)&~UnsignedShort(ImageFlag2D::Array))|flags}, _size{Math::Vector::pad(other._size, 1)}, _data{other._data} {} -#endif -template template ImageView::ImageView(const ImageView& other) noexcept: _storage{other._storage}, _format{other._format}, _formatExtra{other._formatExtra}, _pixelSize{other._pixelSize}, _flags{other._flags}, _size{other._size}, _data{other._data} {} +template template::value && !std::is_const::value, int>::type> ImageView::ImageView(const ImageView& other) noexcept: _storage{other._storage}, _format{other._format}, _formatExtra{other._formatExtra}, _pixelSize{other._pixelSize}, _flags{other._flags}, _size{other._size}, _data{other._data} {} +#endif template template inline CompressedImageView::CompressedImageView(const CompressedPixelStorage storage, const U format, const VectorTypeFor& size, const Containers::ArrayView data, const ImageFlags flags) noexcept: CompressedImageView{storage, UnsignedInt(format), size, data, flags} { static_assert(sizeof(U) <= 4, @@ -1018,17 +1034,17 @@ template template inline CompressedIma "format types larger than 32bits are not supported"); } -#ifndef DOXYGEN_GENERATING_OUTPUT /* it complains otherwise. why? don't know, don't want to know */ -template template CompressedImageView::CompressedImageView(const CompressedImageView& other, const ImageFlags flags) noexcept: +#ifndef DOXYGEN_GENERATING_OUTPUT +template template::type> CompressedImageView::CompressedImageView(const CompressedImageView& other, const ImageFlags flags) noexcept: _storage{other._storage}, _format{other._format}, /* Removing the Array bit and transferring the rest, as documented */ _flags{ImageFlag(UnsignedShort(other._flags)&~UnsignedShort(ImageFlag2D::Array))|flags}, _size{Math::Vector::pad(other._size, 1)}, _data{other._data} {} -#endif -template template CompressedImageView::CompressedImageView(const CompressedImageView& other) noexcept: _storage{other._storage}, _format{other._format}, _flags{other._flags}, _size{other._size}, _data{other._data} {} +template template::value && !std::is_const::value, int>::type> CompressedImageView::CompressedImageView(const CompressedImageView& other) noexcept: _storage{other._storage}, _format{other._format}, _flags{other._flags}, _size{other._size}, _data{other._data} {} +#endif } diff --git a/src/Magnum/Math/Bezier.h b/src/Magnum/Math/Bezier.h index 4aeedc273..1cafce876 100644 --- a/src/Magnum/Math/Bezier.h +++ b/src/Magnum/Math/Bezier.h @@ -119,11 +119,9 @@ template class Bezier { * inverse operation. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template static typename std::enable_if>::type - #else - static Bezier + template::type = 0> #endif - fromCubicHermite(const CubicHermite& a, const CubicHermite& b) { + static Bezier fromCubicHermite(const CubicHermite& a, const CubicHermite& b) { return {a.point(), a.outTangent()/T(3) - a.point(), b.point() - b.inTangent()/T(3), b.point()}; } diff --git a/src/Magnum/Math/BitVector.h b/src/Magnum/Math/BitVector.h index 61903ef12..73b81b37c 100644 --- a/src/Magnum/Math/BitVector.h +++ b/src/Magnum/Math/BitVector.h @@ -112,18 +112,25 @@ template class BitVector { * @param first Value for first 8bit segment * @param next Values for next Bbit segments */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr /*implicit*/ BitVector(UnsignedByte first, T... next) noexcept; - #else - template::type> constexpr /*implicit*/ BitVector(UnsignedByte first, T... next) noexcept: _data{first, UnsignedByte(next)...} {} - #endif + template::type = 0 + #else + , class = typename std::enable_if::type + #endif + #endif + > constexpr /*implicit*/ BitVector(UnsignedByte first, T... next) noexcept: _data{first, UnsignedByte(next)...} {} /** @brief Construct a bit vector with one value for all fields */ - #ifdef DOXYGEN_GENERATING_OUTPUT - explicit BitVector(T value) noexcept; - #else - template::value && size != 1, bool>::type> constexpr explicit BitVector(T value) noexcept: BitVector(typename Containers::Implementation::GenerateSequence::Type{}, value ? FullSegmentMask : 0) {} - #endif + template::value && size != 1, int>::type = 0 + #endif + > constexpr explicit BitVector(T value) noexcept: BitVector(typename Containers::Implementation::GenerateSequence::Type{}, value ? FullSegmentMask : 0) {} /** @brief Construct a bit vector from external representation */ template::from(std::declval()))> constexpr explicit BitVector(const U& other) noexcept: BitVector{Implementation::BitVectorConverter::from(other)} {} diff --git a/src/Magnum/Math/Color.h b/src/Magnum/Math/Color.h index 86f0e46a7..6057668f8 100644 --- a/src/Magnum/Math/Color.h +++ b/src/Magnum/Math/Color.h @@ -48,7 +48,7 @@ namespace Magnum { namespace Math { namespace Implementation { /* Convert color from HSV */ -template typename std::enable_if::value, Color3>::type fromHsv(ColorHsv hsv) { +template::value, int>::type = 0> Color3 fromHsv(ColorHsv hsv) { /* Remove repeats */ hsv.hue -= floor(T(hsv.hue)/T(360))*Deg(360); if(hsv.hue < Deg(0)) hsv.hue += Deg(360); @@ -70,7 +70,7 @@ template typename std::enable_if::value, Color3>: default: CORRADE_INTERNAL_DEBUG_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ } } -template inline typename std::enable_if::value, Color3>::type fromHsv(const ColorHsv::FloatingPointType>& hsv) { +template::value, int>::type = 0> inline Color3 fromHsv(const ColorHsv::FloatingPointType>& hsv) { return pack>(fromHsv::FloatingPointType>(hsv)); } @@ -92,54 +92,54 @@ template Deg hue(const Color3& color, T max, T delta) { } /* Hue, saturation, value for floating-point types */ -template inline Deg hue(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline Deg hue(const Color3& color) { T max = color.max(); T delta = max - color.min(); return hue(color, max, delta); } -template inline T saturation(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline T saturation(const Color3& color) { T max = color.max(); T delta = max - color.min(); return max != T(0) ? delta/max : T(0); } -template inline T value(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline T value(const Color3& color) { return color.max(); } /* Hue, saturation, value for integral types */ -template inline Deg::FloatingPointType> hue(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline Deg::FloatingPointType> hue(const Color3& color) { return hue::FloatingPointType>(unpack::FloatingPointType>>(color)); } -template inline typename Color3::FloatingPointType saturation(typename std::enable_if::value, const Color3&>::type& color) { +template::value, int>::type = 0> inline typename Color3::FloatingPointType saturation(const Color3& color) { return saturation::FloatingPointType>(unpack::FloatingPointType>>(color)); } -template inline typename Color3::FloatingPointType value(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline typename Color3::FloatingPointType value(const Color3& color) { return unpack::FloatingPointType>(color.max()); } /* Convert color to HSV */ -template inline ColorHsv toHsv(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline ColorHsv toHsv(const Color3& color) { T max = color.max(); T delta = max - color.min(); return ColorHsv{hue::FloatingPointType>(color, max, delta), max != T(0) ? delta/max : T(0), max}; } -template inline ColorHsv::FloatingPointType> toHsv(typename std::enable_if::value, const Color3&>::type color) { +template::value, int>::type = 0> inline ColorHsv::FloatingPointType> toHsv(const Color3& color) { return toHsv::FloatingPointType>(unpack::FloatingPointType>>(color)); } /* sRGB -> RGB conversion */ -template typename std::enable_if::value, Color3>::type fromSrgb(const Vector3& srgb) { +template::value, int>::type = 0> inline Color3 fromSrgb(const Vector3& srgb) { constexpr const T a(T(0.055)); return lerp(srgb/T(12.92), pow((srgb + Vector3{a})/(T(1.0) + a), T(2.4)), srgb > Vector3(T(0.04045))); } -template typename std::enable_if::value, Color4>::type fromSrgbAlpha(const Vector4& srgbAlpha) { +template::value, int>::type = 0> inline Color4 fromSrgbAlpha(const Vector4& srgbAlpha) { return {fromSrgb(srgbAlpha.rgb()), srgbAlpha.a()}; } -template inline typename std::enable_if::value, Color3>::type fromSrgb(const Vector3::FloatingPointType>& srgb) { +template::value, int>::type = 0> inline Color3 fromSrgb(const Vector3::FloatingPointType>& srgb) { return pack>(fromSrgb::FloatingPointType>(srgb)); } -template inline typename std::enable_if::value, Color4>::type fromSrgbAlpha(const Vector4::FloatingPointType>& srgbAlpha) { +template::value, int>::type = 0> inline Color4 fromSrgbAlpha(const Vector4::FloatingPointType>& srgbAlpha) { return {fromSrgb(srgbAlpha.rgb()), pack(srgbAlpha.a())}; } template inline Color3 fromSrgbIntegral(const Vector3& srgb) { @@ -152,23 +152,23 @@ template inline Color4 fromSrgbAlphaIntegral(const V } /* Integer linear RGB -> linear RGB conversion */ -template inline typename std::enable_if::value, Color3>::type fromLinearRgbInt(UnsignedInt linear) { +template::value, int>::type = 0> inline Color3 fromLinearRgbInt(UnsignedInt linear) { return {unpack(UnsignedByte(linear >> 16)), unpack(UnsignedByte(linear >> 8)), unpack(UnsignedByte(linear))}; } -template inline typename std::enable_if::value, Color4>::type fromLinearRgbaInt(UnsignedInt linear) { +template::value, int>::type = 0> inline Color4 fromLinearRgbaInt(UnsignedInt linear) { return {unpack(UnsignedByte(linear >> 24)), unpack(UnsignedByte(linear >> 16)), unpack(UnsignedByte(linear >> 8)), unpack(UnsignedByte(linear))}; } -template inline typename std::enable_if::value, Color3>::type fromLinearRgbInt(UnsignedInt linear) { +template::value, int>::type = 0> inline Color3 fromLinearRgbInt(UnsignedInt linear) { return {pack(unpack(UnsignedByte(linear >> 16))), pack(unpack(UnsignedByte(linear >> 8))), pack(unpack(UnsignedByte(linear)))}; } -template inline typename std::enable_if::value, Color4>::type fromLinearRgbaInt(UnsignedInt linear) { +template::value, int>::type = 0> inline Color4 fromLinearRgbaInt(UnsignedInt linear) { return {pack(unpack(UnsignedByte(linear >> 24))), pack(unpack(UnsignedByte(linear >> 16))), pack(unpack(UnsignedByte(linear >> 8))), @@ -176,17 +176,17 @@ template inline typename std::enable_if::value, Color4 } /* RGB -> sRGB conversion */ -template Vector3::FloatingPointType> toSrgb(typename std::enable_if::value, const Color3&>::type rgb) { +template::value, int>::type = 0> Vector3::FloatingPointType> toSrgb(const Color3& rgb) { constexpr const T a = T(0.055); return lerp(rgb*T(12.92), (T(1.0) + a)*pow(rgb, T(1.0)/T(2.4)) - Vector3{a}, rgb > Vector3(T(0.0031308))); } -template Vector4::FloatingPointType> toSrgbAlpha(typename std::enable_if::value, const Color4&>::type rgba) { +template::value, int>::type = 0> Vector4::FloatingPointType> toSrgbAlpha(const Color4& rgba) { return {toSrgb(rgba.rgb()), rgba.a()}; } -template inline Vector3::FloatingPointType> toSrgb(typename std::enable_if::value, const Color3&>::type rgb) { +template::value, int>::type = 0> inline Vector3::FloatingPointType> toSrgb(const Color3& rgb) { return toSrgb::FloatingPointType>(unpack::FloatingPointType>>(rgb)); } -template inline Vector4::FloatingPointType> toSrgbAlpha(typename std::enable_if::value, const Color4&>::type rgba) { +template::value, int>::type = 0> inline Vector4::FloatingPointType> toSrgbAlpha(const Color4& rgba) { return {toSrgb(rgba.rgb()), unpack::FloatingPointType>(rgba.a())}; } template inline Vector3 toSrgbIntegral(const Color3& rgb) { @@ -199,23 +199,23 @@ template inline Vector4 toSrgbAlphaIntegral(c } /* Linear RGB -> integer linear RGB conversion */ -template inline typename std::enable_if::value, UnsignedInt>::type toLinearRgbInt(const Color3& linear) { +template::value, int>::type = 0> inline UnsignedInt toLinearRgbInt(const Color3& linear) { return (pack(linear[0]) << 16) | (pack(linear[1]) << 8) | pack(linear[2]); } -template inline typename std::enable_if::value, UnsignedInt>::type toLinearRgbaInt(const Color4& linear) { +template::value, int>::type = 0> inline UnsignedInt toLinearRgbaInt(const Color4& linear) { return (pack(linear[0]) << 24) | (pack(linear[1]) << 16) | (pack(linear[2]) << 8) | pack(linear[3]); } -template inline typename std::enable_if::value, UnsignedInt>::type toLinearRgbInt(const Color3& linear) { +template::value, int>::type = 0> inline UnsignedInt toLinearRgbInt(const Color3& linear) { return (pack(unpack(linear[0])) << 16) | (pack(unpack(linear[1])) << 8) | pack(unpack(linear[2])); } -template inline typename std::enable_if::value, UnsignedInt>::type toLinearRgbaInt(const Color4& linear) { +template::value, int>::type = 0> inline UnsignedInt toLinearRgbaInt(const Color4& linear) { return (pack(unpack(linear[0])) << 24) | (pack(unpack(linear[1])) << 16) | (pack(unpack(linear[2])) << 8) | @@ -223,7 +223,7 @@ template inline typename std::enable_if::value, UnsignedI } /* CIE XYZ -> RGB conversion */ -template typename std::enable_if::value, Color3>::type fromXyz(const Vector3& xyz) { +template::value, int>::type = 0> Color3 fromXyz(const Vector3& xyz) { /* Taken from https://en.wikipedia.org/wiki/Talk:SRGB#Rounded_vs._Exact, the rounded matrices from the main article don't round-trip perfectly */ return Matrix3x3{ @@ -231,12 +231,12 @@ template typename std::enable_if::value, Color3>: Vector3{T(-329)/T(214), T(1648619)/T(878810), T(-2585)/T(12673)}, Vector3{T(-1974)/T(3959), T(36519)/T(878810), T(705)/T(667)}}*xyz; } -template inline typename std::enable_if::value, Color3>::type fromXyz(const Vector3::FloatingPointType>& xyz) { +template::value, int>::type = 0> inline Color3 fromXyz(const Vector3::FloatingPointType>& xyz) { return pack>(fromXyz::FloatingPointType>(xyz)); } /* RGB -> CIE XYZ conversion */ -template Vector3::FloatingPointType> toXyz(typename std::enable_if::value, const Color3&>::type rgb) { +template::value, int>::type = 0> Vector3::FloatingPointType> toXyz(const Color3& rgb) { /* Taken from https://en.wikipedia.org/wiki/Talk:SRGB#Rounded_vs._Exact, the rounded matrices from the main article don't round-trip perfectly */ return (Matrix3x3{ @@ -244,7 +244,7 @@ template Vector3::FloatingPointType> toXyz(typename Vector3{T(87881)/T(245763), T(175762)/T(245763), T(87881)/T(737289)}, Vector3{T(12673)/T(70218), T(12673)/T(175545), T(1001167)/T(1053270)}})*rgb; } -template inline Vector3::FloatingPointType> toXyz(typename std::enable_if::value, const Color3&>::type rgb) { +template::value, int>::type = 0> inline Vector3::FloatingPointType> toXyz(const Color3& rgb) { return toXyz::FloatingPointType>(unpack::FloatingPointType>>(rgb)); } @@ -256,10 +256,10 @@ template inline Vector3::FloatingPointType> toXyz(ty projects created directly using VS (enabled by default since 15.5) but not projects using CMake. Not using SFINAE in this case makes it work. Minimal repro case here: https://twitter.com/czmosra/status/1039446378248896513 */ -template constexpr typename std::enable_if::value, T>::type fullChannel() { +template::value, int>::type = 0> constexpr T fullChannel() { return T(1.0); } -template constexpr typename std::enable_if::value, T>::type fullChannel() { +template::value, int>::type = 0> constexpr T fullChannel() { return Implementation::bitMax(); } #else diff --git a/src/Magnum/Math/CubicHermite.h b/src/Magnum/Math/CubicHermite.h index 4d6a99757..3c480eb80 100644 --- a/src/Magnum/Math/CubicHermite.h +++ b/src/Magnum/Math/CubicHermite.h @@ -88,13 +88,11 @@ template class CubicHermite { * Enabled only on vector underlying types. See * @ref Bezier::fromCubicHermite() for the inverse operation. */ - template static - #ifdef DOXYGEN_GENERATING_OUTPUT - CubicHermite - #else - typename std::enable_if, T>::value, CubicHermite>::type - #endif - fromBezier(const CubicBezier& a, const CubicBezier& b) { + template, T>::value, int>::type = 0 + #endif + > static CubicHermite fromBezier(const CubicBezier& a, const CubicBezier& b) { return CORRADE_CONSTEXPR_DEBUG_ASSERT(a[3] == b[0], "Math::CubicHermite::fromBezier(): segments are not adjacent"), CubicHermite{3*(a[3] - a[2]), a[3], 3*(b[1] - a[3])}; @@ -124,7 +122,10 @@ template class CubicHermite { * @ref outTangent() is constructed as zero. Enabled only for complex * and quaternion types. */ - template::value>::type> constexpr explicit CubicHermite(IdentityInitT) noexcept: _inTangent{ZeroInit}, _point{IdentityInit}, _outTangent{ZeroInit} {} + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> + #endif + constexpr explicit CubicHermite(IdentityInitT) noexcept: _inTangent{ZeroInit}, _point{IdentityInit}, _outTangent{ZeroInit} {} /** @brief Construct a cubic Hermite spline point without initializing its contents */ explicit CubicHermite(Magnum::NoInitT) noexcept: CubicHermite{Magnum::NoInit, typename std::conditional::value, Magnum::NoInitT*, void*>::type{}} {} diff --git a/src/Magnum/Math/Dual.h b/src/Magnum/Math/Dual.h index 10728b2d3..5ba1c2d40 100644 --- a/src/Magnum/Math/Dual.h +++ b/src/Magnum/Math/Dual.h @@ -81,18 +81,17 @@ template class Dual { #ifdef DOXYGEN_GENERATING_OUTPUT constexpr explicit Dual(ZeroInitT) noexcept; #else - /* MSVC 2015 can't handle {} instead of ::value */ - template::value && std::is_trivial::value>::type> constexpr explicit Dual(ZeroInitT) noexcept: _real{}, _dual{} {} - template::value>::type> constexpr explicit Dual(ZeroInitT) noexcept: _real{ZeroInit}, _dual{ZeroInit} {} + template::value && std::is_trivial::value, int>::type = 0> constexpr explicit Dual(ZeroInitT) noexcept: _real{}, _dual{} {} + template::value, int>::type = 0> + constexpr explicit Dual(ZeroInitT) noexcept: _real{ZeroInit}, _dual{ZeroInit} {} #endif /** @brief Construct without initializing the contents */ #ifdef DOXYGEN_GENERATING_OUTPUT explicit Dual(NoInitT) noexcept; #else - /* MSVC 2015 can't handle {} instead of ::value */ - template::value && std::is_trivial::value>::type> explicit Dual(Magnum::NoInitT) noexcept {} - template::value>::type> explicit Dual(Magnum::NoInitT) noexcept: _real{Magnum::NoInit}, _dual{Magnum::NoInit} {} + template::value && std::is_trivial::value, int>::type = 0> explicit Dual(Magnum::NoInitT) noexcept {} + template::value, int>::type = 0> explicit Dual(Magnum::NoInitT) noexcept: _real{Magnum::NoInit}, _dual{Magnum::NoInit} {} #endif /** @@ -275,7 +274,11 @@ template class Dual { * @see @ref operator*(const Dual&) const, * @ref operator*(const T&, const Dual&) */ - template::value, void>::type> Dual()*std::declval())> operator*(const U& other) const { + template::value, int>::type = 0 + #endif + > Dual()*std::declval())> operator*(const U& other) const { return {_real*other, _dual*other}; } @@ -287,7 +290,7 @@ template class Dual { * @f] * @see @ref operator/(const U&) const */ - template auto operator/(const Dual& other) const -> Dual()/std::declval())> { + template Dual()/std::declval())> operator/(const Dual& other) const { return {_real/other._real, (_dual*other._real - _real*other._dual)/(other._real*other._real)}; } @@ -300,7 +303,11 @@ template class Dual { * @f] * @see @ref operator/(const Dual&) const */ - template::value, Dual()/std::declval())>>::type> V operator/(const U& other) const { + template::value, int>::type = 0 + #endif + > Dual()/std::declval())> operator/(const U& other) const { return {_real/other, _dual/other}; } @@ -328,7 +335,11 @@ Equivalent to @ref Dual::operator*(const Dual&) const assuming that \hat a \hat b = a_0 b_0 + \epsilon (a_0 b_\epsilon + a_\epsilon b_0) = a_0 b_0 + \epsilon a_0 b_\epsilon @f] */ -template::value, Dual()*std::declval())>>::type> inline V operator*(const T& a, const Dual& b) { +template::value, int>::type = 0 + #endif +> inline Dual()*std::declval())> operator*(const T& a, const Dual& b) { return {a*b.real(), a*b.dual()}; } diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 1e273aaa3..8f72b8e2c 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -252,7 +252,11 @@ the operations component-wise. @see @ref isNan(), @ref Constants::inf(), @ref isInf(const Containers::StridedArrayView1D&) */ -template inline typename std::enable_if::value, bool>::type isInf(T value) { +template::value, int>::type = 0 + #endif +> inline bool isInf(T value) { return std::isinf(UnderlyingTypeOf(value)); } @@ -276,7 +280,11 @@ Equivalent to @cpp value != value @ce. @ref isNan(const Containers::StridedArrayView1D&) */ /* defined in Vector.h */ -template typename std::enable_if::value, bool>::type isNan(T value); +template::value, int>::type + #endif +> bool isNan(T value); /** @overload @@ -298,7 +306,11 @@ template inline BitVector isNan(const Vector constexpr typename std::enable_if::value, T>::type min(T value, T min); +template::value, int>::type + #endif +> constexpr T min(T value, T min); /** @overload */ template inline Vector min(const Vector& value, const Vector& min) { @@ -325,7 +337,11 @@ template inline Vector min(const Vector constexpr typename std::enable_if::value, T>::type max(T a, T b); +template::value, int>::type + #endif +> constexpr T max(T a, T b); /** @overload */ template Vector max(const Vector& value, const Vector& max) { @@ -351,7 +367,11 @@ template inline Vector max(const Vector&) */ -template inline typename std::enable_if::value, Containers::Pair>::type minmax(T a, T b) { +template::value, int>::type = 0 + #endif +> inline Containers::Pair minmax(T a, T b) { return a < b ? Containers::pair(a, b) : Containers::pair(b, a); } @@ -376,7 +396,11 @@ set to @p max. Equivalent to: @see @ref min(), @ref max() */ /* defined in Vector.h */ -template constexpr typename std::enable_if::value, T>::type clamp(T value, T min, T max); +template::value, int>::type + #endif +> constexpr T clamp(T value, T min, T max); /** @overload */ template inline Vector clamp(const Vector& value, const Vector& min, const Vector& max) { @@ -399,7 +423,11 @@ template inline Vector clamp(const Vector 0, `0` if @p x = 0 and `-1` if @p x < 0. */ -template inline typename std::enable_if::value, UnderlyingTypeOf>::type sign(T scalar) { +template::value, int>::type = 0 + #endif +> inline UnderlyingTypeOf sign(T scalar) { if(scalar > T(0)) return UnderlyingTypeOf(1); if(scalar < T(0)) return UnderlyingTypeOf(-1); return UnderlyingTypeOf(0); @@ -414,7 +442,11 @@ template inline Vector> sig } /** @brief Absolute value */ -template inline typename std::enable_if::value, T>::type abs(T a) { +template::value, int>::type = 0 + #endif +> inline T abs(T a) { return T(std::abs(UnderlyingTypeOf(a))); } @@ -427,7 +459,11 @@ template inline Vector abs(const Vector inline typename std::enable_if::value, T>::type floor(T a) { +template::value, int>::type = 0 + #endif +> inline T floor(T a) { return T(std::floor(UnderlyingTypeOf(a))); } @@ -440,7 +476,11 @@ template inline Vector floor(const Vector inline typename std::enable_if::value, T>::type round(T a) { +template::value, int>::type = 0 + #endif +> inline T round(T a) { return T(std::round(UnderlyingTypeOf(a))); } @@ -453,7 +493,11 @@ template inline Vector round(const Vector inline typename std::enable_if::value, T>::type ceil(T a) { +template::value, int>::type = 0 + #endif +> inline T ceil(T a) { return T(std::ceil(UnderlyingTypeOf(a))); } @@ -481,7 +525,11 @@ Calculates the remainder @f$ r @f$ of a floating point division: @f[ @m_keyword{mod(),GLSL mod(),} */ -template inline typename std::enable_if::value, T>::type fmod(T a, T b) { +template::value, int>::type = 0 + #endif +> inline T fmod(T a, T b) { return T(std::fmod(UnderlyingTypeOf(a), UnderlyingTypeOf(b))); } @@ -526,13 +574,11 @@ See @ref select() for constant interpolation using the same API and @ref lerp(const CubicHermiteQuaternion&, const CubicHermiteQuaternion&, T) @m_keyword{mix(),GLSL mix(),} */ -template inline +template::value || IsScalar::value) && !Implementation::IsBitVectorOrScalar::value, T>::type - #else - T + , typename std::enable_if<(IsVector::value || IsScalar::value) && !Implementation::IsBitVectorOrScalar::value, int>::type = 0 #endif -lerp(const T& a, const T& b, U t) { +> inline T lerp(const T& a, const T& b, U t) { return Implementation::lerp(a, b, t); } @@ -587,7 +633,11 @@ expression combines that with @ref clamp() to ensure the value is in bounds: @see @ref select() */ -template inline UnderlyingTypeOf::value, T>::type> lerpInverted(T a, T b, T lerp) { +template::value, int>::type = 0 + #endif +> inline UnderlyingTypeOf lerpInverted(T a, T b, T lerp) { return (lerp - a)/(b - a); } @@ -623,7 +673,11 @@ Computes and returns @f$ ab + c @f$. On some architectures might be faster than doing the computation manually. Works only on types that satisfy @ref IsUnitless. */ -template inline typename std::enable_if::value, T>::type fma(T a, T b, T c) { +template::value, int>::type = 0 + #endif +> inline T fma(T a, T b, T c) { static_assert(IsUnitless::value, "expecting a unitless type"); /* On Emscripten it works with -O2 but not with -O1 (function not defined). I guess that's only because -O2 optimizes it out, so disabling it there. */ @@ -693,7 +747,11 @@ Returns integral power of base to the exponent. Works only on types that satisfy @ref IsUnitless. @see @ref pow(T, T) */ -template constexpr typename std::enable_if::value, T>::type pow(T base) { +template::value, int>::type = 0 + #endif +> constexpr T pow(T base) { static_assert(IsUnitless::value, "expected a unitless type"); return Implementation::Pow::pow(base); } @@ -713,7 +771,11 @@ Returns power of @p base to the @p exponent. Works only on types that satisfy @ref IsUnitless. @see @ref pow(T), @ref exp() */ -template inline typename std::enable_if::value, T>::type pow(T base, T exponent) { +template::value, int>::type = 0 + #endif +> inline T pow(T base, T exponent) { static_assert(IsUnitless::value, "expected a unitless type"); return std::pow(base, exponent); } @@ -732,7 +794,11 @@ template inline Vector pow(const Vector&) */ -template inline typename std::enable_if::value, T>::type sqrt(T a) { +template::value, int>::type = 0 + #endif +> inline T sqrt(T a) { static_assert(IsUnitless::value, "expecting a unitless type"); return std::sqrt(a); } @@ -752,7 +818,11 @@ Works only on types that satisfy @ref IsUnitless. @see @ref sqrt(), @ref Vector::lengthInverted() @m_keyword{inversesqrt(),GLSL inversesqrt(),} */ -template inline typename std::enable_if::value, T>::type sqrtInverted(T a) { +template::value, int>::type = 0 + #endif +> inline T sqrtInverted(T a) { static_assert(IsUnitless::value, "expecting a unitless type"); return T(1)/std::sqrt(a); } diff --git a/src/Magnum/Math/FunctionsBatch.h b/src/Magnum/Math/FunctionsBatch.h index 1e7e83054..4b7c2ed67 100644 --- a/src/Magnum/Math/FunctionsBatch.h +++ b/src/Magnum/Math/FunctionsBatch.h @@ -292,7 +292,7 @@ template inline T max(const T(&array)[size]) { } namespace Implementation { - template inline typename std::enable_if::value, void>::type minmax(T& min, T& max, T value) { + template::value, int>::type = 0> inline void minmax(T& min, T& max, T value) { if(value < min) min = value; else if(value > max) diff --git a/src/Magnum/Math/Packing.h b/src/Magnum/Math/Packing.h index 9c307f97d..a37452b6c 100644 --- a/src/Magnum/Math/Packing.h +++ b/src/Magnum/Math/Packing.h @@ -82,14 +82,14 @@ representation to use. Example usage: */ template inline FloatingPoint unpack(const Integral& value); #else -template inline typename std::enable_if::value && std::is_unsigned::value, FloatingPoint>::type unpack(const Integral& value) { +template::value && std::is_unsigned::value, int>::type = 0> inline FloatingPoint unpack(const Integral& value) { static_assert(IsFloatingPoint::value && IsIntegral::value, "unpacking must be done from integral to floating-point type"); static_assert(bits <= sizeof(Integral)*8, "bit count larger than size of the integral type"); return FloatingPoint(value/UnderlyingTypeOf(Implementation::bitMax())); } -template inline typename std::enable_if::value && std::is_signed::value, FloatingPoint>::type unpack(const Integral& value) { +template::value && std::is_signed::value, int>::type = 0> inline FloatingPoint unpack(const Integral& value) { static_assert(IsFloatingPoint::value && IsIntegral::value, "unpacking must be done from integral to floating-point type"); static_assert(bits <= sizeof(Integral)*8, @@ -111,7 +111,7 @@ template inline FloatingPoint unpack(const Integral& value); #else -template inline typename std::enable_if::value, FloatingPoint>::type unpack(const Integral& value) { +template::value, int>::type = 0> inline FloatingPoint unpack(const Integral& value) { return unpack(value); } template inline FloatingPoint unpack(const Vector& value) { @@ -139,7 +139,7 @@ given *signed* integral type. #ifdef DOXYGEN_GENERATING_OUTPUT template inline Integral pack(const FloatingPoint& value); #else -template inline typename std::enable_if::value, Integral>::type pack(FloatingPoint value) { +template::value, int>::type = 0> inline Integral pack(FloatingPoint value) { static_assert(IsFloatingPoint::value && IsIntegral::value, "packing must be done from floating-point to integral type"); static_assert(bits <= sizeof(Integral)*8, @@ -167,7 +167,7 @@ representation to use. Example usage: #ifdef DOXYGEN_GENERATING_OUTPUT template inline Integral pack(FloatingPoint value); #else -template inline typename std::enable_if::value, Integral>::type pack(FloatingPoint value) { +template::value, int>::type = 0> inline Integral pack(FloatingPoint value) { return pack(value); } template inline Integral pack(const Vector& value) { diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index 11180097a..80a03d10a 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -144,7 +144,7 @@ template class Range { constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max) noexcept: _min{min}, _max{max} {} /** @overload */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif constexpr /*implicit*/ Range(const Vector& min, const Vector& max) noexcept: _min{Implementation::RangeTraits::fromVector(min)}, _max{Implementation::RangeTraits::fromVector(max)} {} @@ -161,7 +161,7 @@ template class Range { /** @overload */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif constexpr /*implicit*/ Range(const Containers::Pair, Vector>& minmax) noexcept: _min{minmax.first()}, _max{minmax.second()} {} @@ -311,7 +311,7 @@ template class Range { * @m_since_latest */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif Range scaled(T scaling) const { return {_min*scaling, _max*scaling}; @@ -334,7 +334,7 @@ template class Range { * @m_since_latest */ #ifndef DOXYGEN_GENERATING_OUTPUT - template::type> + template::type = 0> #endif Range scaledFromCenter(T scaling) const { /* Can't use *T(0.5) because that won't work for integers */ diff --git a/src/Magnum/Math/Test/TypeTraitsTest.cpp b/src/Magnum/Math/Test/TypeTraitsTest.cpp index 307f07350..972b0c29c 100644 --- a/src/Magnum/Math/Test/TypeTraitsTest.cpp +++ b/src/Magnum/Math/Test/TypeTraitsTest.cpp @@ -359,10 +359,10 @@ template void TypeTraitsTest::equalsFloatingPointNaN() { } /* Argh! Why there is no standard std::abs() for unsigned types? */ -template::value>::type> T abs(T value) { +template::value, int>::type = 0> T abs(T value) { return value; } -template::value>::type> T abs(T value) { +template::value, int>::type = 0> T abs(T value) { return std::abs(value); } diff --git a/src/Magnum/Math/TypeTraits.h b/src/Magnum/Math/TypeTraits.h index 67c942b1b..a75661ec6 100644 --- a/src/Magnum/Math/TypeTraits.h +++ b/src/Magnum/Math/TypeTraits.h @@ -405,7 +405,11 @@ Calls @ref TypeTraits::equals() --- using fuzzy compare for floating-point types and doing equality comparison on integral types. Scalar complement to @ref equal(const Vector& a, const Vector&). */ -template inline typename std::enable_if::value, bool>::type equal(T a, T b) { +template::value, int>::type = 0 + #endif +> inline bool equal(T a, T b) { return TypeTraits::equals(a, b); } @@ -417,7 +421,11 @@ Calls @ref TypeTraits::equals() --- using fuzzy compare for floating-point types and doing equality comparison on integral types. Scalar complement to @ref notEqual(const Vector& a, const Vector&). */ -template inline typename std::enable_if::value, bool>::type notEqual(T a, T b) { +template::value, int>::type = 0 + #endif +> inline bool notEqual(T a, T b) { return !TypeTraits::equals(a, b); } diff --git a/src/Magnum/Math/Unit.h b/src/Magnum/Math/Unit.h index 4a1b6c8e7..2bf5787a2 100644 --- a/src/Magnum/Math/Unit.h +++ b/src/Magnum/Math/Unit.h @@ -178,12 +178,11 @@ template class Derived, class T> class Unit { * Similar to @ref operator*=(T), except that the multiplication is * done in floating-point. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Unit& - #else - template typename std::enable_if::value && std::is_floating_point::value, Unit&>::type - #endif - operator*=(FloatingPoint number) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > Unit& operator*=(FloatingPoint number) { _value = T(_value*number); return *this; } @@ -199,12 +198,11 @@ template class Derived, class T> class Unit { an out-of-class overload wrapped in CORRADE_MSVC2015_COMPATIBILITY which is (and the two don't conflict, apparently, so both are present) */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr Unit - #else - template constexpr typename std::enable_if::value && std::is_floating_point::value, Unit>::type - #endif - operator*(FloatingPoint number) const { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > constexpr Unit operator*(FloatingPoint number) const { return Unit{T(_value*number)}; } @@ -214,12 +212,11 @@ template class Derived, class T> class Unit { * * Same as @ref operator*(FloatingPoint) const. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template friend constexpr Unit - #else - template friend constexpr typename std::enable_if::value && std::is_floating_point::value, Unit>::type - #endif - operator*(FloatingPoint number, const Unit& value) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > friend constexpr Unit operator*(FloatingPoint number, const Unit& value) { return Unit{T(value._value*number)}; } @@ -241,12 +238,11 @@ template class Derived, class T> class Unit { * Similar to @ref operator/=(T), except that the division is done in * floating-point. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Unit& - #else - template typename std::enable_if::value && std::is_floating_point::value, Unit&>::type - #endif - operator/=(FloatingPoint number) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > Unit& operator/=(FloatingPoint number) { _value = T(_value/number); return *this; } @@ -258,12 +254,11 @@ template class Derived, class T> class Unit { * Similar to @ref operator/(T) const, except that the division is done * in floating-point. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr Unit - #else - template constexpr typename std::enable_if::value && std::is_floating_point::value, Unit>::type - #endif - operator/(FloatingPoint number) const { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > constexpr Unit operator/(FloatingPoint number) const { return Unit{T(_value/number)}; } @@ -278,12 +273,10 @@ template class Derived, class T> class Unit { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Unit& - #else - template typename std::enable_if::value, Unit&>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator%=(Unit other) { + Unit& operator%=(Unit other) { _value %= other._value; return *this; } @@ -294,12 +287,10 @@ template class Derived, class T> class Unit { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Unit - #else - template constexpr typename std::enable_if::value, Unit>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator%(Unit other) const { + constexpr Unit operator%(Unit other) const { return Unit{_value%other._value}; } @@ -314,7 +305,7 @@ template class Derived, class T> class Unit { picked up correctly (and doesn't conflict with the in-class one). See UnitTest::multiplyDivideIntegral() for regression tests, the same issue and a matching workaround is done in Vector as well. */ -template class Derived, class FloatingPoint, class Integral> constexpr typename std::enable_if::value && std::is_floating_point::value, Unit>::type operator*(FloatingPoint number, const Unit& value) { +template class Derived, class FloatingPoint, class Integral, typename std::enable_if::value && std::is_floating_point::value, int>::type = 0> constexpr Unit operator*(FloatingPoint number, const Unit& value) { return value*number; } #endif diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 3690f2d0c..2b74d0650 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -55,18 +55,18 @@ namespace Magnum { namespace Math { #ifndef DOXYGEN_GENERATING_OUTPUT /* Documented in Functions.h, defined here because Vector needs them */ -template inline typename std::enable_if::value, bool>::type isNan(T value) { +template::value, int>::type = 0> inline bool isNan(T value) { return std::isnan(UnderlyingTypeOf(value)); } /* Keeping the same parameter names as in Functions.h so the note about NaN propagation works here too */ -template constexpr typename std::enable_if::value, T>::type min(T value, T min) { +template::value, int>::type = 0> constexpr T min(T value, T min) { return min < value ? min : value; } -template constexpr typename std::enable_if::value, T>::type max(T value, T max) { +template::value, int>::type = 0> constexpr T max(T value, T max) { return value < max ? max : value; } -template constexpr typename std::enable_if::value, T>::type clamp(T value, T min, T max) { +template::value, int>::type = 0> constexpr T clamp(T value, T min, T max) { return Math::min(Math::max(value, min), max); } #endif @@ -139,13 +139,11 @@ dot product is clamped to the @f$ [-1, +1] @f$ range before being passed to @ref angle(const Complex&, const Complex&), @ref angle(const Quaternion&, const Quaternion&) */ -template inline -#ifdef DOXYGEN_GENERATING_OUTPUT -Rad -#else -typename std::enable_if::value, Rad>::type -#endif -angle(const Vector& normalizedA, const Vector& normalizedB) { +template::value, int>::type = 0 + #endif +> inline Rad angle(const Vector& normalizedA, const Vector& normalizedB) { CORRADE_DEBUG_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(), "Math::angle(): vectors" << normalizedA << "and" << normalizedB << "are not normalized", {}); return Rad(std::acos(clamp(dot(normalizedA, normalizedB), FloatingPoint(-1), FloatingPoint(1)))); @@ -217,11 +215,11 @@ template class Vector { explicit Vector(Magnum::NoInitT) noexcept {} /** @brief Construct a vector from components */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr /*implicit*/ Vector(T first, U... next) noexcept; - #else - template::type> constexpr /*implicit*/ Vector(T first, U... next) noexcept: _data{first, next...} {} - #endif + template::type = 0 + #endif + > constexpr /*implicit*/ Vector(T first, U... next) noexcept: _data{first, next...} {} /** * @brief Construct a vector from a fixed-size array @@ -243,9 +241,9 @@ template class Vector { /** @brief Construct a vector with one value for all components */ #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr explicit Vector(T value) noexcept; + constexpr explicit Vector(T value) noexcept; /* showing T instead of U */ #else - template::value && size != 1, T>::type> constexpr explicit Vector(U value) noexcept: Vector(typename Containers::Implementation::GenerateSequence::Type{}, value) {} + template::value && size != 1, int>::type = 0> constexpr explicit Vector(U value) noexcept: Vector(typename Containers::Implementation::GenerateSequence::Type{}, value) {} #endif /** @@ -399,12 +397,10 @@ template class Vector { * @f] * @see @ref flipped(), @ref Vector2::perpendicular() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator-() const { + constexpr Vector operator-() const { return negateInternal(typename Containers::Implementation::GenerateSequence::Type{}); } @@ -503,12 +499,11 @@ template class Vector { * Similar to @ref operator*=(T), except that the multiplication is * done in floating-point. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Vector& - #else - template typename std::enable_if::value && std::is_floating_point::value, Vector&>::type - #endif - operator*=(FloatingPoint scalar) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > Vector& operator*=(FloatingPoint scalar) { for(std::size_t i = 0; i != size; ++i) _data[i] = T(_data[i]*scalar); @@ -521,12 +516,11 @@ template class Vector { * Similar to @ref operator*(T) const, except that the multiplication * is done in floating-point. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr Vector - #else - template constexpr typename std::enable_if::value && std::is_floating_point::value, Vector>::type - #endif - operator*(FloatingPoint scalar) const { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > constexpr Vector operator*(FloatingPoint scalar) const { return multiplyIntegerInternal(scalar, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -539,11 +533,11 @@ template class Vector { an out-of-class overload wrapped in CORRADE_MSVC2015_COMPATIBILITY which is (and the two don't conflict, apparently, so both are present) */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template friend constexpr Vector - #else - template friend constexpr typename std::enable_if::value && std::is_floating_point::value, Vector>::type - #endif + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > friend constexpr Vector operator*(FloatingPoint scalar, const Vector& vector) { return vector*scalar; } @@ -600,12 +594,11 @@ template class Vector { * Similar to @ref operator/=(T), except that the division is done in * floating-point. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Vector& - #else - template typename std::enable_if::value && std::is_floating_point::value, Vector&>::type - #endif - operator/=(FloatingPoint scalar) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > Vector& operator/=(FloatingPoint scalar) { for(std::size_t i = 0; i != size; ++i) _data[i] = T(_data[i]/scalar); @@ -618,12 +611,11 @@ template class Vector { * Similar to @ref operator/(T) const, except that the division is done * in floating-point. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Vector constexpr - #else - template constexpr typename std::enable_if::value && std::is_floating_point::value, Vector>::type - #endif - operator/(FloatingPoint scalar) const { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > constexpr Vector operator/(FloatingPoint scalar) const { return divideIntegerInternal(scalar, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -661,12 +653,11 @@ template class Vector { * multiplication is done in floating-point. The computation is done * in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Vector& - #else - template typename std::enable_if::value && std::is_floating_point::value, Vector&>::type - #endif - operator*=(const Vector& other) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > Vector& operator*=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] = T(_data[i]*other._data[i]); @@ -683,7 +674,7 @@ template class Vector { */ template::value && std::is_floating_point::value>::type* = nullptr + , class Integral = T, typename std::enable_if::value && std::is_floating_point::value, int>::type = 0 #endif > constexpr Vector operator*(const Vector& other) const { return multiplyIntegerInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); @@ -701,7 +692,7 @@ template class Vector { Integral*FloatingPoint variant above */ template::value && std::is_floating_point::value>::type* = nullptr + , class FloatingPoint = T, typename std::enable_if::value && std::is_floating_point::value, int>::type = 0 #endif > constexpr Vector operator*(const Vector& other) const { return other**this; @@ -740,12 +731,11 @@ template class Vector { * division is done in floating-point. The computation is done * in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template Vector& - #else - template typename std::enable_if::value && std::is_floating_point::value, Vector&>::type - #endif - operator/=(const Vector& other) { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > Vector& operator/=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] = T(_data[i]/other._data[i]); @@ -760,12 +750,11 @@ template class Vector { * always an integral vector, convert both arguments to the same * floating-point type to have a floating-point result. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - template constexpr Vector - #else - template constexpr typename std::enable_if::value && std::is_floating_point::value, Vector>::type - #endif - operator/(const Vector& other) const { + template::value && std::is_floating_point::value, int>::type = 0 + #endif + > constexpr Vector operator/(const Vector& other) const { return divideIntegerInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -774,12 +763,10 @@ template class Vector { * * Enabled only for integral types. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector& - #else - template typename std::enable_if::value, Vector&>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator%=(T scalar) { + Vector& operator%=(T scalar) { for(std::size_t i = 0; i != size; ++i) _data[i] %= scalar; @@ -791,12 +778,10 @@ template class Vector { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator%(T scalar) const { + constexpr Vector operator%(T scalar) const { return moduloInternal(scalar, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -805,12 +790,10 @@ template class Vector { * * Enabled only for integral types. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector& - #else - template typename std::enable_if::value, Vector&>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator%=(const Vector& other) { + Vector& operator%=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] %= other._data[i]; @@ -822,12 +805,10 @@ template class Vector { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator%(const Vector& other) const { + constexpr Vector operator%(const Vector& other) const { return moduloInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -836,12 +817,10 @@ template class Vector { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator~() const { + constexpr Vector operator~() const { return invertInternal(typename Containers::Implementation::GenerateSequence::Type{}); } @@ -850,12 +829,10 @@ template class Vector { * * Enabled only for integral types. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector& - #else - template typename std::enable_if::value, Vector&>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator&=(const Vector& other) { + Vector& operator&=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] &= other._data[i]; @@ -867,12 +844,10 @@ template class Vector { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator&(const Vector& other) const { + constexpr Vector operator&(const Vector& other) const { return andInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -881,12 +856,10 @@ template class Vector { * * Enabled only for integral types. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector& - #else - template typename std::enable_if::value, Vector&>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator|=(const Vector& other) { + Vector& operator|=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] |= other._data[i]; @@ -898,12 +871,10 @@ template class Vector { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator|(const Vector& other) const { + constexpr Vector operator|(const Vector& other) const { return orInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -912,12 +883,10 @@ template class Vector { * * Enabled only for integral types. The computation is done in-place. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector& - #else - template typename std::enable_if::value, Vector&>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator^=(const Vector& other) { + Vector& operator^=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] ^= other._data[i]; @@ -929,12 +898,10 @@ template class Vector { * * Enabled only for integral types. */ - #ifdef DOXYGEN_GENERATING_OUTPUT - constexpr Vector - #else - template constexpr typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - operator^(const Vector& other) const { + constexpr Vector operator^(const Vector& other) const { return xorInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); } @@ -946,7 +913,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector& operator<<=(T shift) #else - template typename std::enable_if::value, Vector&>::type operator<<=(typename std::common_type::type shift) + template::value, int>::type = 0> Vector& operator<<=(typename std::common_type::type shift) #endif { for(std::size_t i = 0; i != size; ++i) @@ -963,8 +930,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT constexpr Vector operator<<(T shift) const #else - template constexpr typename std::enable_if::value, Vector>::type - operator<<(typename std::common_type::type shift) const + template::value, int>::type = 0> constexpr Vector operator<<(typename std::common_type::type shift) const #endif { return shiftLeftInternal(shift, typename Containers::Implementation::GenerateSequence::Type{}); @@ -978,7 +944,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector& operator>>=(T shift) #else - template typename std::enable_if::value, Vector&>::type operator>>=(typename std::common_type::type shift) + template::value, int>::type = 0> Vector& operator>>=(typename std::common_type::type shift) #endif { for(std::size_t i = 0; i != size; ++i) @@ -995,8 +961,8 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT constexpr Vector operator>>(T shift) const #else - template - constexpr typename std::enable_if::value, Vector>::type operator>>(typename std::common_type::type shift) const + template::value, int>::type = 0> + constexpr Vector operator>>(typename std::common_type::type shift) const #endif { return shiftRightInternal(shift, typename Containers::Implementation::GenerateSequence::Type{}); @@ -1051,12 +1017,10 @@ template class Vector { * @see @ref length(), @ref Math::sqrtInverted(), @ref normalized(), * @ref resized() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - T - #else - template typename std::enable_if::value, T>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - lengthInverted() const { return T(1)/length(); } + T lengthInverted() const { return T(1)/length(); } /** * @brief Normalized vector (of unit length) @@ -1065,12 +1029,10 @@ template class Vector { * @see @ref isNormalized(), @ref lengthInverted(), @ref resized() * @m_keyword{normalize(),GLSL normalize(),} */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector - #else - template typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - normalized() const { return *this*lengthInverted(); } + Vector normalized() const { return *this*lengthInverted(); } /** * @brief Resized vector @@ -1083,12 +1045,10 @@ template class Vector { * * @see @ref normalized() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector - #else - template typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - resized(T length) const { + Vector resized(T length) const { return *this*(lengthInverted()*length); } @@ -1101,12 +1061,10 @@ template class Vector { * @f] * @see @ref Math::dot(), @ref projectedOntoNormalized() */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector - #else - template typename std::enable_if::value, Vector>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - projected(const Vector& line) const { + Vector projected(const Vector& line) const { return line*Math::dot(*this, line)/line.dot(); } @@ -1121,11 +1079,10 @@ template class Vector { * @see @ref Math::dot() */ #ifdef DOXYGEN_GENERATING_OUTPUT - Vector #else - template typename std::enable_if::value, Vector>::type + template::value, int>::type = 0> #endif - projectedOntoNormalized(const Vector& line) const; + Vector projectedOntoNormalized(const Vector& line) const; /** * @brief Flipped vector @@ -1398,8 +1355,7 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& constexpr Type_ operator+() const { \ return Math::Vector::operator+(); \ } \ - template constexpr typename std::enable_if::value, Type_>::type \ - operator-() const { \ + template::value, int>::type = 0> constexpr Type_ operator-() const { \ return Math::Vector::negateInternal(typename Containers::Implementation::GenerateSequence::Type{}); \ } \ Type_& operator+=(const Math::Vector& other) { \ @@ -1427,14 +1383,14 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& friend constexpr Type_ operator*(typename std::common_type::type scalar, const Type_& vector) { \ return scalar*static_cast&>(vector); \ } \ - template typename std::enable_if::value && std::is_floating_point::value, Type_&>::type operator*=(FloatingPoint scalar) { \ + template::value && std::is_floating_point::value, int>::type = 0> Type_& operator*=(FloatingPoint scalar) { \ Math::Vector::operator*=(scalar); \ return *this; \ } \ - template constexpr typename std::enable_if::value && std::is_floating_point::value, Type_>::type operator*(FloatingPoint scalar) const { \ + template::value && std::is_floating_point::value, int>::type = 0> constexpr Type_ operator*(FloatingPoint scalar) const { \ return Math::Vector::multiplyIntegerInternal(scalar, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template friend constexpr typename std::enable_if::value && std::is_floating_point::value, Type_>::type operator*(FloatingPoint scalar, const Type_& vector) { \ + template::value && std::is_floating_point::value, int>::type = 0> friend constexpr Type_ operator*(FloatingPoint scalar, const Type_& vector) { \ return scalar*static_cast&>(vector); \ } \ \ @@ -1448,11 +1404,11 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& friend constexpr Type_ operator/(typename std::common_type::type scalar, const Type_& vector) { \ return scalar/static_cast&>(vector); \ } \ - template typename std::enable_if::value && std::is_floating_point::value, Type_&>::type operator/=(FloatingPoint scalar) { \ + template::value && std::is_floating_point::value, int>::type = 0> Type_& operator/=(FloatingPoint scalar) { \ Math::Vector::operator/=(scalar); \ return *this; \ } \ - template constexpr typename std::enable_if::value && std::is_floating_point::value, Type_>::type operator/(FloatingPoint scalar) const { \ + template::value && std::is_floating_point::value, int>::type = 0> constexpr Type_ operator/(FloatingPoint scalar) const { \ return Math::Vector::divideIntegerInternal(scalar, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ \ @@ -1463,14 +1419,14 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& constexpr Type_ operator*(const Math::Vector& other) const { \ return Math::Vector::multiplyInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value && std::is_floating_point::value, Type_&>::type operator*=(const Math::Vector& other) { \ + template::value && std::is_floating_point::value, int>::type = 0> Type_& operator*=(const Math::Vector& other) { \ Math::Vector::operator*=(other); \ return *this; \ } \ - template::value && std::is_floating_point::value>::type* = nullptr> constexpr Type_ operator*(const Math::Vector& other) const { \ + template::value && std::is_floating_point::value, int>::type = 0> constexpr Type_ operator*(const Math::Vector& other) const { \ return Math::Vector::multiplyIntegerInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template::value && std::is_floating_point::value>::type* = nullptr> constexpr Type_ operator*(const Math::Vector& other) const { \ + template::value && std::is_floating_point::value, int>::type = 0> constexpr Type_ operator*(const Math::Vector& other) const { \ return other**this; \ } \ \ @@ -1481,78 +1437,78 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& constexpr Type_ operator/(const Math::Vector& other) const { \ return Math::Vector::divideInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value && std::is_floating_point::value, Type_&>::type operator/=(const Math::Vector& other) { \ + template::value && std::is_floating_point::value, int>::type = 0> Type_& operator/=(const Math::Vector& other) { \ Math::Vector::operator/=(other); \ return *this; \ } \ - template constexpr typename std::enable_if::value && std::is_floating_point::value, Type_>::type operator/(const Math::Vector& other) const { \ + template::value && std::is_floating_point::value, int>::type = 0> constexpr Type_ operator/(const Math::Vector& other) const { \ return Math::Vector::divideIntegerInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ \ - template typename std::enable_if::value, Type_&>::type operator%=(T scalar) { \ + template::value, int>::type = 0> Type_& operator%=(T scalar) { \ Math::Vector::operator%=(scalar); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator%(T scalar) const { \ + template::value, int>::type = 0> constexpr Type_ operator%(T scalar) const { \ return Math::Vector::moduloInternal(scalar, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value, Type_&>::type operator%=(const Math::Vector& other) { \ + template::value, int>::type = 0> Type_& operator%=(const Math::Vector& other) { \ Math::Vector::operator%=(other); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator%(const Math::Vector& other) const { \ + template::value, int>::type = 0> constexpr Type_ operator%(const Math::Vector& other) const { \ return Math::Vector::moduloInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ \ - template constexpr typename std::enable_if::value, Type_>::type operator~() const { \ + template::value, int>::type = 0> constexpr Type_ operator~() const { \ return Math::Vector::invertInternal(typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value, Type_&>::type operator&=(const Math::Vector& other) { \ + template::value, int>::type = 0> Type_& operator&=(const Math::Vector& other) { \ Math::Vector::operator&=(other); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator&(const Math::Vector& other) const { \ + template::value, int>::type = 0> constexpr Type_ operator&(const Math::Vector& other) const { \ return Math::Vector::andInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value, Type_&>::type operator|=(const Math::Vector& other) { \ + template::value, int>::type = 0> Type_& operator|=(const Math::Vector& other) { \ Math::Vector::operator|=(other); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator|(const Math::Vector& other) const { \ + template::value, int>::type = 0> constexpr Type_ operator|(const Math::Vector& other) const { \ return Math::Vector::orInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value, Type_&>::type operator^=(const Math::Vector& other) { \ + template::value, int>::type = 0> Type_& operator^=(const Math::Vector& other) { \ Math::Vector::operator^=(other); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator^(const Math::Vector& other) const { \ + template::value, int>::type = 0> constexpr Type_ operator^(const Math::Vector& other) const { \ return Math::Vector::xorInternal(other, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value, Type_&>::type operator<<=(typename std::common_type::type shift) { \ + template::value, int>::type = 0> Type_& operator<<=(typename std::common_type::type shift) { \ Math::Vector::operator<<=(shift); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator<<(typename std::common_type::type shift) const { \ + template::value, int>::type = 0> constexpr Type_ operator<<(typename std::common_type::type shift) const { \ return Math::Vector::shiftLeftInternal(shift, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ - template typename std::enable_if::value, Type_&>::type operator>>=(typename std::common_type::type shift) { \ + template::value, int>::type = 0> Type_& operator>>=(typename std::common_type::type shift) { \ Math::Vector::operator>>=(shift); \ return *this; \ } \ - template constexpr typename std::enable_if::value, Type_>::type operator>>(typename std::common_type::type shift) const { \ + template::value, int>::type = 0> constexpr Type_ operator>>(typename std::common_type::type shift) const { \ return Math::Vector::shiftRightInternal(shift, typename Containers::Implementation::GenerateSequence::Type{}); \ } \ \ - template typename std::enable_if::value, Type_>::type normalized() const { \ + template::value, int>::type = 0> Type_ normalized() const { \ return Math::Vector::normalized(); \ } \ - template typename std::enable_if::value, Type_>::type resized(T length) const { \ + template::value, int>::type = 0> Type_ resized(T length) const { \ return Math::Vector::resized(length); \ } \ - template typename std::enable_if::value, Type_>::type projected(const Math::Vector& other) const { \ + template::value, int>::type = 0> Type_ projected(const Math::Vector& other) const { \ return Math::Vector::projected(other); \ } \ - template typename std::enable_if::value, Type_>::type projectedOntoNormalized(const Math::Vector& other) const { \ + template::value, int>::type = 0> Type_ projectedOntoNormalized(const Math::Vector& other) const { \ return Math::Vector::projectedOntoNormalized(other); \ } \ constexpr Type_ flipped() const { \ @@ -1570,12 +1526,12 @@ extern template MAGNUM_EXPORT Debug& operator<<(Debug&, const Vector<4, Double>& VectorTest::subclass() and corresponding cases in Vector2Test, Vector3Test, Vector4Test and ColorTest for regression tests. The same issue and a matching workaround is done in Unit as well. */ -template constexpr typename std::enable_if::value && std::is_floating_point::value, Vector>::type operator*(FloatingPoint scalar, const Vector& vector) { +template::value && std::is_floating_point::value, int>::type = 0> constexpr Vector operator*(FloatingPoint scalar, const Vector& vector) { return vector*scalar; } #define MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(size, Type) \ - template constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(FloatingPoint scalar, const Type& vector) { \ + template::value && std::is_floating_point::value, int>::type = 0> constexpr Type operator*(FloatingPoint scalar, const Type& vector) { \ return vector*scalar; \ } #endif @@ -1617,12 +1573,10 @@ template inline BitVector Vector::oper } template -#ifdef DOXYGEN_GENERATING_OUTPUT -inline Vector -#else -template inline typename std::enable_if::value, Vector>::type +#ifndef DOXYGEN_GENERATING_OUTPUT +template::value, int>::type> #endif -Vector::projectedOntoNormalized(const Vector& line) const { +inline Vector Vector::projectedOntoNormalized(const Vector& line) const { CORRADE_DEBUG_ASSERT(line.isNormalized(), "Math::Vector::projectedOntoNormalized(): line" << line << "is not normalized", {}); return line*Math::dot(*this, line); diff --git a/src/Magnum/Math/Vector2.h b/src/Magnum/Math/Vector2.h index caf359a7b..78285dd38 100644 --- a/src/Magnum/Math/Vector2.h +++ b/src/Magnum/Math/Vector2.h @@ -220,12 +220,10 @@ template class Vector2: public Vector<2, T> { * @ref Vector::operator-() const "operator-() const" */ /* For some reason @ref operator-() const doesn't work since 1.8.17 */ - #ifdef DOXYGEN_GENERATING_OUTPUT - Vector2 - #else - template typename std::enable_if::value, Vector2>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - perpendicular() const { return {-y(), x()}; } + Vector2 perpendicular() const { return {-y(), x()}; } /** * @brief Aspect ratio @@ -235,12 +233,10 @@ template class Vector2: public Vector<2, T> { * a = \frac{v_x}{v_y} * @f] */ - #ifdef DOXYGEN_GENERATING_OUTPUT - T - #else - template typename std::enable_if::value, T>::type + #ifndef DOXYGEN_GENERATING_OUTPUT + template::value, int>::type = 0> #endif - aspectRatio() const { return x()/y(); } + T aspectRatio() const { return x()/y(); } MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(2, Vector2) diff --git a/src/Magnum/MeshTools/Interleave.h b/src/Magnum/MeshTools/Interleave.h index 91300d966..f560c2e81 100644 --- a/src/Magnum/MeshTools/Interleave.h +++ b/src/Magnum/MeshTools/Interleave.h @@ -50,7 +50,7 @@ namespace Implementation { resolution (the functions would otherwise need to be de-inlined to break cyclic dependencies) */ struct AttributeCount { - template typename std::enable_if::value, std::size_t>::type operator()(const T& first, const U&... + template::value, int>::type = 0> std::size_t operator()(const T& first, const U&... #ifndef CORRADE_NO_ASSERT next #endif @@ -90,7 +90,7 @@ template constexpr std::size_t typeSize() { /* Stride, taking gaps into account. It must be in the structure, same reason as above */ struct Stride { - template typename std::enable_if::value, std::size_t>::type operator()(const T&, const U&... next) const { + template::value, int>::type = 0> std::size_t operator()(const T&, const U&... next) const { return typeSize() + Stride{}(next...); } template std::size_t operator()(std::size_t gap, const T&... next) const { @@ -100,7 +100,7 @@ struct Stride { }; /* Copy data to the buffer */ -template typename std::enable_if::value, std::size_t>::type writeOneInterleaved(std::size_t stride, char* startingOffset, const T& attributeList) { +template::value, int>::type = 0> std::size_t writeOneInterleaved(std::size_t stride, char* startingOffset, const T& attributeList) { auto it = attributeList.begin(); for(std::size_t i = 0; i != attributeList.size(); ++i, ++it) std::memcpy(startingOffset + i*stride, reinterpret_cast(&*it), typeSize()); @@ -150,7 +150,7 @@ would be 21 bytes, causing possible performance loss. template::value>::type + , typename std::enable_if::value, int>::type = 0 #endif > Containers::Array interleave(const T& first, const U&... next) { diff --git a/src/Magnum/Platform/ScreenedApplication.h b/src/Magnum/Platform/ScreenedApplication.h index 661fac76c..aa82f12bb 100644 --- a/src/Magnum/Platform/ScreenedApplication.h +++ b/src/Magnum/Platform/ScreenedApplication.h @@ -295,8 +295,8 @@ template class BasicScreenedApplication: CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") const BasicScreenedApplication& operator*() const { return *this; } CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") operator BasicScreenedApplication*() { return this; } CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") operator const BasicScreenedApplication*() const { return this; } - template, T>::value>::type> CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") operator T*() { return static_cast(this); } - template, T>::value>::type> CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") operator const T*() const { return static_cast(this); } + template, T>::value, int>::type = 0> CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") operator T*() { return static_cast(this); } + template, T>::value, int>::type = 0> CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now") operator const T*() const { return static_cast(this); } CORRADE_DEPRECATED("Platform::Screen::application() returns a reference now, use hasApplication() instead") bool operator!() const { return false; } #endif diff --git a/src/Magnum/SceneGraph/AbstractFeature.h b/src/Magnum/SceneGraph/AbstractFeature.h index 03f9a6170..1c4fe4d49 100644 --- a/src/Magnum/SceneGraph/AbstractFeature.h +++ b/src/Magnum/SceneGraph/AbstractFeature.h @@ -161,7 +161,7 @@ template class AbstractFeature /* This is here to avoid ambiguity with deleted copy constructor when passing `*this` from class subclassing both AbstractFeature and AbstractObject */ - template, U>::value>::type> AbstractFeature(U& object): AbstractFeature(static_cast&>(object)) {} + template, U>::value, int>::type = 0> AbstractFeature(U& object): AbstractFeature(static_cast&>(object)) {} #endif virtual ~AbstractFeature() = 0; diff --git a/src/Magnum/SceneGraph/Animable.h b/src/Magnum/SceneGraph/Animable.h index f506cd44a..6ddbd5586 100644 --- a/src/Magnum/SceneGraph/Animable.h +++ b/src/Magnum/SceneGraph/Animable.h @@ -139,7 +139,7 @@ template class Animable: public AbstractGrouped #ifndef DOXYGEN_GENERATING_OUTPUT /* This is here to avoid ambiguity with deleted copy constructor when passing `*this` from class subclassing both Animable and AbstractObject */ - template, U>::value>::type> explicit Animable(U& object): Animable{static_cast&>(object)} {} + template, U>::value, int>::type = 0> explicit Animable(U& object): Animable{static_cast&>(object)} {} #endif ~Animable(); diff --git a/src/Magnum/SceneGraph/Camera.h b/src/Magnum/SceneGraph/Camera.h index dc678fb72..9fec34d71 100644 --- a/src/Magnum/SceneGraph/Camera.h +++ b/src/Magnum/SceneGraph/Camera.h @@ -100,7 +100,7 @@ template class Camera: public AbstractFeature, U>::value>::type> explicit Camera(U& object): Camera{static_cast&>(object)} {} + template, U>::value, int>::type = 0> explicit Camera(U& object): Camera{static_cast&>(object)} {} #endif ~Camera(); diff --git a/src/Magnum/SceneGraph/Drawable.h b/src/Magnum/SceneGraph/Drawable.h index 8fbcf315e..16898f826 100644 --- a/src/Magnum/SceneGraph/Drawable.h +++ b/src/Magnum/SceneGraph/Drawable.h @@ -162,7 +162,7 @@ template class Drawable: public AbstractGrouped #ifndef DOXYGEN_GENERATING_OUTPUT /* This is here to avoid ambiguity with deleted copy constructor when passing `*this` from class subclassing both Drawable and AbstractObject */ - template, U>::value>::type> explicit Drawable(U& object): Drawable{static_cast&>(object)} {} + template, U>::value, int>::type = 0> explicit Drawable(U& object): Drawable{static_cast&>(object)} {} #endif /** diff --git a/src/Magnum/Trade/MaterialData.h b/src/Magnum/Trade/MaterialData.h index dfbab0c34..75c1ef2b5 100644 --- a/src/Magnum/Trade/MaterialData.h +++ b/src/Magnum/Trade/MaterialData.h @@ -1408,7 +1408,7 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { */ template::value && !std::is_convertible>::value>::type + , typename std::enable_if::value && !std::is_convertible>::value, int>::type = 0 #endif > constexpr /*implicit*/ MaterialAttributeData(Containers::StringView name, const T& value) noexcept; @@ -1447,7 +1447,7 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { #ifndef DOXYGEN_GENERATING_OUTPUT /* "Sure can't be constexpr" overloads to avoid going through the *insane* overload puzzle when not needed */ - template::value && !std::is_convertible>::value>::type> /*implicit*/ MaterialAttributeData(const char* name, const T& value) noexcept: MaterialAttributeData{name, Implementation::MaterialAttributeTypeFor::type(), sizeof(T), &value} {} + template::value && !std::is_convertible>::value, int>::type = 0> /*implicit*/ MaterialAttributeData(const char* name, const T& value) noexcept: MaterialAttributeData{name, Implementation::MaterialAttributeTypeFor::type(), sizeof(T), &value} {} /*implicit*/ MaterialAttributeData(const char* name, Containers::StringView value) noexcept: MaterialAttributeData{name, MaterialAttributeType::String, 0, &value} {} #endif @@ -1466,7 +1466,7 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { */ template::value>::type + , typename std::enable_if::value, int>::type = 0 #endif > /*implicit*/ MaterialAttributeData(MaterialAttribute name, const T& value) noexcept: MaterialAttributeData{name, Implementation::MaterialAttributeTypeFor::type(), &value} {} @@ -1677,18 +1677,18 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { constexpr explicit Storage(Containers::StringView name, Containers::StringView value) noexcept: s{MaterialAttributeType::String, name, value} {} - template constexpr explicit Storage(typename std::enable_if::type type, Containers::StringView name, const T& value) noexcept: _1{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::value, MaterialAttributeType>::type type, Containers::StringView name, const T& value) noexcept: _4{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::value && !std::is_pointer::value, MaterialAttributeType>::type type, Containers::StringView name, const T& value) noexcept: _8{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::value && !std::is_pointer::value, MaterialAttributeType>::type type, Containers::StringView name, const T& value) noexcept: _8v{type, name, value} {} + template::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _1{type, name, value} {} + template::value, int>::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _4{type, name, value} {} + template::value && !std::is_pointer::value, int>::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _8{type, name, value} {} + template::value && !std::is_pointer::value, int>::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _8v{type, name, value} {} constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const void* value) noexcept: p{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::type type, Containers::StringView name, const T& value) noexcept: _12{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::value, MaterialAttributeType>::type type, Containers::StringView name, const T& value) noexcept: _16{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::value, MaterialAttributeType>::type type, Containers::StringView name, const T& value) noexcept: _16m{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::type type, Containers::StringView name, const T& value) noexcept: _24{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::type type, Containers::StringView name, const T& value) noexcept: _32{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::type type, Containers::StringView name, const T& value) noexcept: _36{type, name, value} {} - template constexpr explicit Storage(typename std::enable_if::type type, Containers::StringView name, const T& value) noexcept: _48{type, name, value} {} + template::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _12{type, name, value} {} + template::value, int>::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _16{type, name, value} {} + template::value, int>::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _16m{type, name, value} {} + template::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _24{type, name, value} {} + template::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _32{type, name, value} {} + template::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _36{type, name, value} {} + template::type = 0> constexpr explicit Storage(MaterialAttributeType type, Containers::StringView name, const T& value) noexcept: _48{type, name, value} {} MaterialAttributeType type; char data[Implementation::MaterialAttributeDataSize]; @@ -3563,7 +3563,7 @@ namespace Implementation { /* The 2 extra bytes are for a null byte after the name and a type */ template::value && !std::is_convertible>::value, int>::type #endif > constexpr MaterialAttributeData::MaterialAttributeData(const Containers::StringView name, const T& value) noexcept: _data{Implementation::MaterialAttributeTypeFor::type(), ( diff --git a/src/Magnum/Trade/MeshData.h b/src/Magnum/Trade/MeshData.h index 72a2f8f3d..ffb533ead 100644 --- a/src/Magnum/Trade/MeshData.h +++ b/src/Magnum/Trade/MeshData.h @@ -313,7 +313,7 @@ class MAGNUM_TRADE_EXPORT MeshIndexData { * @ref MeshIndexData(std::nullptr_t) constructor. */ #ifndef DOXYGEN_GENERATING_OUTPUT - template>::value>::type> explicit MeshIndexData(MeshIndexType type, T&& data) noexcept; + template>::value, int>::type = 0> explicit MeshIndexData(MeshIndexType type, T&& data) noexcept; #else explicit MeshIndexData(MeshIndexType type, Containers::ArrayView data) noexcept; #endif @@ -523,7 +523,7 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData { offset-only constructor (where 0 passed to offset would match with std::nullptr_t). 0 as null pointer constant was deprecated in C++11 already, WHY IS THIS STILL A PROBLEM?! */ - template::value && !std::is_convertible::value>::type> explicit MeshAttributeData(MeshAttribute name, VertexFormat format, U, UnsignedShort arraySize = 0, Int morphTargetId = -1) noexcept: MeshAttributeData{nullptr, name, format, nullptr, arraySize, morphTargetId} {} + template::value && !std::is_convertible::value, int>::type = 0> explicit MeshAttributeData(MeshAttribute name, VertexFormat format, U, UnsignedShort arraySize = 0, Int morphTargetId = -1) noexcept: MeshAttributeData{nullptr, name, format, nullptr, arraySize, morphTargetId} {} #endif /** @@ -1770,7 +1770,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * @ref isVertexFormatImplementationSpecific(), * @ref attributeArraySize() */ - template::value>::type> Containers::StridedArrayView1D attribute(UnsignedInt id) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D attribute(UnsignedInt id) const; /** * @brief Data for given array attribute in a concrete type @@ -1782,7 +1786,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * @ref attributeArraySize() for given attribute. For non-array * attributes the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> attribute(UnsignedInt id) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> attribute(UnsignedInt id) const; /** * @brief Mutable data for given attribute in a concrete type @@ -1791,7 +1799,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * Expects that the mesh is mutable. * @see @ref vertexDataFlags() */ - template::value>::type> Containers::StridedArrayView1D mutableAttribute(UnsignedInt id); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D mutableAttribute(UnsignedInt id); /** * @brief Mutable data for given array attribute in a concrete type @@ -1803,7 +1815,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * @ref attributeArraySize() for given attribute. For non-array * attributes the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> mutableAttribute(UnsignedInt id); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> mutableAttribute(UnsignedInt id); /** * @brief Data for given named attribute @@ -1853,7 +1869,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * @ref mutableAttribute(MeshAttribute, UnsignedInt, Int), * @ref isVertexFormatImplementationSpecific() */ - template::value>::type> Containers::StridedArrayView1D attribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D attribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const; /** * @brief Data for given named array attribute in a concrete type @@ -1865,7 +1885,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * @ref attributeArraySize() for given attribute. For non-array * attributes the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> attribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> attribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1) const; /** * @brief Mutable data for given named attribute in a concrete type @@ -1874,7 +1898,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * returns a mutable view. Expects that the mesh is mutable. * @see @ref vertexDataFlags() */ - template::value>::type> Containers::StridedArrayView1D mutableAttribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D mutableAttribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1); /** * @brief Mutable data for given named array attribute in a concrete type @@ -1886,7 +1914,11 @@ class MAGNUM_TRADE_EXPORT MeshData { * @ref attributeArraySize() for given attribute. For non-array * attributes the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> mutableAttribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> mutableAttribute(MeshAttribute name, UnsignedInt id = 0, Int morphTargetId = -1); /** * @brief Indices as 32-bit integers @@ -2330,7 +2362,7 @@ namespace Implementation { } #ifndef DOXYGEN_GENERATING_OUTPUT -template MeshIndexData::MeshIndexData(const MeshIndexType type, T&& data) noexcept: _type{type} { +template>::value, int>::type> MeshIndexData::MeshIndexData(const MeshIndexType type, T&& data) noexcept: _type{type} { const Containers::ArrayView erased = data; CORRADE_ASSERT(!isMeshIndexTypeImplementationSpecific(type), "Trade::MeshIndexData: can't create index data from a contiguous view and an implementation-specific type" << Debug::hex << meshIndexTypeUnwrap(type) << Debug::nospace << ", pass a strided view instead", ); @@ -2737,7 +2769,8 @@ template bool MeshData::checkVertexFormatCompatibility(const MeshAttrib } #endif -template Containers::StridedArrayView1D MeshData::attribute(const UnsignedInt id) const { +#ifndef DOXYGEN_GENERATING_OUTPUT +template::value, int>::type> Containers::StridedArrayView1D MeshData::attribute(const UnsignedInt id) const { Containers::StridedArrayView2D data = attribute(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -2748,7 +2781,7 @@ template Containers::StridedArrayView1D MeshData::attri return Containers::arrayCast<1, const T>(data); } -template Containers::StridedArrayView2D::type> MeshData::attribute(const UnsignedInt id) const { +template::value, int>::type> Containers::StridedArrayView2D::type> MeshData::attribute(const UnsignedInt id) const { Containers::StridedArrayView2D data = attribute(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -2759,7 +2792,7 @@ template Containers::StridedArrayView2D::type>(data); } -template Containers::StridedArrayView1D MeshData::mutableAttribute(const UnsignedInt id) { +template::value, int>::type> Containers::StridedArrayView1D MeshData::mutableAttribute(const UnsignedInt id) { Containers::StridedArrayView2D data = mutableAttribute(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -2770,7 +2803,7 @@ template Containers::StridedArrayView1D MeshData::mutableAttr return Containers::arrayCast<1, T>(data); } -template Containers::StridedArrayView2D::type> MeshData::mutableAttribute(const UnsignedInt id) { +template::value, int>::type> Containers::StridedArrayView2D::type> MeshData::mutableAttribute(const UnsignedInt id) { Containers::StridedArrayView2D data = mutableAttribute(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -2781,7 +2814,7 @@ template Containers::StridedArrayView2D::type>(data); } -template Containers::StridedArrayView1D MeshData::attribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) const { +template::value, int>::type> Containers::StridedArrayView1D MeshData::attribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) const { const UnsignedInt attributeId = findAttributeIdInternal(name, id, morphTargetId); #ifndef CORRADE_NO_ASSERT if(morphTargetId == -1) CORRADE_ASSERT(attributeId != ~UnsignedInt{}, @@ -2798,7 +2831,7 @@ template Containers::StridedArrayView1D MeshData::attri return Containers::arrayCast<1, const T>(data); } -template Containers::StridedArrayView2D::type> MeshData::attribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) const { +template::value, int>::type> Containers::StridedArrayView2D::type> MeshData::attribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) const { const UnsignedInt attributeId = findAttributeIdInternal(name, id, morphTargetId); #ifndef CORRADE_NO_ASSERT if(morphTargetId == -1) CORRADE_ASSERT(attributeId != ~UnsignedInt{}, @@ -2815,7 +2848,7 @@ template Containers::StridedArrayView2D::type>(data); } -template Containers::StridedArrayView1D MeshData::mutableAttribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) { +template::value, int>::type> Containers::StridedArrayView1D MeshData::mutableAttribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) { const UnsignedInt attributeId = findAttributeIdInternal(name, id, morphTargetId); #ifndef CORRADE_NO_ASSERT if(morphTargetId == -1) CORRADE_ASSERT(attributeId != ~UnsignedInt{}, @@ -2833,7 +2866,7 @@ template Containers::StridedArrayView1D MeshData::mutableAttr return Containers::arrayCast<1, T>(data); } -template Containers::StridedArrayView2D::type> MeshData::mutableAttribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) { +template::value, int>::type> Containers::StridedArrayView2D::type> MeshData::mutableAttribute(const MeshAttribute name, const UnsignedInt id, const Int morphTargetId) { const UnsignedInt attributeId = findAttributeIdInternal(name, id, morphTargetId); #ifndef CORRADE_NO_ASSERT if(morphTargetId == -1) CORRADE_ASSERT(attributeId != ~UnsignedInt{}, @@ -2850,6 +2883,7 @@ template Containers::StridedArrayView2D::type>(data); } +#endif }} diff --git a/src/Magnum/Trade/SceneData.h b/src/Magnum/Trade/SceneData.h index 54310f4af..cc6c6f5f1 100644 --- a/src/Magnum/Trade/SceneData.h +++ b/src/Magnum/Trade/SceneData.h @@ -2528,7 +2528,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * @see @ref field(SceneField) const, @ref mutableField(UnsignedInt), * @ref fieldArraySize() */ - template::value>::type> Containers::StridedArrayView1D field(UnsignedInt id) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D field(UnsignedInt id) const; /** * @brief Data for given array field in a concrete type @@ -2541,7 +2545,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * @ref fieldArraySize(UnsignedInt) const for given field. For * non-array fields the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> field(UnsignedInt id) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> field(UnsignedInt id) const; /** * @brief Mutable data for given field in a concrete type @@ -2551,7 +2559,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * Expects that the scene is mutable. * @see @ref dataFlags() */ - template::value>::type> Containers::StridedArrayView1D mutableField(UnsignedInt id); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D mutableField(UnsignedInt id); /** * @brief Mutable data for given array field in a concrete type @@ -2564,7 +2576,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * @ref fieldArraySize(UnsignedInt) const for given field. For * non-array fields the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> mutableField(UnsignedInt id); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> mutableField(UnsignedInt id); /** * @brief Data for given named field @@ -2608,7 +2624,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * @see @ref hasField(), @ref field(UnsignedInt) const, * @ref mutableField(SceneField) */ - template::value>::type> Containers::StridedArrayView1D field(SceneField name) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D field(SceneField name) const; /** * @brief Data for given named array field in a concrete type @@ -2621,7 +2641,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * @ref fieldArraySize(SceneField) const for given field. For non-array * fields the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> field(SceneField name) const; + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> field(SceneField name) const; /** * @brief Mutable data for given named field @@ -2631,7 +2655,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * Expects that the scene is mutable. * @see @ref dataFlags() */ - template::value>::type> Containers::StridedArrayView1D mutableField(SceneField name); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView1D mutableField(SceneField name); /** * @brief Mutable data for given named array field in a concrete type @@ -2644,7 +2672,11 @@ class MAGNUM_TRADE_EXPORT SceneData { * @ref fieldArraySize(SceneField) const for given field. For non-array * fields the second dimension has a size of @cpp 1 @ce. */ - template::value>::type> Containers::StridedArrayView2D::type> mutableField(SceneField name); + template::value, int>::type = 0 + #endif + > Containers::StridedArrayView2D::type> mutableField(SceneField name); /** * @brief Contents of given bit field @@ -4265,7 +4297,8 @@ template bool SceneData::checkFieldTypeCompatibility(const SceneFieldDa } #endif -template Containers::StridedArrayView1D SceneData::field(const UnsignedInt id) const { +#ifndef DOXYGEN_GENERATING_OUTPUT +template::value, int>::type> Containers::StridedArrayView1D SceneData::field(const UnsignedInt id) const { Containers::StridedArrayView2D data = field(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -4276,7 +4309,7 @@ template Containers::StridedArrayView1D SceneData::fiel return Containers::arrayCast<1, const T>(data); } -template Containers::StridedArrayView2D::type> SceneData::field(const UnsignedInt id) const { +template::value, int>::type> Containers::StridedArrayView2D::type> SceneData::field(const UnsignedInt id) const { Containers::StridedArrayView2D data = field(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -4287,7 +4320,7 @@ template Containers::StridedArrayView2D::type>(data); } -template Containers::StridedArrayView1D SceneData::mutableField(const UnsignedInt id) { +template::value, int>::type> Containers::StridedArrayView1D SceneData::mutableField(const UnsignedInt id) { Containers::StridedArrayView2D data = mutableField(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -4298,7 +4331,7 @@ template Containers::StridedArrayView1D SceneData::mutableFie return Containers::arrayCast<1, T>(data); } -template Containers::StridedArrayView2D::type> SceneData::mutableField(const UnsignedInt id) { +template::value, int>::type> Containers::StridedArrayView2D::type> SceneData::mutableField(const UnsignedInt id) { Containers::StridedArrayView2D data = mutableField(id); #ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */ if(!data.stride()[1]) return {}; @@ -4309,7 +4342,7 @@ template Containers::StridedArrayView2D::type>(data); } -template Containers::StridedArrayView1D SceneData::field(const SceneField name) const { +template::value, int>::type> Containers::StridedArrayView1D SceneData::field(const SceneField name) const { const UnsignedInt fieldId = findFieldIdInternal(name); CORRADE_ASSERT(fieldId != ~UnsignedInt{}, "Trade::SceneData::field(): field" << name << "not found", {}); @@ -4323,7 +4356,7 @@ template Containers::StridedArrayView1D SceneData::fiel return Containers::arrayCast<1, const T>(data); } -template Containers::StridedArrayView2D::type> SceneData::field(const SceneField name) const { +template::value, int>::type> Containers::StridedArrayView2D::type> SceneData::field(const SceneField name) const { const UnsignedInt fieldId = findFieldIdInternal(name); CORRADE_ASSERT(fieldId != ~UnsignedInt{}, "Trade::SceneData::field(): field" << name << "not found", {}); @@ -4337,7 +4370,7 @@ template Containers::StridedArrayView2D::type>(data); } -template Containers::StridedArrayView1D SceneData::mutableField(const SceneField name) { +template::value, int>::type> Containers::StridedArrayView1D SceneData::mutableField(const SceneField name) { const UnsignedInt fieldId = findFieldIdInternal(name); CORRADE_ASSERT(fieldId != ~UnsignedInt{}, "Trade::SceneData::mutableField(): field" << name << "not found", {}); @@ -4351,7 +4384,7 @@ template Containers::StridedArrayView1D SceneData::mutableFie return Containers::arrayCast<1, T>(data); } -template Containers::StridedArrayView2D::type> SceneData::mutableField(const SceneField name) { +template::value, int>::type> Containers::StridedArrayView2D::type> SceneData::mutableField(const SceneField name) { const UnsignedInt fieldId = findFieldIdInternal(name); CORRADE_ASSERT(fieldId != ~UnsignedInt{}, "Trade::SceneData::mutableField(): field" << name << "not found", {}); @@ -4364,6 +4397,7 @@ template Containers::StridedArrayView2D::type>(data); } +#endif }} diff --git a/src/Magnum/Vk/Extensions.h b/src/Magnum/Vk/Extensions.h index d8fee7157..61f1c8e90 100644 --- a/src/Magnum/Vk/Extensions.h +++ b/src/Magnum/Vk/Extensions.h @@ -214,7 +214,11 @@ class MAGNUM_VK_EXPORT InstanceExtension { constexpr Containers::StringView string() const { return _string; } /** @brief Construct from a compile-time instance extension */ - template::value>::type> constexpr /*implicit*/ InstanceExtension(const E&): _index{E::InstanceIndex}, _requiredVersion{E::requiredVersion()}, _coreVersion{E::coreVersion()}, _string{E::string()} {} + template::value, int>::type = 0 + #endif + > constexpr /*implicit*/ InstanceExtension(const E&): _index{E::InstanceIndex}, _requiredVersion{E::requiredVersion()}, _coreVersion{E::coreVersion()}, _string{E::string()} {} private: std::size_t _index; @@ -253,7 +257,11 @@ class MAGNUM_VK_EXPORT Extension { /** @brief Construct from a compile-time device extension */ /** @todo prohibit conversion from GL/AL extensions also? */ - template::value>::type> constexpr /*implicit*/ Extension(const E&): _index{E::Index}, _requiredVersion{E::requiredVersion()}, _coreVersion{E::coreVersion()}, _string{E::string()} {} + template::value, int>::type = 0 + #endif + > constexpr /*implicit*/ Extension(const E&): _index{E::Index}, _requiredVersion{E::requiredVersion()}, _coreVersion{E::coreVersion()}, _string{E::string()} {} private: std::size_t _index; diff --git a/src/Magnum/Vk/Implementation/structureHelpers.h b/src/Magnum/Vk/Implementation/structureHelpers.h index d11ca78b1..0f9c97ac1 100644 --- a/src/Magnum/Vk/Implementation/structureHelpers.h +++ b/src/Magnum/Vk/Implementation/structureHelpers.h @@ -101,7 +101,7 @@ template inline const void** structureFind(const void*& next, const T& class AnyStructure { public: - template::value>::type> /*implicit*/ AnyStructure(const T& structure): _structure{reinterpret_cast(&structure)} {} + template::value, int>::type = 0> /*implicit*/ AnyStructure(const T& structure): _structure{reinterpret_cast(&structure)} {} /*implicit*/ operator const VkBaseOutStructure&() const { return *_structure; }