From 5a1f43f20bc93141b3624344084b3d8f6336c451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 17 Dec 2020 18:05:09 +0100 Subject: [PATCH] Switch to the new & optimized GenerateSequence from Corrade. This should help slightly with compiler memory usage, on GCC 10 the huge Trade::MaterialData test used "only" 309 instead of 318 MB after this change. --- src/Magnum/Array.h | 11 +++++--- src/Magnum/Math/Bezier.h | 12 ++++----- src/Magnum/Math/BoolVector.h | 18 +++---------- src/Magnum/Math/Matrix.h | 14 +++++----- src/Magnum/Math/RectangularMatrix.h | 40 ++++++++++++++--------------- src/Magnum/Math/Swizzle.h | 4 +-- src/Magnum/Math/Vector.h | 16 ++++++------ src/Magnum/Trade/MaterialData.h | 8 +++--- 8 files changed, 58 insertions(+), 65 deletions(-) diff --git a/src/Magnum/Array.h b/src/Magnum/Array.h index d5863bae8..4c3d15687 100644 --- a/src/Magnum/Array.h +++ b/src/Magnum/Array.h @@ -30,12 +30,17 @@ */ #include +#include +#include #include "Magnum/Magnum.h" -#include "Magnum/Math/BoolVector.h" /* for Math::Implementation::Sequence */ namespace Magnum { +namespace Implementation { + template constexpr T repeat(T value, std::size_t) { return value; } +} + /** @brief Array @tparam dimensions Dimension count @@ -77,7 +82,7 @@ template class Array { constexpr /*implicit*/ Array(T value); #else template::value && dimensions != 1, T>::type> - constexpr /*implicit*/ Array(U value): Array(typename Math::Implementation::GenerateSequence::Type(), value) {} + constexpr /*implicit*/ Array(U value): Array(typename Containers::Implementation::GenerateSequence::Type{}, value) {} #endif /** @brief Equality */ @@ -112,7 +117,7 @@ template class Array { private: /* Implementation for Array::Array(U) */ - template constexpr explicit Array(Math::Implementation::Sequence, T value): _data{Math::Implementation::repeat(value, sequence)...} {} + template constexpr explicit Array(Containers::Implementation::Sequence, T value): _data{Implementation::repeat(value, sequence)...} {} }; /** diff --git a/src/Magnum/Math/Bezier.h b/src/Magnum/Math/Bezier.h index c63039c01..d37886d3b 100644 --- a/src/Magnum/Math/Bezier.h +++ b/src/Magnum/Math/Bezier.h @@ -102,17 +102,17 @@ template class Bezier { * * Equivalent to @ref Bezier(ZeroInitT). */ - constexpr /*implicit*/ Bezier() noexcept: Bezier{typename Implementation::GenerateSequence::Type{}, ZeroInit} {} + constexpr /*implicit*/ Bezier() noexcept: Bezier{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, ZeroInit} {} /** * @brief Construct a zero curve * * All control points are zero vectors. */ - constexpr explicit Bezier(ZeroInitT) noexcept: Bezier{typename Implementation::GenerateSequence::Type{}, ZeroInit} {} + constexpr explicit Bezier(ZeroInitT) noexcept: Bezier{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, ZeroInit} {} /** @brief Construct Bézier without initializing the contents */ - explicit Bezier(Magnum::NoInitT) noexcept: Bezier{typename Implementation::GenerateSequence::Type{}, Magnum::NoInit} {} + explicit Bezier(Magnum::NoInitT) noexcept: Bezier{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, Magnum::NoInit} {} /** @brief Construct Bézier curve with given array of control points */ template constexpr /*implicit*/ Bezier(const Vector& first, U... next) noexcept: _data{first, next...} { @@ -125,7 +125,7 @@ template class Bezier { * Performs only default casting on the values, no rounding or * anything else. */ - template constexpr explicit Bezier(const Bezier& other) noexcept: Bezier{typename Implementation::GenerateSequence::Type(), other} {} + template constexpr explicit Bezier(const Bezier& other) noexcept: Bezier{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, other} {} /** @brief Construct Bézier curve from external representation */ template::from(std::declval()))> constexpr explicit Bezier(const U& other) noexcept: Bezier{Implementation::BezierConverter::from(other)} {} @@ -198,11 +198,11 @@ template class Bezier { private: /* Implementation for Bezier::Bezier(const Bezier&) */ - template constexpr explicit Bezier(Implementation::Sequence, const Bezier& other) noexcept: _data{Vector(other._data[sequence])...} {} + template constexpr explicit Bezier(Corrade::Containers::Implementation::Sequence, const Bezier& other) noexcept: _data{Vector(other._data[sequence])...} {} /* Implementation for Bezier::Bezier(ZeroInitT) and Bezier::Bezier(NoInitT) */ /* MSVC 2015 can't handle {} here */ - template constexpr explicit Bezier(Implementation::Sequence, U): _data{Vector((static_cast(sequence), U{typename U::Init{}}))...} {} + template constexpr explicit Bezier(Corrade::Containers::Implementation::Sequence, U): _data{Vector((static_cast(sequence), U{typename U::Init{}}))...} {} /* Calculates and returns all intermediate points generated when using De Casteljau's algorithm */ void calculateIntermediatePoints(Bezier(&iPoints)[order + 1], Float t) const { diff --git a/src/Magnum/Math/BoolVector.h b/src/Magnum/Math/BoolVector.h index e967a152e..30daebeb7 100644 --- a/src/Magnum/Math/BoolVector.h +++ b/src/Magnum/Math/BoolVector.h @@ -30,6 +30,7 @@ */ #include +#include #ifndef CORRADE_NO_DEBUG #include #endif @@ -43,19 +44,6 @@ namespace Magnum { namespace Math { namespace Implementation { template struct BoolVectorConverter; - /** @todo C++14: use std::make_index_sequence and std::integer_sequence */ - template struct Sequence {}; - - #ifndef DOXYGEN_GENERATING_OUTPUT - /* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */ - template struct GenerateSequence: - GenerateSequence {}; - - template struct GenerateSequence<0, sequence...> { - typedef Sequence Type; - }; - #endif - template constexpr T repeat(T value, std::size_t) { return value; } } @@ -129,7 +117,7 @@ template class BoolVector { #ifdef DOXYGEN_GENERATING_OUTPUT explicit BoolVector(T value) noexcept; #else - template::value && size != 1, bool>::type> constexpr explicit BoolVector(T value) noexcept: BoolVector(typename Implementation::GenerateSequence::Type(), value ? FullSegmentMask : 0) {} + template::value && size != 1, bool>::type> constexpr explicit BoolVector(T value) noexcept: BoolVector(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, value ? FullSegmentMask : 0) {} #endif /** @brief Construct a boolean vector from external representation */ @@ -305,7 +293,7 @@ template class BoolVector { }; /* Implementation for Vector::Vector(U) */ - template constexpr explicit BoolVector(Implementation::Sequence, UnsignedByte value): _data{Implementation::repeat(value, sequence)...} {} + template constexpr explicit BoolVector(Corrade::Containers::Implementation::Sequence, UnsignedByte value): _data{Implementation::repeat(value, sequence)...} {} UnsignedByte _data[(size-1)/8+1]; }; diff --git a/src/Magnum/Math/Matrix.h b/src/Magnum/Math/Matrix.h index 4cb0d83f1..c0ff9c4aa 100644 --- a/src/Magnum/Math/Matrix.h +++ b/src/Magnum/Math/Matrix.h @@ -36,13 +36,13 @@ namespace Magnum { namespace Math { namespace Implementation { template struct MatrixDeterminant; - template constexpr Vector valueOrIdentityVector(Sequence, const RectangularMatrix& other) { + template constexpr Vector valueOrIdentityVector(Corrade::Containers::Implementation::Sequence, const RectangularMatrix& other) { return {(col < otherSize && row < otherSize ? other[col][row] : col == row ? T{1} : T{0})...}; } template constexpr Vector valueOrIdentityVector(const RectangularMatrix& other) { - return valueOrIdentityVector(typename Implementation::GenerateSequence::Type(), other); + return valueOrIdentityVector(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, other); } } @@ -72,7 +72,7 @@ template class Matrix: public RectangularMatrix{typename Implementation::GenerateSequence::Type(), Vector(T(1))} {} + constexpr /*implicit*/ Matrix() noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, Vector(T(1))} {} /** * @brief Construct an identity matrix @@ -80,7 +80,7 @@ template class Matrix: public RectangularMatrix{typename Implementation::GenerateSequence::Type(), Vector(value)} {} + constexpr explicit Matrix(IdentityInitT, T value = T(1)) noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, Vector(value)} {} /** @copydoc RectangularMatrix::RectangularMatrix(ZeroInitT) */ constexpr explicit Matrix(ZeroInitT) noexcept: RectangularMatrix{ZeroInit} {} @@ -92,7 +92,7 @@ template class Matrix: public RectangularMatrix constexpr /*implicit*/ Matrix(const Vector& first, const U&... next) noexcept: RectangularMatrix(first, next...) {} /** @brief Construct with one value for all elements */ - constexpr explicit Matrix(T value) noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type(), value} {} + constexpr explicit Matrix(T value) noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, value} {} /** * @brief Construct from a matrix of adifferent type @@ -114,7 +114,7 @@ template class Matrix: public RectangularMatrix constexpr explicit Matrix(const RectangularMatrix& other) noexcept: Matrix{typename Implementation::GenerateSequence::Type(), other} {} + template constexpr explicit Matrix(const RectangularMatrix& other) noexcept: Matrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, other} {} /** @brief Copy constructor */ constexpr /*implicit*/ Matrix(const RectangularMatrix& other) noexcept: RectangularMatrix(other) {} @@ -302,7 +302,7 @@ template class Matrix: public RectangularMatrix; /* Implementation for RectangularMatrix::RectangularMatrix(const RectangularMatrix&) */ - template constexpr explicit Matrix(Implementation::Sequence, const RectangularMatrix& other) noexcept: RectangularMatrix{Implementation::valueOrIdentityVector(other)...} {} + template constexpr explicit Matrix(Corrade::Containers::Implementation::Sequence, const RectangularMatrix& other) noexcept: RectangularMatrix{Implementation::valueOrIdentityVector(other)...} {} }; /** diff --git a/src/Magnum/Math/RectangularMatrix.h b/src/Magnum/Math/RectangularMatrix.h index b46cce8d0..5eef52954 100644 --- a/src/Magnum/Math/RectangularMatrix.h +++ b/src/Magnum/Math/RectangularMatrix.h @@ -114,7 +114,7 @@ template class RectangularMatrix { * @see @ref diagonal() */ constexpr static RectangularMatrix fromDiagonal(const Vector& diagonal) noexcept { - return RectangularMatrix(typename Implementation::GenerateSequence::Type(), diagonal); + return RectangularMatrix(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, diagonal); } /** @@ -122,13 +122,13 @@ template class RectangularMatrix { * * Equivalent to @ref RectangularMatrix(ZeroInitT). */ - constexpr /*implicit*/ RectangularMatrix() noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type{}, ZeroInit} {} + constexpr /*implicit*/ RectangularMatrix() noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, ZeroInit} {} /** @brief Construct a zero-filled matrix */ - constexpr explicit RectangularMatrix(ZeroInitT) noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type{}, ZeroInit} {} + constexpr explicit RectangularMatrix(ZeroInitT) noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, ZeroInit} {} /** @brief Construct without initializing the contents */ - explicit RectangularMatrix(Magnum::NoInitT) noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type{}, Magnum::NoInit} {} + explicit RectangularMatrix(Magnum::NoInitT) noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, Magnum::NoInit} {} /** @brief Construct from column vectors */ template constexpr /*implicit*/ RectangularMatrix(const Vector& first, const U&... next) noexcept: _data{first, next...} { @@ -136,7 +136,7 @@ template class RectangularMatrix { } /** @brief Construct with one value for all components */ - constexpr explicit RectangularMatrix(T value) noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type(), value} {} + constexpr explicit RectangularMatrix(T value) noexcept: RectangularMatrix{typename Corrade::Containers::Implementation::GenerateSequence::Type{}, value} {} /** * @brief Construct matrix from another of different type @@ -146,7 +146,7 @@ template class RectangularMatrix { * * @snippet MagnumMath.cpp RectangularMatrix-conversion */ - template constexpr explicit RectangularMatrix(const RectangularMatrix& other) noexcept: RectangularMatrix(typename Implementation::GenerateSequence::Type(), other) {} + template constexpr explicit RectangularMatrix(const RectangularMatrix& other) noexcept: RectangularMatrix(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, other) {} /** @brief Construct matrix from external representation */ template::from(std::declval()))> constexpr explicit RectangularMatrix(const U& other): RectangularMatrix(Implementation::RectangularMatrixConverter::from(other)) {} @@ -399,7 +399,7 @@ template class RectangularMatrix { * @see @ref transposed(), @ref flippedRows(), @ref Vector::flipped() */ constexpr RectangularMatrix flippedCols() const { - return flippedColsInternal(typename Implementation::GenerateSequence::Type{}); + return flippedColsInternal(typename Corrade::Containers::Implementation::GenerateSequence::Type{}); } /** @@ -409,7 +409,7 @@ template class RectangularMatrix { * @see @ref transposed(), @ref flippedCols(), @ref Vector::flipped() */ constexpr RectangularMatrix flippedRows() const { - return flippedRowsInternal(typename Implementation::GenerateSequence::Type{}); + return flippedRowsInternal(typename Corrade::Containers::Implementation::GenerateSequence::Type{}); } /** @@ -421,7 +421,7 @@ template class RectangularMatrix { /* NVCC (from CUDA) has problems compiling this function under Windows when there's a separate definition due to DiagonalSize (see https://github.com/mosra/magnum/issues/345 for details) */ - return diagonalInternal(typename Implementation::GenerateSequence::Type()); + return diagonalInternal(typename Corrade::Containers::Implementation::GenerateSequence::Type{}); } /** @@ -443,11 +443,11 @@ template class RectangularMatrix { private: #endif /* Implementation for RectangularMatrix::fromDiagonal() and Matrix(IdentityInitT, T) */ - template constexpr explicit RectangularMatrix(Implementation::Sequence, const Vector& diagonal); + template constexpr explicit RectangularMatrix(Corrade::Containers::Implementation::Sequence, const Vector& diagonal); /* Implementation for RectangularMatrix::RectangularMatrix(T) and Matrix(T) */ /* MSVC 2015 can't handle {} here */ - template constexpr explicit RectangularMatrix(Implementation::Sequence, T value) noexcept: _data{Vector((static_cast(sequence), value))...} {} + template constexpr explicit RectangularMatrix(Corrade::Containers::Implementation::Sequence, T value) noexcept: _data{Vector((static_cast(sequence), value))...} {} private: /* These two needed to access _data to speed up debug builds, @@ -456,21 +456,21 @@ template class RectangularMatrix { template friend struct Implementation::MatrixDeterminant; /* Implementation for RectangularMatrix::RectangularMatrix(const RectangularMatrix&) */ - template constexpr explicit RectangularMatrix(Implementation::Sequence, const RectangularMatrix& matrix) noexcept: _data{Vector(matrix[sequence])...} {} + template constexpr explicit RectangularMatrix(Corrade::Containers::Implementation::Sequence, const RectangularMatrix& matrix) noexcept: _data{Vector(matrix[sequence])...} {} /* Implementation for RectangularMatrix::RectangularMatrix(ZeroInitT) and RectangularMatrix::RectangularMatrix(NoInitT) */ /* MSVC 2015 can't handle {} here */ - template constexpr explicit RectangularMatrix(Implementation::Sequence, U) noexcept: _data{Vector((static_cast(sequence), U{typename U::Init{}}))...} {} + template constexpr explicit RectangularMatrix(Corrade::Containers::Implementation::Sequence, U) noexcept: _data{Vector((static_cast(sequence), U{typename U::Init{}}))...} {} - template constexpr RectangularMatrix flippedColsInternal(Implementation::Sequence) const { + template constexpr RectangularMatrix flippedColsInternal(Corrade::Containers::Implementation::Sequence) const { return {_data[cols - 1 - sequence]...}; } - template constexpr RectangularMatrix flippedRowsInternal(Implementation::Sequence) const { + template constexpr RectangularMatrix flippedRowsInternal(Corrade::Containers::Implementation::Sequence) const { return {_data[sequence].flipped()...}; } - template constexpr Vector diagonalInternal(Implementation::Sequence) const; + template constexpr Vector diagonalInternal(Corrade::Containers::Implementation::Sequence) const; Vector _data[cols]; }; @@ -713,15 +713,15 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili #endif namespace Implementation { - template constexpr Vector diagonalMatrixColumn2(Implementation::Sequence, const T& number) { + template constexpr Vector diagonalMatrixColumn2(Corrade::Containers::Implementation::Sequence, const T& number) { return {(sequence == i ? number : T(0))...}; } template constexpr Vector diagonalMatrixColumn(const T& number) { - return diagonalMatrixColumn2(typename Implementation::GenerateSequence::Type(), number); + return diagonalMatrixColumn2(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, number); } } -template template constexpr RectangularMatrix::RectangularMatrix(Implementation::Sequence, const Vector& diagonal): _data{Implementation::diagonalMatrixColumn(sequence < DiagonalSize ? diagonal[sequence] : T{})...} {} +template template constexpr RectangularMatrix::RectangularMatrix(Corrade::Containers::Implementation::Sequence, const Vector& diagonal): _data{Implementation::diagonalMatrixColumn(sequence < DiagonalSize ? diagonal[sequence] : T{})...} {} template inline Vector RectangularMatrix::row(std::size_t row) const { Vector out; @@ -776,7 +776,7 @@ template inline RectangularMatrix template constexpr auto RectangularMatrix::diagonalInternal(Implementation::Sequence) const -> Vector { +template template constexpr auto RectangularMatrix::diagonalInternal(Corrade::Containers::Implementation::Sequence) const -> Vector { return {_data[sequence][sequence]...}; } #endif diff --git a/src/Magnum/Math/Swizzle.h b/src/Magnum/Math/Swizzle.h index 531bb4996..06a0f2de2 100644 --- a/src/Magnum/Math/Swizzle.h +++ b/src/Magnum/Math/Swizzle.h @@ -90,7 +90,7 @@ namespace Implementation { template struct ScatterComponent: ScatterComponentOr {}; template struct ScatterComponent: ScatterComponentOr {}; - template constexpr T scatterComponentOr(const T& vector, const typename T::Type& value, Sequence) { + template constexpr T scatterComponentOr(const T& vector, const typename T::Type& value, Corrade::Containers::Implementation::Sequence) { return {ScatterComponent::value(vector, value)...}; } template constexpr T scatterRecursive(const T& vector, const Vector&, std::size_t) { @@ -98,7 +98,7 @@ namespace Implementation { } template constexpr T scatterRecursive(const T& vector, const Vector& values, std::size_t valueIndex) { return scatterRecursive( - scatterComponentOr(vector, values._data[valueIndex], typename GenerateSequence::Type{}), + scatterComponentOr(vector, values._data[valueIndex], typename Corrade::Containers::Implementation::GenerateSequence::Type{}), values, valueIndex + 1); } } diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 861a49664..6d9a04cf2 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -177,7 +177,7 @@ template class Vector { * @see @ref Vector4::pad(const Vector&, T, T) */ template constexpr static Vector pad(const Vector& a, T value = T()) { - return padInternal(typename Implementation::GenerateSequence::Type(), a, value); + return padInternal(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, a, value); } /** @@ -210,7 +210,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT constexpr explicit Vector(T value) noexcept; #else - template::value && size != 1, T>::type> constexpr explicit Vector(U value) noexcept: Vector(typename Implementation::GenerateSequence::Type(), value) {} + template::value && size != 1, T>::type> constexpr explicit Vector(U value) noexcept: Vector(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, value) {} #endif /** @@ -221,7 +221,7 @@ template class Vector { * * @snippet MagnumMath.cpp Vector-conversion */ - template constexpr explicit Vector(const Vector& other) noexcept: Vector(typename Implementation::GenerateSequence::Type(), other) {} + template constexpr explicit Vector(const Vector& other) noexcept: Vector(typename Corrade::Containers::Implementation::GenerateSequence::Type{}, other) {} /** @brief Construct a vector from external representation */ template::from(std::declval()))> constexpr explicit Vector(const U& other) noexcept: Vector(Implementation::VectorConverter::from(other)) {} @@ -623,7 +623,7 @@ template class Vector { * @ref RectangularMatrix::flippedRows() */ constexpr Vector flipped() const { - return flippedInternal(typename Implementation::GenerateSequence::Type{}); + return flippedInternal(typename Corrade::Containers::Implementation::GenerateSequence::Type{}); } /** @@ -692,16 +692,16 @@ template class Vector { template friend U dot(const Vector&, const Vector&); /* Implementation for Vector::Vector(const Vector&) */ - template constexpr explicit Vector(Implementation::Sequence, const Vector& vector) noexcept: _data{T(vector._data[sequence])...} {} + template constexpr explicit Vector(Corrade::Containers::Implementation::Sequence, const Vector& vector) noexcept: _data{T(vector._data[sequence])...} {} /* Implementation for Vector::Vector(U) */ - template constexpr explicit Vector(Implementation::Sequence, T value) noexcept: _data{Implementation::repeat(value, sequence)...} {} + template constexpr explicit Vector(Corrade::Containers::Implementation::Sequence, T value) noexcept: _data{Implementation::repeat(value, sequence)...} {} - template constexpr static Vector padInternal(Implementation::Sequence, const Vector& a, T value) { + template constexpr static Vector padInternal(Corrade::Containers::Implementation::Sequence, const Vector& a, T value) { return {sequence < otherSize ? a[sequence] : value...}; } - template constexpr Vector flippedInternal(Implementation::Sequence) const { + template constexpr Vector flippedInternal(Corrade::Containers::Implementation::Sequence) const { return {_data[size - 1 - sequence]...}; } }; diff --git a/src/Magnum/Trade/MaterialData.h b/src/Magnum/Trade/MaterialData.h index 13f4eed3d..93a756d4b 100644 --- a/src/Magnum/Trade/MaterialData.h +++ b/src/Magnum/Trade/MaterialData.h @@ -1266,8 +1266,8 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { right after the null-terminated string) makes them accessible in O(1) as well. */ struct StringData { - template constexpr explicit StringData(MaterialAttributeType type, Containers::StringView name, Containers::StringView value, Math::Implementation::Sequence): type{type}, nameValue{(sequence < name.size() ? name[sequence] : (sequence - (Implementation::MaterialAttributeDataSize - value.size() - 3) < value.size() ? value[sequence - (Implementation::MaterialAttributeDataSize - value.size() - 3)] : '\0'))...}, size{UnsignedByte(value.size())} {} - constexpr explicit StringData(MaterialAttributeType type, Containers::StringView name, Containers::StringView value): StringData{type, name, value, typename Math::Implementation::GenerateSequence::Type{}} {} + template constexpr explicit StringData(MaterialAttributeType type, Containers::StringView name, Containers::StringView value, Containers::Implementation::Sequence): type{type}, nameValue{(sequence < name.size() ? name[sequence] : (sequence - (Implementation::MaterialAttributeDataSize - value.size() - 3) < value.size() ? value[sequence - (Implementation::MaterialAttributeDataSize - value.size() - 3)] : '\0'))...}, size{UnsignedByte(value.size())} {} + constexpr explicit StringData(MaterialAttributeType type, Containers::StringView name, Containers::StringView value): StringData{type, name, value, typename Containers::Implementation::GenerateSequence::Type{}} {} MaterialAttributeType type; char nameValue[Implementation::MaterialAttributeDataSize - 2]; @@ -1309,8 +1309,8 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { Math::RectangularMatrix b; }; template struct Data { - template constexpr explicit Data(MaterialAttributeType type, Containers::StringView name, const U& value, Math::Implementation::Sequence): type{type}, name{(sequence < name.size() ? name[sequence] : '\0')...}, value{value} {} - template constexpr explicit Data(MaterialAttributeType type, Containers::StringView name, const U& value): Data{type, name, value, typename Math::Implementation::GenerateSequence<63 - sizeof(T)>::Type{}} {} + template constexpr explicit Data(MaterialAttributeType type, Containers::StringView name, const U& value, Containers::Implementation::Sequence): type{type}, name{(sequence < name.size() ? name[sequence] : '\0')...}, value{value} {} + template constexpr explicit Data(MaterialAttributeType type, Containers::StringView name, const U& value): Data{type, name, value, typename Containers::Implementation::GenerateSequence<63 - sizeof(T)>::Type{}} {} MaterialAttributeType type; char name[Implementation::MaterialAttributeDataSize - sizeof(MaterialAttributeType) - sizeof(T)];