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; }