Source browser

detail/math.hpp

Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.

File fingerprint
1/** @file math.hpp
2 * @brief GLSL-compatible scalar, vector and matrix operations for C++11.
3 *
4 * Vectors provide x/y/z/w component fields, indexed access, and writable
5 * swizzles. Color and texture-coordinate aliases are accessor functions in
6 * ordinary C++ code. Matrices use GLSL column-major order. The same types and
7 * functions are available to generated CPU kernels and application code.
8 *
9 * Floating-point precision and exceptional values depend on the implementation.
10 * Normalize nonzero vectors, invert nonsingular matrices and use valid shift
11 * counts. Keep signed arithmetic within its representable range and use
12 * nonnegative signed operands for left shifts to follow portable C++ rules.
13 * Resource element layout is defined by the buffer and image APIs separately.
14 */
15#ifndef SHDR_DETAIL_MATH_HPP // Include this math layer only once.
16#define SHDR_DETAIL_MATH_HPP // Remember that the math layer is available.
17#include <cmath> // Use the standard scalar math functions.
18#include <cstddef> // Use portable size types.
19#include <cstdint> // Use exact-width GLSL integer types.
20#include <cstring> // Copy bit patterns through byte storage.
21#include <initializer_list> // Accept ordinary C++ brace lists.
22#include <limits> // Query numeric limits and quiet NaNs.
23#include <ostream> // Support readable vector and matrix output.
24#include <stdexcept> // Report invalid array initializers.
25#include <type_traits> // Choose only compatible template overloads.
26namespace shdr { // Keep these names inside the shdr namespace.
27namespace glsl { // Keep these names inside the glsl namespace.
28/** @brief GLSL's portable 32-bit unsigned scalar spelling. */
29typedef std::uint32_t uint; // Use a portable 32-bit unsigned scalar.
30template <class T, std::size_t N> class vec; // Store a fixed-size vector with named component fields.
31template <class T, std::size_t N> class array; // Store a fixed number of values of one element type.
32template <class T, std::size_t N, std::size_t... I> class swizzle_ref; // Describe a component selection that refers to a vector.
33template <class T, std::size_t C, std::size_t R> class mat; // Describe a matrix by its scalar type and dimensions.
34namespace detail { // Keep these names inside the detail namespace.
35template <class T, std::size_t N> struct storage; // Choose named storage for the vector dimension.
36template <class T> struct storage<T, 2> { // Choose named storage for the vector dimension.
37    T x, y; // Store the named vector components in order.
38    T& at(std::size_t i) { // Select the named component matching this index.
39        return i == 0 ? x : y; // Select the named field for this valid component index.
40    } // Finish the at operation.
41    const T& at(std::size_t i) const { // Select the named component matching this index.
42        return i == 0 ? x : y; // Select the named field for this valid component index.
43    } // Finish the at operation.
44}; // Finish the storage type description.
45template <class T> struct storage<T, 3> { // Choose named storage for the vector dimension.
46    T x, y, z; // Store the named vector components in order.
47    T& at(std::size_t i) { // Select the named component matching this index.
48        return i == 0 ? x : (i == 1 ? y : z); // Select the named field for this valid component index.
49    } // Finish the at operation.
50    const T& at(std::size_t i) const { // Select the named component matching this index.
51        return i == 0 ? x : (i == 1 ? y : z); // Select the named field for this valid component index.
52    } // Finish the at operation.
53}; // Finish the storage type description.
54template <class T> struct storage<T, 4> { // Choose named storage for the vector dimension.
55    T x, y, z, w; // Store the named vector components in order.
56    T& at(std::size_t i) { // Select the named component matching this index.
57        return i == 0 ? x : (i == 1 ? y : (i == 2 ? z : w)); // Select the named field for this valid component index.
58    } // Finish the at operation.
59    const T& at(std::size_t i) const { // Select the named component matching this index.
60        return i == 0 ? x : (i == 1 ? y : (i == 2 ? z : w)); // Select the named field for this valid component index.
61    } // Finish the at operation.
62}; // Finish the storage type description.
63template <class A> struct shape { // Describe an ordinary scalar input.
64    typedef A scalar; // Keep the chosen component type for the calculation.
65    static const std::size_t size = 1; // Treat a scalar as one component.
66    static const bool vector = false; // Keep this input out of vector-only overloads.
67    static const bool valid = std::is_arithmetic<A>::value; // Record whether componentwise arithmetic accepts this shape.
68}; // Finish the shape type description.
69template <class T, std::size_t N> struct shape<vec<T, N>> { // Describe the scalar type and size of a vector.
70    typedef T scalar; // Keep the chosen component type for the calculation.
71    static const std::size_t size = N; // Keep the fixed component count available at compile time.
72    static const bool vector = true; // Mark this input as a vector-shaped value.
73    static const bool valid = true; // Record whether componentwise arithmetic accepts this shape.
74}; // Finish the shape type description.
75template <class T, std::size_t N, std::size_t... I> struct shape<swizzle_ref<T, N, I...>> { // Describe the scalar type and size of a component selection.
76    typedef T scalar; // Keep the chosen component type for the calculation.
77    static const std::size_t size = sizeof...(I); // Count the selected vector components.
78    static const bool vector = true; // Mark this input as a vector-shaped value.
79    static const bool valid = true; // Record whether componentwise arithmetic accepts this shape.
80}; // Finish the shape type description.
81template <class A> struct traits : shape<typename std::decay<A>::type> {}; // Ignore references and const when inspecting an input type.
82template <class... A> struct count; // Count components supplied by constructor arguments.
83template <> struct count<> { // Count components supplied by constructor arguments.
84    static const std::size_t value = 0; // Start the component count at zero.
85}; // Finish the count type description.
86template <class A, class... B> struct count<A, B...> { // Count components supplied by constructor arguments.
87    static const std::size_t value = traits<A>::size + count<B...>::value; // Add this argument count to the remaining components.
88}; // Finish the count type description.
89template <class... A> struct prefix_count; // Count constructor components before the final argument.
90template <class Last> struct prefix_count<Last> { // Count constructor components before the final argument.
91    static const std::size_t value = 0; // Start the component count at zero.
92}; // Finish the prefix_count type description.
93template <class A, class B, class... Rest> struct prefix_count<A, B, Rest...> { // Count constructor components before the final argument.
94    static const std::size_t value = traits<A>::size + prefix_count<B, Rest...>::value; // Add this argument count to the remaining components.
95}; // Finish the prefix_count type description.
96template <class A> struct is_matrix : std::false_type {}; // Identify matrix types at compile time.
97template <class T, std::size_t C, std::size_t R> struct is_matrix<mat<T, C, R>> : std::true_type {}; // Identify matrix types at compile time.
98template <class T, std::size_t C, std::size_t R> struct shape<mat<T, C, R>> { // Describe a matrix separately from vector arithmetic.
99    typedef T scalar; // Keep the chosen component type for the calculation.
100    static const std::size_t size = C * R; // Count scalar entries across every matrix column.
101    static const bool vector = false; // Keep this input out of vector-only overloads.
102    static const bool valid = false; // Record whether componentwise arithmetic accepts this shape.
103}; // Finish the shape type description.
104template <class... A> struct any_matrix; // Check whether a constructor argument is a matrix.
105template <> struct any_matrix<> : std::false_type {}; // Check whether a constructor argument is a matrix.
106template <class A, class... B> // Accept the matching input types and dimensions.
107struct any_matrix<A, B...> // Describe this input or selection at compile time.
108    : std::integral_constant<bool, // Turn the component rule into a compile-time boolean.
109                             is_matrix<typename std::decay<A>::type>::value || // Complete the type and dimension rule for this overload.
110                                 any_matrix<B...>::value> {}; // Complete the type and dimension rule for this overload.
111template <std::size_t Needle, std::size_t... I> struct contains; // Check whether the remaining index list contains an index.
112template <std::size_t Needle> struct contains<Needle> : std::false_type {}; // Check whether the remaining index list contains an index.
113template <std::size_t Needle, std::size_t A, std::size_t... I> // Accept the matching input types and dimensions.
114struct contains<Needle, A, I...> // Describe this input or selection at compile time.
115    : std::integral_constant<bool, Needle == A || contains<Needle, I...>::value> {}; // Turn the component rule into a compile-time boolean.
116template <std::size_t... I> struct unique; // Check that selected component indices are distinct.
117template <> struct unique<> : std::true_type {}; // Check that selected component indices are distinct.
118template <std::size_t A, std::size_t... I> // Accept the matching input types and dimensions.
119struct unique<A, I...> // Describe this input or selection at compile time.
120    : std::integral_constant<bool, !contains<A, I...>::value && unique<I...>::value> {}; // Turn the component rule into a compile-time boolean.
121template <class A> struct writable_shape : std::false_type {}; // Identify vector selections that can receive values.
122template <class T, std::size_t N> struct writable_shape<vec<T, N>> : std::true_type {}; // Describe the scalar type and size of a vector.
123template <class T, std::size_t N, std::size_t... I> // Accept the matching input types and dimensions.
124struct writable_shape<swizzle_ref<T, N, I...>> : unique<I...> {}; // Describe this input or selection at compile time.
125template <class A> // Accept the matching input types and dimensions.
126struct writable // Describe this input or selection at compile time.
127    : std::integral_constant<bool, // Turn the component rule into a compile-time boolean.
128                             writable_shape<typename std::decay<A>::type>::value && // Complete the type and dimension rule for this overload.
129                                 !std::is_const<typename std::remove_reference<A>::type>::value> {}; // Complete the type and dimension rule for this overload.
130template <std::size_t N, std::size_t... I> struct in_range; // Check that every selected index fits the vector.
131template <std::size_t N> struct in_range<N> : std::true_type {}; // Check that every selected index fits the vector.
132template <std::size_t N, std::size_t A, std::size_t... I> // Accept the matching input types and dimensions.
133struct in_range<N, A, I...> : std::integral_constant<bool, // Check this index and the remaining selected indices.
134    A < N && in_range<N, I...>::value> {}; // Require every selected component index to fit the vector.
135template <class A> // Accept the matching input types and dimensions.
136typename std::enable_if<!traits<A>::vector, typename traits<A>::scalar>::type // Enable this overload only for compatible input types.
137component(const A& a, std::size_t) { // Read the requested scalar or vector component.
138    return a; // Return the scalar unchanged.
139} // Finish the component operation.
140template <class A> // Accept the matching input types and dimensions.
141typename std::enable_if<traits<A>::vector, typename traits<A>::scalar>::type // Enable this overload only for compatible input types.
142component(const A& a, std::size_t i) { // Read the requested scalar or vector component.
143    return a[i]; // Read the requested scalar or vector component.
144} // Finish the component operation.
145template <class A, class B> struct binary { // Choose compatible componentwise operand shapes.
146    static const bool valid = // Record whether componentwise arithmetic accepts this shape.
147        traits<A>::valid && traits<B>::valid && (traits<A>::vector || traits<B>::vector) && // Complete the type and dimension rule for this overload.
148        (!traits<A>::vector || !traits<B>::vector || traits<A>::size == traits<B>::size); // Require equal lengths when both operands are vectors.
149    typedef typename std::conditional<traits<A>::vector, // Name the type selected for this math result.
150                                      typename traits<A>::scalar, // Preserve the selected component type and result shape.
151                                      typename traits<B>::scalar>::type scalar; // Preserve the selected component type and result shape.
152    static const std::size_t size = traits<A>::vector ? traits<A>::size : traits<B>::size; // Record the compile-time component rule.
153    typedef vec<scalar, size> result; // Name the vector type produced by this operation.
154}; // Finish the binary type description.
155template <class A> struct result { // Choose the value type for this expression result.
156    typedef typename std::conditional<traits<A>::vector, // Name the type selected for this math result.
157                                      vec<typename traits<A>::scalar, traits<A>::size>, // Preserve the selected component type and result shape.
158                                      typename traits<A>::scalar>::type type; // Preserve the selected component type and result shape.
159}; // Finish the result type description.
160template <class T, class U> // Accept the matching input types and dimensions.
161typename std::enable_if<std::is_arithmetic<U>::value>::type // Enable this overload only for compatible input types.
162append(T* target, std::size_t& n, const U& a) { // Append the next argument to the flat component list.
163    target[n++] = static_cast<T>(a); // Append this component and advance the destination position.
164} // Finish the append operation.
165template <class T, class U, std::size_t N> // Accept the matching input types and dimensions.
166void append(T* target, std::size_t& n, const vec<U, N>& a) { // Append constructor components in their original order.
167    for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
168        target[n++] = static_cast<T>(a[i]); // Append this component and advance the destination position.
169} // Finish the append operation.
170template <class T, class U, std::size_t N, std::size_t... I> // Accept the matching input types and dimensions.
171void append(T* target, std::size_t& n, const swizzle_ref<U, N, I...>& a) { // Append constructor components in their original order.
172    for (std::size_t i = 0; i < sizeof...(I); ++i) // Visit each component needed by this calculation.
173        target[n++] = static_cast<T>(a[i]); // Append this component and advance the destination position.
174} // Finish the append operation.
175template <class T, class U, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
176void append(T* target, std::size_t& n, const mat<U, C, R>& a) { // Append constructor components in their original order.
177    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
178        for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
179            target[n++] = static_cast<T>(a[c][r]); // Append this component and advance the destination position.
180} // Finish the append operation.
181template <class T> void flatten(T*, std::size_t&) { // Accept the matching input types and dimensions.
182} // Finish the flatten operation.
183template <class T, class A, class... B> // Accept the matching input types and dimensions.
184void flatten(T* target, std::size_t& n, const A& a, const B&... b) { // Collect components from the remaining constructor arguments.
185    append(target, n, a); // Append the next argument to the flat component list.
186    flatten(target, n, b...); // Append the remaining arguments in order.
187} // Finish the flatten operation.
188} // namespace detail
189
190/** @brief A fixed-size array for GLSL local variables and function arguments.
191 * The size must be positive. Default construction initializes every element to
192 * its zero/default value.  component construction requires exactly N elements.
193 * Copy construction and assignment copy all elements. Use length() to query
194 * the element count and operator[] to select an element with a valid index.
195 * Resource ports define buffer and uniform memory layouts separately.
196 */
197template <class T, std::size_t N> class array { // Store a fixed number of values of one element type.
198    static_assert(N > 0, "GLSL fixed arrays require a positive size"); // Require at least one fixed-array element.
199    T elements_[N]; // Keep exactly N fixed-array elements.
200
201  public: // Expose the public math operations.
202    typedef T value_type; // Expose the element type to host code and templates.
203    static const std::size_t size_value = N; // Keep the fixed component count available at compile time.
204    /** @brief Return the number of array elements. */
205    static constexpr std::size_t length() { // Record the compile-time component rule.
206        return N; // Return the fixed number of available components.
207    } // Finish the length operation.
208    /** @brief Initialize every element to its zero/default value. */
209    array() : elements_() { // Initialize fixed-array storage from the supplied values.
210    } // Finish initializing the fixed array.
211    /** @brief Construct from exactly N scalar or aggregate element values. */
212    template <class... A> // Accept the matching input types and dimensions.
213    explicit array(const A&... values) : elements_{static_cast<T>(values)...} { // Initialize fixed-array storage from the supplied values.
214        static_assert(sizeof...(A) == N, "array constructor element count mismatch"); // Require exactly one argument for each array element.
215    } // Finish initializing the fixed array.
216    /** @brief Initialize from a C++ brace list containing exactly N elements.
217     * A length mismatch throws std::invalid_argument.
218     */
219    array(std::initializer_list<T> values) : elements_() { // Initialize fixed-array storage from the supplied values.
220        if (values.size() != N) // Reject a brace list with the wrong element count.
221            throw std::invalid_argument("array initializer element count mismatch"); // Report an initializer length mismatch.
222        std::size_t i = 0; // Begin filling the first array element.
223        for (const T& value : values) // Read initializer values in their original order.
224            elements_[i++] = value; // Store the next brace-list element.
225    } // Finish initializing the fixed array.
226    /** @brief Read or modify element i.  i must be less than length(). */
227    T& operator[](std::size_t i) { // Provide this arithmetic or component access overload.
228        return elements_[i]; // Return the selected component with its original reference type.
229    } // Finish this operator overload.
230    const T& operator[](std::size_t i) const { // Provide this arithmetic or component access overload.
231        return elements_[i]; // Return the selected component with its original reference type.
232    } // Finish this operator overload.
233}; // Finish the array type description.
234template <class T, std::size_t N> const std::size_t array<T, N>::size_value; // Accept the matching input types and dimensions.
235/** @brief Compare two arrays by comparing every element. */
236template <class T, std::size_t N> bool operator==(const array<T, N>& a, const array<T, N>& b) { // Accept the matching input types and dimensions.
237    for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
238        if (!(a[i] == b[i])) // Stop when corresponding components differ.
239            return false; // Report that at least one component differs.
240    return true; // Report that every required component matched.
241} // Finish this operator overload.
242/** @brief Return true when any pair of corresponding elements differs. */
243template <class T, std::size_t N> bool operator!=(const array<T, N>& a, const array<T, N>& b) { // Accept the matching input types and dimensions.
244    return !(a == b); // Return the component count or geometric length.
245} // Finish this operator overload.
246
247/** @brief A vector with two, three or four components of one scalar type.
248 * A scalar constructor fills every component. Component constructors consume
249 * scalar, vector and matrix arguments from left to right.  matrices contribute
250 * columns in order. Excess components in the final argument are discarded.
251 * Vector conversion takes the first N components of a source with at least N components.
252 * Default construction initializes every component to zero. Indexing requires
253 * an index less than length().
254 */
255template <class T, std::size_t N> class vec : public detail::storage<T, N> { // Store a fixed-size vector with named component fields.
256    static_assert(N >= 2 && N <= 4, "GLSL vectors require 2 to 4 components"); // Require two, three or four vector components.
257
258  public: // Expose the public math operations.
259    typedef T value_type; // Expose the element type to host code and templates.
260    typedef T component_type; // Expose the element type to host code and templates.
261    static const std::size_t length_value = N; // Keep the fixed component count available at compile time.
262    /** @brief Return the number of vector components. */
263    static constexpr std::size_t length() { // Record the compile-time component rule.
264        return N; // Return the fixed number of available components.
265    } // Finish the length operation.
266    vec() { // Initialize vector components from the supplied values.
267        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
268            (*this)[i] = T(); // Update the selected destination component.
269    } // Finish initializing the vector.
270    template <class U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0> // Accept the matching input types and dimensions.
271    explicit vec(U value) { // Initialize vector components from the supplied values.
272        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
273            (*this)[i] = static_cast<T>(value); // Update the selected destination component.
274    } // Finish initializing the vector.
275    template <class U, std::size_t M> explicit vec(const vec<U, M>& value) { // Accept the matching input types and dimensions.
276        static_assert(M >= N, "vector conversion cannot invent components"); // Check this type or dimension requirement at compile time.
277        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
278            (*this)[i] = static_cast<T>(value[i]); // Update the selected destination component.
279    } // Finish initializing the vector.
280    template <class U, std::size_t M, std::size_t... I> vec(const swizzle_ref<U, M, I...>& value) { // Accept the matching input types and dimensions.
281        static_assert(sizeof...(I) >= N, "swizzle conversion cannot invent components"); // Check this type or dimension requirement at compile time.
282        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
283            (*this)[i] = static_cast<T>(value[i]); // Update the selected destination component.
284    } // Finish initializing the vector.
285    /** @brief Read matrix columns consecutively to initialize the vector. */
286    template <class U, std::size_t C, std::size_t R> explicit vec(const mat<U, C, R>& value) { // Accept the matching input types and dimensions.
287        static_assert(C * R >= N, "matrix does not provide enough vector components"); // Check this type or dimension requirement at compile time.
288        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
289            (*this)[i] = static_cast<T>(value[i / R][i % R]); // Update the selected destination component.
290    } // Finish initializing the vector.
291    template <class A, class B, class... Rest> // Accept the matching input types and dimensions.
292    explicit vec(const A& a, const B& b, const Rest&... rest) { // Initialize vector components from the supplied values.
293        static_assert(detail::count<A, B, Rest...>::value >= N, // Require enough components to fill the destination.
294                      "vector constructor has too few components"); // Explain the rejected input: vector constructor has too few components.
295        static_assert(detail::prefix_count<A, B, Rest...>::value < N, // Reject constructor arguments that would go unused.
296                      "vector constructor has unused arguments"); // Explain the rejected input: vector constructor has unused arguments.
297        T values[detail::count<A, B, Rest...>::value]; // Allocate space for the supplied constructor components.
298        std::size_t n = 0; // Begin appending at the first temporary component.
299        detail::flatten(values, n, a, b, rest...); // Append the remaining arguments in order.
300        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
301            (*this)[i] = values[i]; // Update the selected destination component.
302    } // Finish initializing the vector.
303    /** @brief Read or modify component i. */
304    T& operator[](std::size_t i) { // Provide this arithmetic or component access overload.
305        return this->at(i); // Return the selected component with its original reference type.
306    } // Finish this operator overload.
307    const T& operator[](std::size_t i) const { // Provide this arithmetic or component access overload.
308        return this->at(i); // Return the selected component with its original reference type.
309    } // Finish this operator overload.
310    /** @brief Color aliases for x/y/z/w.  b and a require three and four components. */
311    T& r() { // Expose the first component through its color name.
312        return (*this)[0]; // Return the selected component with its original reference type.
313    } // Finish the r operation.
314    const T& r() const { // Expose the first component through its color name.
315        return (*this)[0]; // Return the selected component with its original reference type.
316    } // Finish the r operation.
317    T& g() { // Expose the second component through its color name.
318        return (*this)[1]; // Return the selected component with its original reference type.
319    } // Finish the g operation.
320    const T& g() const { // Expose the second component through its color name.
321        return (*this)[1]; // Return the selected component with its original reference type.
322    } // Finish the g operation.
323    T& b() { // Expose the third component through its color name.
324        static_assert(N >= 3, "b needs three components"); // Check this type or dimension requirement at compile time.
325        return (*this)[2]; // Return the selected component with its original reference type.
326    } // Finish the b operation.
327    const T& b() const { // Expose the third component through its color name.
328        static_assert(N >= 3, "b needs three components"); // Check this type or dimension requirement at compile time.
329        return (*this)[2]; // Return the selected component with its original reference type.
330    } // Finish the b operation.
331    T& a() { // Expose the fourth component through its color name.
332        static_assert(N >= 4, "a needs four components"); // Check this type or dimension requirement at compile time.
333        return (*this)[3]; // Return the selected component with its original reference type.
334    } // Finish the a operation.
335    const T& a() const { // Expose the fourth component through its color name.
336        static_assert(N >= 4, "a needs four components"); // Check this type or dimension requirement at compile time.
337        return (*this)[3]; // Return the selected component with its original reference type.
338    } // Finish the a operation.
339    /** @brief Texture-coordinate aliases for x/y/z/w. */
340    T& s() { // Expose the first texture coordinate.
341        return (*this)[0]; // Return the selected component with its original reference type.
342    } // Finish the s operation.
343    const T& s() const { // Expose the first texture coordinate.
344        return (*this)[0]; // Return the selected component with its original reference type.
345    } // Finish the s operation.
346    T& t() { // Expose the second texture coordinate.
347        return (*this)[1]; // Return the selected component with its original reference type.
348    } // Finish the t operation.
349    const T& t() const { // Expose the second texture coordinate.
350        return (*this)[1]; // Return the selected component with its original reference type.
351    } // Finish the t operation.
352    T& p() { // Expose the third texture coordinate.
353        static_assert(N >= 3, "p needs three components"); // Check this type or dimension requirement at compile time.
354        return (*this)[2]; // Return the selected component with its original reference type.
355    } // Finish the p operation.
356    const T& p() const { // Expose the third texture coordinate.
357        static_assert(N >= 3, "p needs three components"); // Check this type or dimension requirement at compile time.
358        return (*this)[2]; // Return the selected component with its original reference type.
359    } // Finish the p operation.
360    T& q() { // Expose the fourth texture coordinate.
361        static_assert(N >= 4, "q needs four components"); // Check this type or dimension requirement at compile time.
362        return (*this)[3]; // Return the selected component with its original reference type.
363    } // Finish the q operation.
364    const T& q() const { // Expose the fourth texture coordinate.
365        static_assert(N >= 4, "q needs four components"); // Check this type or dimension requirement at compile time.
366        return (*this)[3]; // Return the selected component with its original reference type.
367    } // Finish the q operation.
368    /** @brief Select one component as a scalar reference. */
369    template <std::size_t I> T& swizzle() { // Accept the matching input types and dimensions.
370        static_assert(I < N, "swizzle index out of range"); // Reject a component index outside the vector.
371        return (*this)[I]; // Return the selected component with its original reference type.
372    } // Finish the swizzle operation.
373    template <std::size_t I> const T& swizzle() const { // Accept the matching input types and dimensions.
374        static_assert(I < N, "swizzle index out of range"); // Reject a component index outside the vector.
375        return (*this)[I]; // Return the selected component with its original reference type.
376    } // Finish the swizzle operation.
377    /** @brief Select components in the requested order.  writable destinations
378     * must contain unique indices. Const vectors produce an independent value.
379     */
380    template <std::size_t... I> // Accept the matching input types and dimensions.
381    typename std::enable_if<(sizeof...(I) >= 2), swizzle_ref<T, N, I...>>::type swizzle() { // Enable this overload only for compatible input types.
382        static_assert(sizeof...(I) >= 2 && sizeof...(I) <= 4, "swizzles require 2 to 4 components"); // Check this type or dimension requirement at compile time.
383        static_assert(detail::in_range<N, I...>::value, "swizzle index out of range"); // Reject a component index outside the vector.
384        return swizzle_ref<T, N, I...>(*this); // Select components in the requested order.
385    } // Finish the swizzle operation.
386    template <std::size_t... I> // Accept the matching input types and dimensions.
387    typename std::enable_if<(sizeof...(I) >= 2), vec<T, sizeof...(I)>>::type swizzle() const { // Enable this overload only for compatible input types.
388        static_assert(sizeof...(I) >= 2 && sizeof...(I) <= 4, "swizzles require 2 to 4 components"); // Check this type or dimension requirement at compile time.
389        static_assert(detail::in_range<N, I...>::value, "swizzle index out of range"); // Reject a component index outside the vector.
390        const std::size_t indices[] = {I...}; // Keep the requested component order available for indexing.
391        vec<T, sizeof...(I)> out; // Keep an independent value for the result or aliased inputs.
392        for (std::size_t j = 0; j < sizeof...(I); ++j) // Visit each component needed by this calculation.
393            out[j] = (*this)[indices[j]]; // Store the computed component in the independent result.
394        return out; // Return the completed result.
395    } // Finish the swizzle operation.
396#define SHDR_DETAIL_VEC_ASSIGN(OP) /* Generate the matching scalar and vector overloads. */ \
397    template <class A> vec& operator OP(const A & a) { /* Accept the matching input types and dimensions. */ \
398        static_assert(!detail::traits<A>::vector || detail::traits<A>::size == N, /* Require matching component counts. */ \
399                      "vector dimension mismatch"); /* Explain the rejected input: vector dimension mismatch. */ \
400        T values[N]; /* Allocate space for the supplied constructor components. */ \
401        for (std::size_t i = 0; i < N; ++i) { /* Visit each component needed by this calculation. */ \
402            values[i] = static_cast<T>(detail::component(a, i)); /* Copy source components before any destination is changed. */ \
403        } /* Finish this component or matrix pass. */ \
404        for (std::size_t i = 0; i < N; ++i) { /* Visit each component needed by this calculation. */ \
405            (*this)[i] OP values[i]; /* Update the selected destination component. */ \
406        } /* Finish this component or matrix pass. */ \
407        return *this; /* Allow this update to be used in a chained expression. */ \
408    } /* Finish this operator overload. */
409    SHDR_DETAIL_VEC_ASSIGN(+=) // Provide componentwise addition.
410    SHDR_DETAIL_VEC_ASSIGN(-=) // Provide componentwise subtraction.
411    SHDR_DETAIL_VEC_ASSIGN(*=) // Provide componentwise multiplication.
412    SHDR_DETAIL_VEC_ASSIGN(/=) // Provide componentwise division.
413    SHDR_DETAIL_VEC_ASSIGN(%=) // Provide componentwise integer remainder.
414    SHDR_DETAIL_VEC_ASSIGN(&=) // Provide componentwise bitwise AND.
415    SHDR_DETAIL_VEC_ASSIGN(|=) // Provide componentwise bitwise OR.
416    SHDR_DETAIL_VEC_ASSIGN(^=) // Provide componentwise bitwise XOR.
417    SHDR_DETAIL_VEC_ASSIGN(<<=) // Provide componentwise left shifting.
418    SHDR_DETAIL_VEC_ASSIGN(>>=) // Provide componentwise right shifting.
419#undef SHDR_DETAIL_VEC_ASSIGN // Remove this local code generator macro.
420    vec& operator++() { // Provide this arithmetic or component access overload.
421        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
422            ++(*this)[i]; // Increment this vector component.
423        return *this; // Allow this update to be used in a chained expression.
424    } // Finish this operator overload.
425    vec operator++(int) { // Provide this arithmetic or component access overload.
426        vec old(*this); // Save the vector value before incrementing or decrementing it.
427        ++*this; // Increment every vector component.
428        return old; // Return the value from before the update.
429    } // Finish this operator overload.
430    vec& operator--() { // Provide this arithmetic or component access overload.
431        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
432            --(*this)[i]; // Decrement this vector component.
433        return *this; // Allow this update to be used in a chained expression.
434    } // Finish this operator overload.
435    vec operator--(int) { // Provide this arithmetic or component access overload.
436        vec old(*this); // Save the vector value before incrementing or decrementing it.
437        --*this; // Decrement every vector component.
438        return old; // Return the value from before the update.
439    } // Finish this operator overload.
440}; // Finish the vec type description.
441template <class T, std::size_t N> const std::size_t vec<T, N>::length_value; // Accept the matching input types and dimensions.
442
443/** @brief A component selection referencing an existing vector.
444 * Assignment evaluates all source components before writing any destination,
445 * so exchanging components of the same vector is safe. Duplicate destination
446 * indices are rejected at compile time. The vector must outlive the selection.
447 * construct a vec value to keep an independent copy.
448 */
449template <class T, std::size_t N, std::size_t... I> class swizzle_ref { // Describe a component selection that refers to a vector.
450    vec<T, N>* source_; // Refer to the vector that owns the selected components.
451
452  public: // Expose the public math operations.
453    static constexpr std::size_t length() { // Record the compile-time component rule.
454        return sizeof...(I); // Return the fixed number of available components.
455    } // Finish the length operation.
456    explicit swizzle_ref(vec<T, N>& source) : source_(&source) { // Keep a reference to the source vector.
457    } // Finish keeping the source vector reference.
458    swizzle_ref(const swizzle_ref&) = default; // Copy the reference to the same source vector.
459    T& operator[](std::size_t i) { // Provide this arithmetic or component access overload.
460        const std::size_t indices[] = {I...}; // Keep the requested component order available for indexing.
461        return (*source_)[indices[i]]; // Return the selected component with its original reference type.
462    } // Finish this operator overload.
463    const T& operator[](std::size_t i) const { // Provide this arithmetic or component access overload.
464        const std::size_t indices[] = {I...}; // Keep the requested component order available for indexing.
465        return (*source_)[indices[i]]; // Return the selected component with its original reference type.
466    } // Finish this operator overload.
467    operator vec<T, sizeof...(I)>() const { // Provide this arithmetic or component access overload.
468        return vec<T, sizeof...(I)>(*this); // Return the component count or geometric length.
469    } // Finish this operator overload.
470    swizzle_ref& operator=(const swizzle_ref& rhs) { // Provide this arithmetic or component access overload.
471        return assign(rhs); // Write through a temporary so overlapping selections remain safe.
472    } // Finish this operator overload.
473    template <class A> swizzle_ref& operator=(const A& rhs) { // Accept the matching input types and dimensions.
474        return assign(rhs); // Write through a temporary so overlapping selections remain safe.
475    } // Finish this operator overload.
476    template <class A> swizzle_ref& assign(const A& rhs) { // Accept the matching input types and dimensions.
477        static_assert(detail::unique<I...>::value, "a writable swizzle cannot repeat components"); // Prevent repeated destination components.
478        static_assert(!detail::traits<A>::vector || detail::traits<A>::size == sizeof...(I), // Require matching component counts.
479                      "swizzle dimension mismatch"); // Explain the rejected input: swizzle dimension mismatch.
480        vec<T, sizeof...(I)> temp; // Keep an independent value for the result or aliased inputs.
481        for (std::size_t j = 0; j < sizeof...(I); ++j) // Visit each component needed by this calculation.
482            temp[j] = static_cast<T>(detail::component(rhs, j)); // Save this source component before writing the selection.
483        for (std::size_t j = 0; j < sizeof...(I); ++j) // Visit each component needed by this calculation.
484            (*this)[j] = temp[j]; // Update the selected destination component.
485        return *this; // Allow this update to be used in a chained expression.
486    } // Finish the assign operation.
487#define SHDR_DETAIL_SWIZZLE_ASSIGN(OP, BINARY) /* Generate the matching scalar and vector overloads. */ \
488    template <class A> swizzle_ref& operator OP(const A & rhs) { /* Accept the matching input types and dimensions. */ \
489        return assign(vec<T, sizeof...(I)>(*this) BINARY rhs); /* Write through a temporary so overlapping selections remain safe. */ \
490    } /* Finish this operator overload. */
491    SHDR_DETAIL_SWIZZLE_ASSIGN(+=, +) // Provide componentwise addition.
492    SHDR_DETAIL_SWIZZLE_ASSIGN(-=, -) // Provide componentwise subtraction.
493    SHDR_DETAIL_SWIZZLE_ASSIGN(*=, *) // Provide componentwise multiplication.
494    SHDR_DETAIL_SWIZZLE_ASSIGN(/=, /) // Provide componentwise division.
495    SHDR_DETAIL_SWIZZLE_ASSIGN(%=, %) // Provide componentwise integer remainder.
496    SHDR_DETAIL_SWIZZLE_ASSIGN(&=, &) // Provide componentwise bitwise AND.
497    SHDR_DETAIL_SWIZZLE_ASSIGN(|=, |) // Provide componentwise bitwise OR.
498    SHDR_DETAIL_SWIZZLE_ASSIGN(^=, ^) // Provide componentwise bitwise XOR.
499    SHDR_DETAIL_SWIZZLE_ASSIGN(<<=, <<) // Provide componentwise left shifting.
500    SHDR_DETAIL_SWIZZLE_ASSIGN(>>=, >>) // Provide componentwise right shifting.
501#undef SHDR_DETAIL_SWIZZLE_ASSIGN // Remove this local code generator macro.
502}; // Finish the swizzle_ref type description.
503/** @name Vector component arithmetic
504 * Vector/scalar and scalar/vector forms broadcast the scalar.
505 * Integer operators require integer components, as in GLSL.
506 * @{ */
507#define SHDR_DETAIL_VEC_BINARY(OP) /* Generate the matching scalar and vector overloads. */ \
508    template <class A, class B> /* Accept the matching input types and dimensions. */ \
509    typename std::enable_if<detail::binary<A, B>::valid, /* Enable this overload only for compatible input types. */ \
510                            typename detail::binary<A, B>::result>::type /* Preserve the selected component type and result shape. */ \
511    operator OP(const A& a, const B& b) { /* Provide this arithmetic or component access overload. */ \
512        typedef typename detail::binary<A, B>::scalar T; /* Keep the chosen component type for the calculation. */ \
513        typename detail::binary<A, B>::result out; /* Allocate an independent result with the correct shape. */ \
514        for (std::size_t i = 0; i < detail::binary<A, B>::size; ++i) { /* Visit each component needed by this calculation. */ \
515            out[i] = static_cast<T>(detail::component(a, i) OP detail::component(b, i)); /* Store the computed component in the independent result. */ \
516        } /* Finish this component or matrix pass. */ \
517        return out; /* Return the completed result. */ \
518    } /* Finish this operator overload. */
519SHDR_DETAIL_VEC_BINARY(+) // Provide componentwise addition.
520SHDR_DETAIL_VEC_BINARY(-) // Provide componentwise subtraction.
521SHDR_DETAIL_VEC_BINARY(*) // Provide componentwise multiplication.
522SHDR_DETAIL_VEC_BINARY(/) // Provide componentwise division.
523SHDR_DETAIL_VEC_BINARY(%) // Provide componentwise integer remainder.
524SHDR_DETAIL_VEC_BINARY(&) // Provide componentwise bitwise AND.
525SHDR_DETAIL_VEC_BINARY(|) // Provide componentwise bitwise OR.
526SHDR_DETAIL_VEC_BINARY(^) // Provide componentwise bitwise XOR.
527SHDR_DETAIL_VEC_BINARY(<<) // Provide componentwise left shifting.
528SHDR_DETAIL_VEC_BINARY(>>) // Provide componentwise right shifting.
529#undef SHDR_DETAIL_VEC_BINARY // Remove this local code generator macro.
530template <class A> // Accept the matching input types and dimensions.
531typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
532operator-(const A& a) { // Provide this arithmetic or component access overload.
533    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
534    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
535        out[i] = -a[i]; // Store the computed component in the independent result.
536    return out; // Return the completed result.
537} // Finish this operator overload.
538template <class A> // Accept the matching input types and dimensions.
539typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
540operator+(const A& a) { // Provide this arithmetic or component access overload.
541    return typename detail::result<A>::type(a); // Copy source components before changing the destination.
542} // Finish this operator overload.
543template <class A> // Accept the matching input types and dimensions.
544typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
545operator~(const A& a) { // Provide this arithmetic or component access overload.
546    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
547    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
548        out[i] = ~a[i]; // Store the computed component in the independent result.
549    return out; // Return the completed result.
550} // Finish this operator overload.
551template <class A, class B> // Accept the matching input types and dimensions.
552typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
553                            detail::traits<A>::size == detail::traits<B>::size, // Complete the type and dimension rule for this overload.
554                        bool>::type // Complete the type and dimension rule for this overload.
555operator==(const A& a, const B& b) { // Provide this arithmetic or component access overload.
556    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { // Visit each component needed by this calculation.
557        if (a[i] != b[i]) // Stop when corresponding components differ.
558            return false; // Report that at least one component differs.
559    } // Finish this component or matrix pass.
560    return true; // Report that every required component matched.
561} // Finish this operator overload.
562template <class A, class B> // Accept the matching input types and dimensions.
563typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
564                            detail::traits<A>::size == detail::traits<B>::size, // Complete the type and dimension rule for this overload.
565                        bool>::type // Complete the type and dimension rule for this overload.
566operator!=(const A& a, const B& b) { // Provide this arithmetic or component access overload.
567    return !(a == b); // Copy source components before changing the destination.
568} // Finish this operator overload.
569/** @} */
570typedef vec<float, 2> vec2; // Name the 2-component float vector.
571typedef vec<float, 3> vec3; // Name the 3-component float vector.
572typedef vec<float, 4> vec4; // Name the 4-component float vector.
573typedef vec<double, 2> dvec2; // Name the 2-component double vector.
574typedef vec<double, 3> dvec3; // Name the 3-component double vector.
575typedef vec<double, 4> dvec4; // Name the 4-component double vector.
576typedef vec<std::int32_t, 2> ivec2; // Name the 2-component signed integer vector.
577typedef vec<std::int32_t, 3> ivec3; // Name the 3-component signed integer vector.
578typedef vec<std::int32_t, 4> ivec4; // Name the 4-component signed integer vector.
579typedef vec<std::uint32_t, 2> uvec2; // Name the 2-component unsigned integer vector.
580typedef vec<std::uint32_t, 3> uvec3; // Name the 3-component unsigned integer vector.
581typedef vec<std::uint32_t, 4> uvec4; // Name the 4-component unsigned integer vector.
582typedef vec<bool, 2> bvec2; // Name the 2-component boolean vector.
583typedef vec<bool, 3> bvec3; // Name the 3-component boolean vector.
584typedef vec<bool, 4> bvec4; // Name the 4-component boolean vector.
585template <class T, std::size_t N> // Accept the matching input types and dimensions.
586std::ostream& operator<<(std::ostream& out, const vec<T, N>& value) { // Provide this arithmetic or component access overload.
587    out << '('; // Write the next component or separator for readable output.
588    for (std::size_t i = 0; i < N; ++i) { // Visit each component needed by this calculation.
589        if (i) // Write a separator only after the first component.
590            out << ", "; // Write the next component or separator for readable output.
591        out << value[i]; // Write the next component or separator for readable output.
592    } // Finish this component or matrix pass.
593    return out << ')'; // Finish the readable representation and return the stream.
594} // Finish this operator overload.
595
596/** @brief A floating-point matrix with C columns and R rows.
597 * A scalar constructor initializes the diagonal and sets other entries to
598 * zero. Component constructors consume scalars and vectors in column order,
599 * discarding excess components in the final argument. Matrix conversion copies
600 * the common region and fills the remaining entries with the identity matrix.
601 * Default construction initializes every component to zero.
602 */
603template <class T, std::size_t C, std::size_t R> class mat { // Describe a matrix by its scalar type and dimensions.
604    static_assert(C >= 2 && C <= 4 && R >= 2 && R <= 4, "matrix dimensions require 2 to 4"); // Require matching component counts.
605    static_assert(std::is_floating_point<T>::value, // Require floating-point components for this operation.
606                  "GLSL matrices require floating point components"); // Explain the rejected input: GLSL matrices require floating point components.
607    vec<T, R> columns_[C]; // Store each matrix column as a vector.
608
609  public: // Expose the public math operations.
610    typedef T value_type; // Expose the element type to host code and templates.
611    typedef vec<T, R> column_type; // Expose the vector type used for each matrix column.
612    static const std::size_t columns = C; // Keep the matrix column count available at compile time.
613    static const std::size_t rows = R; // Keep the matrix row count available at compile time.
614    /** @brief Return the number of matrix columns. */
615    static constexpr std::size_t length() { // Record the compile-time component rule.
616        return C; // Return the fixed number of available components.
617    } // Finish the length operation.
618    mat() : columns_() { // Initialize matrix columns from the supplied values.
619    } // Finish initializing the matrix.
620    template <class U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0> // Accept the matching input types and dimensions.
621    explicit mat(U diagonal) : columns_() { // Initialize matrix columns from the supplied values.
622        for (std::size_t c = 0; c < C && c < R; ++c) // Visit each matrix column.
623            columns_[c][c] = static_cast<T>(diagonal); // Set this diagonal entry to the requested scalar.
624    } // Finish initializing the matrix.
625    template <class U, std::size_t A, std::size_t B> // Accept the matching input types and dimensions.
626    explicit mat(const mat<U, A, B>& other) : columns_() { // Initialize matrix columns from the supplied values.
627        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
628            for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
629                columns_[c][r] = // Copy or complete this matrix entry.
630                    c < A && r < B ? static_cast<T>(other[c][r]) : (c == r ? T(1) : T(0)); // Copy the common region and use identity entries elsewhere.
631    } // Finish initializing the matrix.
632    /** @brief Construct a matrix from the components of one vector or swizzle. */
633    template <class A, typename std::enable_if<detail::traits<A>::vector, int>::type = 0> // Accept the matching input types and dimensions.
634    explicit mat(const A& value) { // Initialize matrix columns from the supplied values.
635        static_assert(detail::traits<A>::size >= C * R, // Check this type or dimension requirement at compile time.
636                      "matrix constructor has too few components"); // Explain the rejected input: matrix constructor has too few components.
637        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
638            for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
639                columns_[c][r] = static_cast<T>(value[c * R + r]); // Copy the next source component in column order.
640    } // Finish initializing the matrix.
641    template <class A, class B, class... Rest> // Accept the matching input types and dimensions.
642    explicit mat(const A& a, const B& b, const Rest&... rest) { // Initialize matrix columns from the supplied values.
643        static_assert(!detail::any_matrix<A, B, Rest...>::value, // Check this type or dimension requirement at compile time.
644                      "matrix conversion cannot be mixed with other arguments"); // Require the matrix to be the sole conversion argument.
645        static_assert(detail::count<A, B, Rest...>::value >= C * R, // Require enough components to fill the destination.
646                      "matrix constructor has too few components"); // Explain the rejected input: matrix constructor has too few components.
647        static_assert(detail::prefix_count<A, B, Rest...>::value < C * R, // Reject constructor arguments that would go unused.
648                      "matrix constructor has unused arguments"); // Explain the rejected input: matrix constructor has unused arguments.
649        T values[detail::count<A, B, Rest...>::value]; // Allocate space for the supplied constructor components.
650        std::size_t n = 0; // Begin appending at the first temporary component.
651        detail::flatten(values, n, a, b, rest...); // Append the remaining arguments in order.
652        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
653            for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
654                columns_[c][r] = values[c * R + r]; // Fill the column from the flattened constructor values.
655    } // Finish initializing the matrix.
656    /** @brief Read or modify column c.  m[c][r] selects row r within that column. */
657    column_type& operator[](std::size_t c) { // Provide this arithmetic or component access overload.
658        return columns_[c]; // Return the component count or geometric length.
659    } // Finish this operator overload.
660    const column_type& operator[](std::size_t c) const { // Provide this arithmetic or component access overload.
661        return columns_[c]; // Return the component count or geometric length.
662    } // Finish this operator overload.
663    mat& operator+=(const mat& b) { // Provide this arithmetic or component access overload.
664        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
665            columns_[c] += b[c]; // Add the corresponding matrix column.
666        return *this; // Allow this update to be used in a chained expression.
667    } // Finish this operator overload.
668    mat& operator-=(const mat& b) { // Provide this arithmetic or component access overload.
669        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
670            columns_[c] -= b[c]; // Subtract the corresponding matrix column.
671        return *this; // Allow this update to be used in a chained expression.
672    } // Finish this operator overload.
673    mat& operator+=(T b) { // Provide this arithmetic or component access overload.
674        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
675            columns_[c] += b; // Add the scalar to every entry in this column.
676        return *this; // Allow this update to be used in a chained expression.
677    } // Finish this operator overload.
678    mat& operator-=(T b) { // Provide this arithmetic or component access overload.
679        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
680            columns_[c] -= b; // Subtract the scalar from every entry in this column.
681        return *this; // Allow this update to be used in a chained expression.
682    } // Finish this operator overload.
683    mat& operator*=(T b) { // Provide this arithmetic or component access overload.
684        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
685            columns_[c] *= b; // Scale this column by the scalar.
686        return *this; // Allow this update to be used in a chained expression.
687    } // Finish this operator overload.
688    mat& operator/=(T b) { // Provide this arithmetic or component access overload.
689        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
690            columns_[c] /= b; // Divide this column by the scalar.
691        return *this; // Allow this update to be used in a chained expression.
692    } // Finish this operator overload.
693    mat& operator/=(const mat& b) { // Provide this arithmetic or component access overload.
694        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
695            columns_[c] /= b[c]; // Divide corresponding entries in this column.
696        return *this; // Allow this update to be used in a chained expression.
697    } // Finish this operator overload.
698    mat& operator*=(const mat<T, C, C>& b) { // Provide this arithmetic or component access overload.
699        *this = *this * b;
700        return *this; // Allow this update to be used in a chained expression.
701    } // Finish this operator overload.
702}; // Finish the mat type description.
703template <class T, std::size_t C, std::size_t R> const std::size_t mat<T, C, R>::columns; // Accept the matching input types and dimensions.
704template <class T, std::size_t C, std::size_t R> const std::size_t mat<T, C, R>::rows; // Accept the matching input types and dimensions.
705
706/** @brief Convert a scalar, or the first component of a vector, to T.
707 * This implements GLSL scalar constructors such as float(vec3) for generated
708 * C++ kernels. Ordinary C++ callers may use scalar_cast<float>(value) directly.
709 */
710template <class T, class A> // Accept the matching input types and dimensions.
711typename std::enable_if<std::is_arithmetic<T>::value && detail::traits<A>::valid, T>::type // Enable this overload only for compatible input types.
712scalar_cast(const A& value) { // Convert the first scalar component to the requested type.
713    return static_cast<T>(detail::component(value, 0)); // Convert the first scalar component to the requested type.
714} // Finish the scalar_cast operation.
715/** @brief Convert the first column's first matrix component to scalar type T. */
716template <class T, class U, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
717typename std::enable_if<std::is_arithmetic<T>::value, T>::type // Enable this overload only for compatible input types.
718scalar_cast(const mat<U, C, R>& value) { // Convert the first scalar component to the requested type.
719    return static_cast<T>(value[0][0]); // Convert the first scalar component to the requested type.
720} // Finish the scalar_cast operation.
721/** @brief GLSL square and rectangular matrix aliases.  dimensions are columns
722 * followed by rows. Float aliases are mat2..4 and mat2x2..mat4x4.  double aliases
723 * use dmat. Double arithmetic is a host extension and requires a supporting
724 * desktop GLSL profile when used by shared shaders.
725 */
726#define SHDR_DETAIL_MATRIX_ALIASES(T, PREFIX) /* Generate the matching scalar and vector overloads. */ \
727    typedef mat<T, 2, 2> PREFIX##2; /* Name the type selected for this math result. */ \
728    typedef mat<T, 3, 3> PREFIX##3; /* Name the type selected for this math result. */ \
729    typedef mat<T, 4, 4> PREFIX##4; /* Name the type selected for this math result. */ \
730    typedef mat<T, 2, 2> PREFIX##2x2; /* Name the type selected for this math result. */ \
731    typedef mat<T, 2, 3> PREFIX##2x3; /* Name the type selected for this math result. */ \
732    typedef mat<T, 2, 4> PREFIX##2x4; /* Name the type selected for this math result. */ \
733    typedef mat<T, 3, 2> PREFIX##3x2; /* Name the type selected for this math result. */ \
734    typedef mat<T, 3, 3> PREFIX##3x3; /* Name the type selected for this math result. */ \
735    typedef mat<T, 3, 4> PREFIX##3x4; /* Name the type selected for this math result. */ \
736    typedef mat<T, 4, 2> PREFIX##4x2; /* Name the type selected for this math result. */ \
737    typedef mat<T, 4, 3> PREFIX##4x3; /* Name the type selected for this math result. */ \
738    typedef mat<T, 4, 4> PREFIX##4x4; /* Name the type selected for this math result. */
739SHDR_DETAIL_MATRIX_ALIASES(float, mat) // Provide the single-precision matrix names.
740SHDR_DETAIL_MATRIX_ALIASES(double, dmat) // Provide the double-precision matrix names.
741#undef SHDR_DETAIL_MATRIX_ALIASES // Remove this local code generator macro.
742template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
743mat<T, C, R> operator+(mat<T, C, R> a, const mat<T, C, R>& b) { // Keep an independent value for the result or aliased inputs.
744    return a += b; // Convert the first scalar component to the requested type.
745} // Finish this operator overload.
746template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
747mat<T, C, R> operator-(mat<T, C, R> a, const mat<T, C, R>& b) { // Keep an independent value for the result or aliased inputs.
748    return a -= b; // Convert the first scalar component to the requested type.
749} // Finish this operator overload.
750template <class T, std::size_t C, std::size_t R> mat<T, C, R> operator-(const mat<T, C, R>& a) { // Accept the matching input types and dimensions.
751    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
752    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
753        out[c] = -a[c]; // Store the computed component in the independent result.
754    return out; // Return the completed result.
755} // Finish this operator overload.
756template <class T, std::size_t C, std::size_t R> mat<T, C, R> operator+(const mat<T, C, R>& a) { // Accept the matching input types and dimensions.
757    return a; // Return the scalar unchanged.
758} // Finish this operator overload.
759#define SHDR_DETAIL_MATRIX_SCALAR(OP, ASSIGN) /* Generate the matching scalar and vector overloads. */ \
760    template <class T, std::size_t C, std::size_t R, class U> /* Accept the matching input types and dimensions. */ \
761    typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator OP( /* Enable this overload only for compatible input types. */ \
762        mat<T, C, R> a, U b) { /* Keep an independent value for the result or aliased inputs. */ \
763        return a ASSIGN static_cast<T>(b); /* Convert the first scalar component to the requested type. */ \
764    } /* Finish this declaration. */ \
765    template <class T, std::size_t C, std::size_t R, class U> /* Accept the matching input types and dimensions. */ \
766    typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator OP( /* Enable this overload only for compatible input types. */ \
767        U a, const mat<T, C, R>& b) { /* Accept a scalar before the matrix operand. */ \
768        mat<T, C, R> out; /* Keep an independent value for the result or aliased inputs. */ \
769        for (std::size_t c = 0; c < C; ++c) { /* Visit each matrix column. */ \
770            out[c] = static_cast<T>(a) OP b[c]; /* Store the computed component in the independent result. */ \
771        } /* Finish this component or matrix pass. */ \
772        return out; /* Return the completed result. */ \
773    } /* Finish this declaration. */
774SHDR_DETAIL_MATRIX_SCALAR(+, +=) // Provide componentwise addition.
775SHDR_DETAIL_MATRIX_SCALAR(-, -=) // Provide componentwise subtraction.
776#undef SHDR_DETAIL_MATRIX_SCALAR // Remove this local code generator macro.
777template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
778typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator*(mat<T, C, R> a, // Enable this overload only for compatible input types.
779                                                                                    U b) { // Accept a scalar after the matrix operand.
780    return a *= static_cast<T>(b); // Convert the first scalar component to the requested type.
781} // Finish this declaration.
782template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
783typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type // Enable this overload only for compatible input types.
784operator*(U a, mat<T, C, R> b) { // Provide this arithmetic or component access overload.
785    return b *= static_cast<T>(a); // Convert the first scalar component to the requested type.
786} // Finish this operator overload.
787template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
788typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator/(mat<T, C, R> a, // Enable this overload only for compatible input types.
789                                                                                    U b) { // Accept a scalar after the matrix operand.
790    return a /= static_cast<T>(b); // Convert the first scalar component to the requested type.
791} // Finish this declaration.
792template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
793typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type // Enable this overload only for compatible input types.
794operator/(U a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
795    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
796    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
797        out[c] = static_cast<T>(a) / b[c]; // Store the computed component in the independent result.
798    return out; // Return the completed result.
799} // Finish this operator overload.
800template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
801mat<T, C, R> operator/(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
802    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
803    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
804        out[c] = a[c] / b[c]; // Store the computed component in the independent result.
805    return out; // Return the completed result.
806} // Finish this operator overload.
807template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
808bool operator==(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
809    for (std::size_t c = 0; c < C; ++c) { // Visit each matrix column.
810        if (a[c] != b[c]) // Handle the exceptional or boundary case before continuing.
811            return false; // Report that at least one component differs.
812    } // Finish this component or matrix pass.
813    return true; // Report that every required component matched.
814} // Finish this operator overload.
815template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
816bool operator!=(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
817    return !(a == b); // Convert the first scalar component to the requested type.
818} // Finish this operator overload.
819/** @brief Algebraic matrix-vector multiplication. */
820template <class T, std::size_t C, std::size_t R, class A> // Accept the matching input types and dimensions.
821typename std::enable_if<detail::traits<A>::vector && detail::traits<A>::size == C, vec<T, R>>::type // Enable this overload only for compatible input types.
822operator*(const mat<T, C, R>& a, const A& b) { // Provide this arithmetic or component access overload.
823    vec<T, R> out(T(0)); // Keep an independent value for the result or aliased inputs.
824    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
825        out += a[c] * b[c]; // Add this component product to the running total.
826    return out; // Return the completed result.
827} // Finish this operator overload.
828template <class T, std::size_t C, std::size_t R, class A> // Accept the matching input types and dimensions.
829typename std::enable_if<detail::traits<A>::vector && detail::traits<A>::size == R, vec<T, C>>::type // Enable this overload only for compatible input types.
830operator*(const A& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
831    vec<T, C> out(T(0)); // Keep an independent value for the result or aliased inputs.
832    for (std::size_t c = 0; c < C; ++c) { // Visit each matrix column.
833        for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
834            out[c] += a[r] * b[c][r]; // Store the computed component in the independent result.
835    } // Finish this component or matrix pass.
836    return out; // Return the completed result.
837} // Finish this operator overload.
838/** @brief Algebraic multiplication, including nonsquare matrices. */
839template <class T, std::size_t C, std::size_t R, std::size_t K> // Accept the matching input types and dimensions.
840mat<T, K, R> operator*(const mat<T, C, R>& a, const mat<T, K, C>& b) { // Provide this arithmetic or component access overload.
841    mat<T, K, R> out; // Keep an independent value for the result or aliased inputs.
842    for (std::size_t c = 0; c < K; ++c) // Visit each matrix column.
843        out[c] = a * b[c]; // Store the computed component in the independent result.
844    return out; // Return the completed result.
845} // Finish this operator overload.
846/** @brief Exchange rows and columns, including rectangular matrices. */
847template <class T, std::size_t C, std::size_t R> mat<T, R, C> transpose(const mat<T, C, R>& a) { // Accept the matching input types and dimensions.
848    mat<T, R, C> out; // Keep an independent value for the result or aliased inputs.
849    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
850        for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
851            out[r][c] = a[c][r]; // Copy the entry to its exchanged row and column.
852    return out; // Return the completed result.
853} // Finish the transpose operation.
854/** @brief Multiply corresponding matrix components element by element. */
855template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
856mat<T, C, R> matrixCompMult(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Multiply corresponding matrix entries.
857    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
858    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
859        out[c] = a[c] * b[c]; // Store the computed component in the independent result.
860    return out; // Return the completed result.
861} // Finish the matrixCompMult operation.
862/** @brief Form a column-by-row outer product.  output column j is column*row[j]. */
863template <class T, std::size_t R, std::size_t C> // Accept the matching input types and dimensions.
864mat<T, C, R> outerProduct(const vec<T, R>& column, const vec<T, C>& row) { // Keep an independent value for the result or aliased inputs.
865    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
866    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
867        out[c] = column * row[c]; // Store the computed component in the independent result.
868    return out; // Return the completed result.
869} // Finish the outerProduct operation.
870/** @brief Determinant using partial-pivot elimination. */
871template <class T, std::size_t N> T determinant(mat<T, N, N> a) { // Accept the matching input types and dimensions.
872    T result(1); // Begin the determinant product with multiplicative identity.
873    for (std::size_t i = 0; i < N; ++i) { // Visit each component needed by this calculation.
874        std::size_t pivot = i; // Begin with the current row as the pivot candidate.
875        for (std::size_t r = i + 1; r < N; ++r) // Visit each matrix row.
876            if (std::abs(a[i][r]) > std::abs(a[i][pivot])) // Prefer the row with the larger pivot magnitude.
877                pivot = r; // Use the stronger row for the next pivot.
878        if (a[i][pivot] == T(0)) // Detect a singular column before division.
879            return T(0); // Compute the determinant with row pivoting.
880        if (pivot != i) { // Swap rows when a better pivot was found.
881            for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
882                T temp = a[c][i]; // Save an entry while exchanging the two rows.
883                a[c][i] = a[c][pivot]; // Update this matrix entry during row elimination or exchange.
884                a[c][pivot] = temp; // Update this matrix entry during row elimination or exchange.
885            } // Finish this component or matrix pass.
886            result = -result; // Reverse the determinant sign after a row exchange.
887        } // Finish handling this condition.
888        T diagonal = a[i][i]; // Save the pivot value before normalizing the row.
889        result *= diagonal; // Multiply the determinant by the next diagonal value.
890        for (std::size_t r = i + 1; r < N; ++r) { // Visit each matrix row.
891            T factor = a[i][r] / diagonal; // Find the amount of the pivot row to eliminate.
892            for (std::size_t c = i + 1; c < N; ++c) // Visit each matrix column.
893                a[c][r] -= factor * a[c][i]; // Update this matrix entry during row elimination or exchange.
894        } // Finish this component or matrix pass.
895    } // Finish this component or matrix pass.
896    return result; // Return the completed result.
897} // Finish the determinant operation.
898/** @brief Inverse using partial-pivot Gauss-Jordan elimination.
899 * Singular input has undefined GLSL semantics.  the host returns quiet NaNs.
900 */
901template <class T, std::size_t N> mat<T, N, N> inverse(mat<T, N, N> a) { // Accept the matching input types and dimensions.
902    mat<T, N, N> out(T(1)); // Keep an independent value for the result or aliased inputs.
903    for (std::size_t i = 0; i < N; ++i) { // Visit each component needed by this calculation.
904        std::size_t pivot = i; // Begin with the current row as the pivot candidate.
905        for (std::size_t r = i + 1; r < N; ++r) // Visit each matrix row.
906            if (std::abs(a[i][r]) > std::abs(a[i][pivot])) // Prefer the row with the larger pivot magnitude.
907                pivot = r; // Use the stronger row for the next pivot.
908        if (a[i][pivot] == T(0)) { // Detect a singular column before division.
909            for (std::size_t c = 0; c < N; ++c) // Visit each matrix column.
910                out[c] = vec<T, N>(std::numeric_limits<T>::quiet_NaN()); // Store the computed component in the independent result.
911            return out; // Return the completed result.
912        } // Finish handling this condition.
913        if (pivot != i) // Swap rows when a better pivot was found.
914            for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
915                T temp = a[c][i]; // Save an entry while exchanging the two rows.
916                a[c][i] = a[c][pivot]; // Update this matrix entry during row elimination or exchange.
917                a[c][pivot] = temp; // Update this matrix entry during row elimination or exchange.
918                temp = out[c][i]; // Save an entry while exchanging the two rows.
919                out[c][i] = out[c][pivot]; // Store the computed component in the independent result.
920                out[c][pivot] = temp; // Store the computed component in the independent result.
921            } // Finish this component or matrix pass.
922        T diagonal = a[i][i]; // Save the pivot value before normalizing the row.
923        for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
924            a[c][i] /= diagonal; // Update this matrix entry during row elimination or exchange.
925            out[c][i] /= diagonal; // Store the computed component in the independent result.
926        } // Finish this component or matrix pass.
927        for (std::size_t r = 0; r < N; ++r) // Visit each matrix row.
928            if (r != i) { // Handle the exceptional or boundary case before continuing.
929                T factor = a[i][r]; // Find the amount of the pivot row to eliminate.
930                for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
931                    a[c][r] -= factor * a[c][i]; // Update this matrix entry during row elimination or exchange.
932                    out[c][r] -= factor * out[c][i]; // Subtract the pivot-row contribution from the inverse.
933                } // Finish this component or matrix pass.
934            } // Finish handling this condition.
935    } // Finish this component or matrix pass.
936    return out; // Return the completed result.
937} // Finish the inverse operation.
938template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
939std::ostream& operator<<(std::ostream& out, const mat<T, C, R>& value) { // Provide this arithmetic or component access overload.
940    out << '['; // Write the next component or separator for readable output.
941    for (std::size_t c = 0; c < C; ++c) { // Visit each matrix column.
942        if (c) // Write a separator only after the first component.
943            out << ", "; // Write the next component or separator for readable output.
944        out << value[c]; // Write the next component or separator for readable output.
945    } // Finish this component or matrix pass.
946    return out << ']'; // Finish the readable representation and return the stream.
947} // Finish this operator overload.
948/** @name Angle, exponential and common scalar/vector math
949 * Floating-point overloads preserve their component type. Vector overloads
950 * apply each scalar operation independently, including swizzle expressions.
951 * @{ */
952#define SHDR_DETAIL_FLOAT_UNARY(NAME, EXPR) /* Generate the matching scalar and vector overloads. */ \
953    template <class T> /* Accept the matching input types and dimensions. */ \
954    typename std::enable_if<std::is_floating_point<T>::value, T>::type NAME(T x) { /* Enable this overload only for compatible input types. */ \
955        return static_cast<T>(EXPR); /* Compute the inverse with row pivoting. */ \
956    } /* Finish this generated overload. */ \
957    template <class A> /* Accept the matching input types and dimensions. */ \
958    typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type /* Enable this overload only for compatible input types. */ \
959    NAME(const A& x) { /* Start the matching math overload. */ \
960        typedef typename detail::traits<A>::scalar T; /* Keep the chosen component type for the calculation. */ \
961        static_assert(std::is_floating_point<T>::value, "floating point components required"); /* Require floating-point components for this operation. */ \
962        typename detail::result<A>::type out; /* Allocate an independent result with the correct shape. */ \
963        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
964            out[i] = glsl::NAME(x[i]); /* Store the computed component in the independent result. */ \
965        return out; /* Return the completed result. */ \
966    } /* Finish this generated overload. */
967SHDR_DETAIL_FLOAT_UNARY(radians, x* T(0.01745329251994329576923690768489L)) // Convert degrees to radians for scalars and vector components.
968SHDR_DETAIL_FLOAT_UNARY(degrees, x* T(57.295779513082320876798154814105L)) // Convert radians to degrees for scalars and vector components.
969SHDR_DETAIL_FLOAT_UNARY(sin, std::sin(x)) // Compute the sine for scalars and vector components.
970SHDR_DETAIL_FLOAT_UNARY(cos, std::cos(x)) // Compute the cosine for scalars and vector components.
971SHDR_DETAIL_FLOAT_UNARY(tan, std::tan(x)) // Compute the tangent for scalars and vector components.
972SHDR_DETAIL_FLOAT_UNARY(asin, std::asin(x)) // Compute the inverse sine for scalars and vector components.
973SHDR_DETAIL_FLOAT_UNARY(acos, std::acos(x)) // Compute the inverse cosine for scalars and vector components.
974SHDR_DETAIL_FLOAT_UNARY(atan, std::atan(x)) // Compute the inverse tangent for scalars and vector components.
975SHDR_DETAIL_FLOAT_UNARY(sinh, std::sinh(x)) // Compute the hyperbolic sine for scalars and vector components.
976SHDR_DETAIL_FLOAT_UNARY(cosh, std::cosh(x)) // Compute the hyperbolic cosine for scalars and vector components.
977SHDR_DETAIL_FLOAT_UNARY(tanh, std::tanh(x)) // Compute the hyperbolic tangent for scalars and vector components.
978SHDR_DETAIL_FLOAT_UNARY(asinh, std::asinh(x)) // Compute the inverse hyperbolic sine for scalars and vector components.
979SHDR_DETAIL_FLOAT_UNARY(acosh, std::acosh(x)) // Compute the inverse hyperbolic cosine for scalars and vector components.
980SHDR_DETAIL_FLOAT_UNARY(atanh, std::atanh(x)) // Compute the inverse hyperbolic tangent for scalars and vector components.
981SHDR_DETAIL_FLOAT_UNARY(exp, std::exp(x)) // Raise e to the input power for scalars and vector components.
982SHDR_DETAIL_FLOAT_UNARY(log, std::log(x)) // Compute the natural logarithm for scalars and vector components.
983SHDR_DETAIL_FLOAT_UNARY(exp2, std::exp2(x)) // Raise two to the input power for scalars and vector components.
984SHDR_DETAIL_FLOAT_UNARY(log2, std::log2(x)) // Compute the base-two logarithm for scalars and vector components.
985SHDR_DETAIL_FLOAT_UNARY(sqrt, std::sqrt(x)) // Compute the square root for scalars and vector components.
986SHDR_DETAIL_FLOAT_UNARY(inversesqrt, T(1) / std::sqrt(x)) // Compute the reciprocal square root for scalars and vector components.
987SHDR_DETAIL_FLOAT_UNARY(floor, std::floor(x)) // Round toward negative infinity for scalars and vector components.
988SHDR_DETAIL_FLOAT_UNARY(trunc, std::trunc(x)) // Round toward zero for scalars and vector components.
989SHDR_DETAIL_FLOAT_UNARY(round, std::round(x)) // Round to the nearest integer for scalars and vector components.
990SHDR_DETAIL_FLOAT_UNARY(ceil, std::ceil(x)) // Round toward positive infinity for scalars and vector components.
991SHDR_DETAIL_FLOAT_UNARY(fract, x - std::floor(x)) // Keep the fraction above the floor for scalars and vector components.
992#undef SHDR_DETAIL_FLOAT_UNARY // Remove this local code generator macro.
993template <class T> typename std::enable_if<std::is_arithmetic<T>::value, T>::type abs(T x) { // Accept the matching input types and dimensions.
994    return x < T(0) ? -x : x; // Return a nonnegative magnitude.
995} // Finish the abs operation.
996template <class A> // Accept the matching input types and dimensions.
997typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
998abs(const A& a) { // Return a nonnegative magnitude.
999    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1000    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1001        out[i] = glsl::abs(a[i]); // Store the computed component in the independent result.
1002    return out; // Return the completed result.
1003} // Finish the abs operation.
1004template <class T> typename std::enable_if<std::is_arithmetic<T>::value, T>::type sign(T x) { // Accept the matching input types and dimensions.
1005    return x > T(0) ? T(1) : (x < T(0) ? T(-1) : T(0)); // Return minus one, zero or one from the input sign.
1006} // Finish the sign operation.
1007template <class A> // Accept the matching input types and dimensions.
1008typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1009sign(const A& a) { // Return minus one, zero or one from the input sign.
1010    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1011    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1012        out[i] = glsl::sign(a[i]); // Store the computed component in the independent result.
1013    return out; // Return the completed result.
1014} // Finish the sign operation.
1015/** @brief Round halfway cases to the nearest even integer, independent of the
1016 * host's floating-point rounding mode. Nonfinite inputs are preserved.
1017 */
1018template <class T> // Accept the matching input types and dimensions.
1019typename std::enable_if<std::is_floating_point<T>::value, T>::type roundEven(T x) { // Enable this overload only for compatible input types.
1020    if (!std::isfinite(x)) // Keep nonfinite inputs unchanged.
1021        return x; // Round halfway values to the nearest even integer.
1022    T lo = std::floor(x), fraction = x - lo; // Separate the lower integer from its fractional remainder.
1023    if (fraction < T(0.5)) // Choose the lower integer below the halfway point.
1024        return lo; // Round halfway values to the nearest even integer.
1025    if (fraction > T(0.5)) // Choose the upper integer above the halfway point.
1026        return lo + T(1); // Round halfway values to the nearest even integer.
1027    return std::fmod(lo, T(2)) == T(0) ? lo : lo + T(1); // Round halfway values to the nearest even integer.
1028} // Finish the roundEven operation.
1029template <class A> // Accept the matching input types and dimensions.
1030typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1031roundEven(const A& a) { // Round halfway values to the nearest even integer.
1032    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1033    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1034        out[i] = glsl::roundEven(a[i]); // Store the computed component in the independent result.
1035    return out; // Return the completed result.
1036} // Finish the roundEven operation.
1037#define SHDR_DETAIL_MATH_BINARY(NAME, ENABLE, EXPR) /* Generate the matching scalar and vector overloads. */ \
1038    template <class T> typename std::enable_if<ENABLE, T>::type NAME(T x, T y) { /* Accept the matching input types and dimensions. */ \
1039        return static_cast<T>(EXPR); /* Round halfway values to the nearest even integer. */ \
1040    } /* Finish this generated overload. */ \
1041    template <class A, class B> /* Accept the matching input types and dimensions. */ \
1042    typename std::enable_if<detail::binary<A, B>::valid, /* Enable this overload only for compatible input types. */ \
1043                            typename detail::binary<A, B>::result>::type /* Preserve the selected component type and result shape. */ \
1044    NAME(const A& a, const B& b) { /* Start the matching math overload. */ \
1045        typedef typename detail::binary<A, B>::scalar T; /* Keep the chosen component type for the calculation. */ \
1046        typename detail::binary<A, B>::result out; /* Allocate an independent result with the correct shape. */ \
1047        for (std::size_t i = 0; i < detail::binary<A, B>::size; ++i) { /* Visit each component needed by this calculation. */ \
1048            out[i] = glsl::NAME(static_cast<T>(detail::component(a, i)), /* Store the computed component in the independent result. */ \
1049                                static_cast<T>(detail::component(b, i))); /* Convert the second operand component to the result type. */ \
1050        } /* Finish this component or matrix pass. */ \
1051        return out; /* Return the completed result. */ \
1052    } /* Finish this generated overload. */
1053SHDR_DETAIL_MATH_BINARY(atan, std::is_floating_point<T>::value, std::atan2(x, y)) // Compute the inverse tangent for scalars and vector components.
1054SHDR_DETAIL_MATH_BINARY(pow, std::is_floating_point<T>::value, std::pow(x, y)) // Raise each base to its exponent.
1055SHDR_DETAIL_MATH_BINARY(mod, std::is_floating_point<T>::value, x - y * std::floor(x / y)) // Use the GLSL floor-based remainder.
1056SHDR_DETAIL_MATH_BINARY(min, std::is_arithmetic<T>::value, y < x ? y : x) // Choose the smaller value.
1057SHDR_DETAIL_MATH_BINARY(max, std::is_arithmetic<T>::value, x < y ? y : x) // Choose the larger value.
1058SHDR_DETAIL_MATH_BINARY(step, std::is_floating_point<T>::value, y < x ? T(0) : T(1)) // Return zero below the edge and one otherwise.
1059#undef SHDR_DETAIL_MATH_BINARY // Remove this local code generator macro.
1060/** @brief Fused multiply-add.  final rounding may differ across CPU/GPU. */
1061template <class T> // Accept the matching input types and dimensions.
1062typename std::enable_if<std::is_floating_point<T>::value, T>::type fma(T a, T b, T c) { // Enable this overload only for compatible input types.
1063    return std::fma(a, b, c); // Multiply and add with one final rounding.
1064} // Finish the fma operation.
1065template <class A, class B, class C> // Accept the matching input types and dimensions.
1066typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1067fma(const A& a, const B& b, const C& c) { // Multiply and add with one final rounding.
1068    static_assert(detail::binary<A, B>::valid && detail::binary<A, C>::valid, // Check this type or dimension requirement at compile time.
1069                  "fma dimensions mismatch"); // Explain the rejected input: fma dimensions mismatch.
1070    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1071    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1072    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1073        out[i] = glsl::fma( // Store the computed component in the independent result.
1074            a[i], static_cast<T>(detail::component(b, i)), static_cast<T>(detail::component(c, i))); // Supply the matching three components to fused multiply-add.
1075    return out; // Return the completed result.
1076} // Finish the fma operation.
1077template <class T> // Accept the matching input types and dimensions.
1078typename std::enable_if<std::is_arithmetic<T>::value, T>::type clamp(T x, T lower, T upper) { // Enable this overload only for compatible input types.
1079    return glsl::min(glsl::max(x, lower), upper); // Keep a value between its lower and upper limits.
1080} // Finish the clamp operation.
1081template <class A, class B, class C> // Accept the matching input types and dimensions.
1082typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1083clamp(const A& a, const B& lower, const C& upper) { // Keep a value between its lower and upper limits.
1084    static_assert(detail::binary<A, B>::valid && detail::binary<A, C>::valid, // Check this type or dimension requirement at compile time.
1085                  "clamp dimensions mismatch"); // Explain the rejected input: clamp dimensions mismatch.
1086    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1087    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1088    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1089        out[i] = glsl::clamp(a[i], // Store the computed component in the independent result.
1090                             static_cast<T>(detail::component(lower, i)), // Use the matching lower bound component.
1091                             static_cast<T>(detail::component(upper, i))); // Use the matching upper bound component.
1092    return out; // Return the completed result.
1093} // Finish the clamp operation.
1094template <class T, class U> // Accept the matching input types and dimensions.
1095typename std::enable_if<std::is_floating_point<T>::value && std::is_arithmetic<U>::value && // Enable this overload only for compatible input types.
1096                            !std::is_same<U, bool>::value, // Complete the type and dimension rule for this overload.
1097                        T>::type // Complete the type and dimension rule for this overload.
1098mix(T x, T y, U selector) { // Blend values or select one with a boolean.
1099    T a = static_cast<T>(selector); // Convert the interpolation amount to the component type.
1100    return x * (T(1) - a) + y * a; // Blend values or select one with a boolean.
1101} // Finish the mix operation.
1102template <class T, class B> // Accept the matching input types and dimensions.
1103typename std::enable_if<std::is_arithmetic<T>::value && std::is_same<B, bool>::value, T>::type // Enable this overload only for compatible input types.
1104mix(T x, T y, B a) { // Blend values or select one with a boolean.
1105    return a ? y : x; // Blend values or select one with a boolean.
1106} // Finish the mix operation.
1107template <class A, class B, class C> // Accept the matching input types and dimensions.
1108typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1109mix(const A& a, const B& b, const C& selector) { // Blend values or select one with a boolean.
1110    static_assert(detail::binary<A, B>::valid && detail::binary<A, C>::valid, // Check this type or dimension requirement at compile time.
1111                  "mix dimensions mismatch"); // Explain the rejected input: mix dimensions mismatch.
1112    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1113    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1114    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1115        out[i] = glsl::mix( // Store the computed component in the independent result.
1116            a[i], static_cast<T>(detail::component(b, i)), detail::component(selector, i)); // Blend or select the matching input components.
1117    return out; // Return the completed result.
1118} // Finish the mix operation.
1119template <class T> // Accept the matching input types and dimensions.
1120typename std::enable_if<std::is_floating_point<T>::value, T>::type // Enable this overload only for compatible input types.
1121smoothstep(T lower, T upper, T x) { // Interpolate smoothly between two edges.
1122    T t = glsl::clamp((x - lower) / (upper - lower), T(0), T(1)); // Map the input into a clamped zero-to-one interval.
1123    return t * t * (T(3) - T(2) * t); // Interpolate smoothly between two edges.
1124} // Finish the smoothstep operation.
1125template <class A, class B, class C> // Accept the matching input types and dimensions.
1126typename std::enable_if<detail::traits<C>::vector, typename detail::result<C>::type>::type // Enable this overload only for compatible input types.
1127smoothstep(const A& lower, const B& upper, const C& x) { // Interpolate smoothly between two edges.
1128    static_assert(detail::binary<C, A>::valid && detail::binary<C, B>::valid, // Check this type or dimension requirement at compile time.
1129                  "smoothstep dimensions mismatch"); // Explain the rejected input: smoothstep dimensions mismatch.
1130    typedef typename detail::traits<C>::scalar T; // Keep the chosen component type for the calculation.
1131    typename detail::result<C>::type out; // Allocate an independent result with the correct shape.
1132    for (std::size_t i = 0; i < detail::traits<C>::size; ++i) // Visit each component needed by this calculation.
1133        out[i] = glsl::smoothstep(static_cast<T>(detail::component(lower, i)), // Store the computed component in the independent result.
1134                                  static_cast<T>(detail::component(upper, i)), // Use the matching upper interpolation edge.
1135                                  x[i]); // Interpolate this input component between its edges.
1136    return out; // Return the completed result.
1137} // Finish the smoothstep operation.
1138template <class T> // Accept the matching input types and dimensions.
1139typename std::enable_if<std::is_floating_point<T>::value, bool>::type isnan(T x) { // Enable this overload only for compatible input types.
1140    return std::isnan(x); // Check whether the value is not a number.
1141} // Finish the isnan operation.
1142template <class T> // Accept the matching input types and dimensions.
1143typename std::enable_if<std::is_floating_point<T>::value, bool>::type isinf(T x) { // Enable this overload only for compatible input types.
1144    return std::isinf(x); // Check whether the value is infinite.
1145} // Finish the isinf operation.
1146#define SHDR_DETAIL_CLASSIFICATION(NAME) /* Generate the matching scalar and vector overloads. */ \
1147    template <class A> /* Accept the matching input types and dimensions. */ \
1148    typename std::enable_if<detail::traits<A>::vector, vec<bool, detail::traits<A>::size>>::type /* Enable this overload only for compatible input types. */ \
1149    NAME(const A& a) { /* Start the matching math overload. */ \
1150        vec<bool, detail::traits<A>::size> out; /* Keep an independent value for the result or aliased inputs. */ \
1151        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
1152            out[i] = glsl::NAME(a[i]); /* Store the computed component in the independent result. */ \
1153        return out; /* Return the completed result. */ \
1154    } /* Finish this generated overload. */
1155SHDR_DETAIL_CLASSIFICATION(isnan) // Check whether the value is not a number.
1156SHDR_DETAIL_CLASSIFICATION(isinf) // Check whether the value is infinite.
1157#undef SHDR_DETAIL_CLASSIFICATION // Remove this local code generator macro.
1158template <class T> // Accept the matching input types and dimensions.
1159typename std::enable_if<std::is_floating_point<T>::value, T>::type modf(T x, T& integer) { // Enable this overload only for compatible input types.
1160    return std::modf(x, &integer); // Separate fractional and integral components.
1161} // Finish the modf operation.
1162/** @brief Split a vector into signed fractional and integer parts.
1163 * The return value contains fractional components.  integer receives the
1164 * integral components. Both arguments may be swizzles, including selections
1165 * of the same vector, because the input is copied before output assignment.
1166 */
1167template <class A, class B> // Accept the matching input types and dimensions.
1168typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1169                        typename detail::result<A>::type>::type // Preserve the selected component type and result shape.
1170modf(const A& x, B&& integer) { // Separate fractional and integral components.
1171    static_assert(detail::traits<A>::size == detail::traits<B>::size, "modf dimensions mismatch"); // Require matching component counts.
1172    static_assert( // Check this type or dimension requirement at compile time.
1173        std::is_same<typename detail::traits<A>::scalar, typename detail::traits<B>::scalar>::value, // Require the input and output component types to match.
1174        "modf component types must match"); // Explain the rejected input: modf component types must match.
1175    static_assert(detail::writable<B>::value, "modf output requires writable unique components"); // Prevent repeated destination components.
1176    typename detail::result<A>::type input(x), out, integral; // Preserve the selected component type and result shape.
1177    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1178        out[i] = glsl::modf(input[i], integral[i]); // Store the computed component in the independent result.
1179    integer = integral; // Publish all integral components after reading the input.
1180    return out; // Return the completed result.
1181} // Finish the modf operation.
1182template <class T> // Accept the matching input types and dimensions.
1183typename std::enable_if<std::is_floating_point<T>::value, T>::type frexp(T x, int& exponent) { // Enable this overload only for compatible input types.
1184    return std::frexp(x, &exponent); // Separate a significand and its binary exponent.
1185} // Finish the frexp operation.
1186/** @brief Return binary significands and write matching signed exponents.
1187 * Each nonzero component satisfies x = significand * 2^exponent. Output may be
1188 * an integer vector or a writable swizzle with matching component count.
1189 */
1190template <class A, class B> // Accept the matching input types and dimensions.
1191typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1192                        typename detail::result<A>::type>::type // Preserve the selected component type and result shape.
1193frexp(const A& x, B&& exponent) { // Separate a significand and its binary exponent.
1194    static_assert(detail::traits<A>::size == detail::traits<B>::size, "frexp dimensions mismatch"); // Require matching component counts.
1195    static_assert(std::is_same<typename detail::traits<B>::scalar, std::int32_t>::value, // Check this type or dimension requirement at compile time.
1196                  "frexp requires signed integer exponent components"); // Explain the rejected input: frexp requires signed integer exponent components.
1197    static_assert(detail::writable<B>::value, "frexp output requires writable unique components"); // Prevent repeated destination components.
1198    typename detail::result<A>::type input(x), out; // Allocate an independent result with the correct shape.
1199    vec<std::int32_t, detail::traits<A>::size> powers; // Use the selected vector or matrix shape for this value.
1200    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { // Visit each component needed by this calculation.
1201        int e = 0; // Prepare a signed exponent for this component.
1202        out[i] = std::frexp(input[i], &e); // Store the computed component in the independent result.
1203        powers[i] = e; // Store the binary exponent for this component.
1204    } // Finish this component or matrix pass.
1205    exponent = powers; // Publish all exponents after reading the input.
1206    return out; // Return the completed result.
1207} // Finish the frexp operation.
1208template <class T> // Accept the matching input types and dimensions.
1209typename std::enable_if<std::is_floating_point<T>::value, T>::type ldexp(T x, int exponent) { // Enable this overload only for compatible input types.
1210    return std::ldexp(x, exponent); // Scale a significand by a power of two.
1211} // Finish the ldexp operation.
1212/** @brief Multiply each component by two raised to its signed integer exponent. */
1213template <class A, class B> // Accept the matching input types and dimensions.
1214typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1215                        typename detail::result<A>::type>::type // Preserve the selected component type and result shape.
1216ldexp(const A& x, const B& exponent) { // Scale a significand by a power of two.
1217    static_assert(detail::traits<A>::size == detail::traits<B>::size, "ldexp dimensions mismatch"); // Require matching component counts.
1218    static_assert(std::is_same<typename detail::traits<B>::scalar, std::int32_t>::value, // Check this type or dimension requirement at compile time.
1219                  "ldexp requires signed integer exponent components"); // Explain the rejected input: ldexp requires signed integer exponent components.
1220    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1221    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1222        out[i] = std::ldexp(x[i], exponent[i]); // Store the computed component in the independent result.
1223    return out; // Return the completed result.
1224} // Finish the ldexp operation.
1225/** @} */
1226
1227/** @name Geometry
1228 * Geometry uses scalar dot products and GLSL's usual component formulas.
1229 * normalize requires nonzero length. Inputs to reflect, refract and faceforward
1230 * should obey GLSL's normalized-normal requirements.
1231 * @{ */
1232template <class T> // Accept the matching input types and dimensions.
1233typename std::enable_if<std::is_floating_point<T>::value, T>::type dot(T a, T b) { // Enable this overload only for compatible input types.
1234    return a * b; // Sum products of corresponding components.
1235} // Finish the dot operation.
1236template <class A, class B> // Accept the matching input types and dimensions.
1237typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1238                        typename detail::traits<A>::scalar>::type // Preserve the selected component type and result shape.
1239dot(const A& a, const B& b) { // Sum products of corresponding components.
1240    static_assert(detail::traits<A>::size == detail::traits<B>::size, "dot dimensions mismatch"); // Require matching component counts.
1241    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1242    T out(0); // Start the scalar accumulator at zero.
1243    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { // Visit each component needed by this calculation.
1244        out += a[i] * b[i]; // Add this component product to the running total.
1245    } // Finish this component or matrix pass.
1246    return out; // Return the completed result.
1247} // Finish the dot operation.
1248template <class T> typename std::enable_if<std::is_floating_point<T>::value, T>::type length(T x) { // Accept the matching input types and dimensions.
1249    return glsl::abs(x); // Return the component count or geometric length.
1250} // Finish the length operation.
1251template <class A> // Accept the matching input types and dimensions.
1252typename std::enable_if<detail::traits<A>::vector, typename detail::traits<A>::scalar>::type // Enable this overload only for compatible input types.
1253length(const A& a) { // Return the component count or geometric length.
1254    return glsl::sqrt(glsl::dot(a, a)); // Return the component count or geometric length.
1255} // Finish the length operation.
1256template <class A, class B> auto distance(const A& a, const B& b) -> decltype(glsl::length(a - b)) { // Accept the matching input types and dimensions.
1257    return glsl::length(a - b); // Measure the length of the difference.
1258} // Finish the distance operation.
1259template <class A, class B> // Accept the matching input types and dimensions.
1260typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
1261                            detail::traits<A>::size == 3 && detail::traits<B>::size == 3, // Complete the type and dimension rule for this overload.
1262                        vec<typename detail::traits<A>::scalar, 3>>::type // Preserve the selected component type and result shape.
1263cross(const A& a, const B& b) { // Compute the three-dimensional cross product.
1264    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1265    return vec<T, 3>( // Compute the three-dimensional cross product.
1266        a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]); // Use the three signed two-by-two minors for the cross product.
1267} // Finish the cross operation.
1268template <class A> // Accept the matching input types and dimensions.
1269typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1270normalize(const A& a) { // Scale a nonzero value to unit length.
1271    return a / glsl::length(a); // Scale a nonzero value to unit length.
1272} // Finish the normalize operation.
1273template <class A, class B, class C> // Accept the matching input types and dimensions.
1274typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1275faceforward(const A& normal, const B& incident, const C& reference) { // Choose the normal direction facing the incident vector.
1276    return glsl::dot(reference, incident) < 0 ? normal : -normal; // Choose the normal direction facing the incident vector.
1277} // Finish the faceforward operation.
1278template <class A, class B> // Accept the matching input types and dimensions.
1279typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1280reflect(const A& incident, const B& normal) { // Reflect an incident vector around its normal.
1281    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1282    return incident - T(2) * glsl::dot(normal, incident) * normal; // Reflect an incident vector around its normal.
1283} // Finish the reflect operation.
1284template <class A, class B> // Accept the matching input types and dimensions.
1285typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1286refract(const A& incident, const B& normal, typename detail::traits<A>::scalar eta) { // Refract an incident vector using the index ratio.
1287    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1288    T d = glsl::dot(normal, incident); // Measure the incident component along the normal.
1289    T k = T(1) - eta * eta * (T(1) - d * d); // Compute the refraction discriminant before taking its root.
1290    return k < T(0) ? typename detail::result<A>::type(T(0)) // Refract an incident vector using the index ratio.
1291                    : eta * incident - (eta * d + glsl::sqrt(k)) * normal; // Apply the transmitted-direction formula when refraction is possible.
1292} // Finish the refract operation.
1293/** @} */
1294
1295/** @name Vector relational functions
1296 * operator== compares the whole vector and returns bool. These builtins return
1297 * component masks. logicalNot is the C++ spelling of GLSL's reserved `not`.
1298 * @{ */
1299#define SHDR_DETAIL_RELATIONAL(NAME, OP) /* Generate the matching scalar and vector overloads. */ \
1300    template <class A, class B> /* Accept the matching input types and dimensions. */ \
1301    typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, /* Enable this overload only for compatible input types. */ \
1302                            vec<bool, detail::traits<A>::size>>::type /* Use the selected vector or matrix shape for this value. */ \
1303    NAME(const A& a, const B& b) { /* Start the matching math overload. */ \
1304        static_assert(detail::traits<A>::size == detail::traits<B>::size, /* Require matching component counts. */ \
1305                      "relational dimensions mismatch"); /* Explain the rejected input: relational dimensions mismatch. */ \
1306        vec<bool, detail::traits<A>::size> out; /* Keep an independent value for the result or aliased inputs. */ \
1307        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
1308            out[i] = a[i] OP b[i]; /* Store the computed component in the independent result. */ \
1309        return out; /* Return the completed result. */ \
1310    } /* Finish this generated overload. */
1311SHDR_DETAIL_RELATIONAL(lessThan, <) // Provide the requested component operation.
1312SHDR_DETAIL_RELATIONAL(lessThanEqual, <=) // Provide the requested component operation.
1313SHDR_DETAIL_RELATIONAL(greaterThan, >) // Provide the requested component operation.
1314SHDR_DETAIL_RELATIONAL(greaterThanEqual, >=) // Provide the requested component operation.
1315SHDR_DETAIL_RELATIONAL(equal, ==) // Provide the requested component operation.
1316SHDR_DETAIL_RELATIONAL(notEqual, !=) // Provide the requested component operation.
1317#undef SHDR_DETAIL_RELATIONAL // Remove this local code generator macro.
1318template <class A> typename std::enable_if<detail::traits<A>::vector, bool>::type any(const A& a) { // Accept the matching input types and dimensions.
1319    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1320        if (a[i]) // Handle the exceptional or boundary case before continuing.
1321            return true; // Report that every required component matched.
1322    return false; // Report that at least one component differs.
1323} // Finish the any operation.
1324template <class A> typename std::enable_if<detail::traits<A>::vector, bool>::type all(const A& a) { // Accept the matching input types and dimensions.
1325    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1326        if (!a[i]) // Handle the exceptional or boundary case before continuing.
1327            return false; // Report that at least one component differs.
1328    return true; // Report that every required component matched.
1329} // Finish the all operation.
1330template <class A> // Accept the matching input types and dimensions.
1331typename std::enable_if<detail::traits<A>::vector, vec<bool, detail::traits<A>::size>>::type // Enable this overload only for compatible input types.
1332logicalNot(const A& a) { // Invert each boolean component.
1333    vec<bool, detail::traits<A>::size> out; // Keep an independent value for the result or aliased inputs.
1334    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1335        out[i] = !a[i]; // Store the computed component in the independent result.
1336    return out; // Return the completed result.
1337} // Finish the logicalNot operation.
1338template <class A> // Accept the matching input types and dimensions.
1339typename std::enable_if<detail::traits<A>::vector, vec<bool, detail::traits<A>::size>>::type // Enable this overload only for compatible input types.
1340_not(const A& a) { // Start the matching math overload.
1341    return glsl::logicalNot(a); // Invert each boolean component.
1342} // Finish the _not operation.
1343/** @} */
1344/** @name 32-bit bit operations
1345 * Reinterpretation uses memcpy and requires IEEE binary32 floats and 32-bit
1346 * integers. Bitfield ranges must satisfy 0 <= offset,bits and offset+bits<=32.
1347 * The 64-bit host intermediates in extended multiplication are never exposed
1348 * to shared shaders. Bit searches and counts return signed integer results.
1349 * @{ */
1350namespace detail { // Keep these names inside the detail namespace.
1351template <class To, class From> To bit_copy(const From& value) { // Accept the matching input types and dimensions.
1352    static_assert(sizeof(To) == sizeof(From), "bit conversion requires equal sizes"); // Check this type or dimension requirement at compile time.
1353    To out; // Allocate a destination with the same bit width.
1354    std::memcpy(&out, &value, sizeof(out)); // Copy the bits with the alias-safe byte-copy operation.
1355    return out; // Return the completed result.
1356} // Finish the bit_copy operation.
1357inline std::uint32_t bit_mask(int bits) { // Start the matching math overload.
1358    return bits == 32 ? UINT32_MAX : (bits == 0 ? 0u : (std::uint32_t(1) << bits) - 1u); // Invert each boolean component.
1359} // Finish the bit_mask operation.
1360template <class T> // Accept the matching input types and dimensions.
1361struct integer32 : std::integral_constant<bool, // Describe this input or selection at compile time.
1362                                          std::is_integral<T>::value && // Require integer components for the bit operation.
1363                                              !std::is_same<T, bool>::value && sizeof(T) == 4> {}; // Complete the type and dimension rule for this overload.
1364} // namespace detail
1365inline std::uint32_t floatBitsToUint(float x) { // Copy float bits into an unsigned integer.
1366    static_assert(sizeof(float) == 4 && std::numeric_limits<float>::is_iec559, // Check this type or dimension requirement at compile time.
1367                  "IEEE binary32 float required"); // Explain the rejected input: IEEE binary32 float required.
1368    return detail::bit_copy<std::uint32_t>(x); // Copy float bits into an unsigned integer.
1369} // Finish the floatBitsToUint operation.
1370inline std::int32_t floatBitsToInt(float x) { // Copy float bits into a signed integer.
1371    return detail::bit_copy<std::int32_t>(x); // Copy float bits into a signed integer.
1372} // Finish the floatBitsToInt operation.
1373inline float uintBitsToFloat(std::uint32_t x) { // Copy unsigned integer bits into a float.
1374    return detail::bit_copy<float>(x); // Copy unsigned integer bits into a float.
1375} // Finish the uintBitsToFloat operation.
1376inline float intBitsToFloat(std::int32_t x) { // Copy signed integer bits into a float.
1377    return detail::bit_copy<float>(x); // Copy signed integer bits into a float.
1378} // Finish the intBitsToFloat operation.
1379#define SHDR_DETAIL_BIT_VECTOR(NAME, OUT_T) /* Generate the matching scalar and vector overloads. */ \
1380    template <class A> /* Accept the matching input types and dimensions. */ \
1381    typename std::enable_if<detail::traits<A>::vector, vec<OUT_T, detail::traits<A>::size>>::type /* Enable this overload only for compatible input types. */ \
1382    NAME(const A& a) { /* Start the matching math overload. */ \
1383        vec<OUT_T, detail::traits<A>::size> out; /* Keep an independent value for the result or aliased inputs. */ \
1384        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
1385            out[i] = glsl::NAME(a[i]); /* Store the computed component in the independent result. */ \
1386        return out; /* Return the completed result. */ \
1387    } /* Finish this generated overload. */
1388SHDR_DETAIL_BIT_VECTOR(floatBitsToUint, std::uint32_t) // Copy float bits into an unsigned integer.
1389SHDR_DETAIL_BIT_VECTOR(floatBitsToInt, std::int32_t) // Copy float bits into a signed integer.
1390SHDR_DETAIL_BIT_VECTOR(uintBitsToFloat, float) // Copy unsigned integer bits into a float.
1391SHDR_DETAIL_BIT_VECTOR(intBitsToFloat, float) // Copy signed integer bits into a float.
1392template <class T> // Accept the matching input types and dimensions.
1393typename std::enable_if<detail::integer32<T>::value, std::int32_t>::type bitCount(T x) { // Enable this overload only for compatible input types.
1394    std::uint32_t v = static_cast<std::uint32_t>(x); // Hold the exact integer bits used by this operation.
1395    std::int32_t count = 0; // Hold the exact integer bits used by this operation.
1396    while (v) { // Continue until the remaining bits reach the required form.
1397        v &= v - 1u; // Remove the least significant set bit.
1398        ++count; // Count the set bit that was removed.
1399    } // Finish this component or matrix pass.
1400    return count; // Count the set bits in a 32-bit value.
1401} // Finish the bitCount operation.
1402template <class T> // Accept the matching input types and dimensions.
1403typename std::enable_if<detail::integer32<T>::value, std::int32_t>::type findLSB(T x) { // Enable this overload only for compatible input types.
1404    std::uint32_t v = static_cast<std::uint32_t>(x); // Hold the exact integer bits used by this operation.
1405    if (!v) // Handle the exceptional or boundary case before continuing.
1406        return -1; // Find the first set bit from the least significant end.
1407    std::int32_t position = 0; // Hold the exact integer bits used by this operation.
1408    while (!(v & 1u)) { // Continue until the remaining bits reach the required form.
1409        v >>= 1; // Move the next bit into the least significant position.
1410        ++position; // Advance the bit position being tested.
1411    } // Finish this component or matrix pass.
1412    return position; // Find the first set bit from the least significant end.
1413} // Finish the findLSB operation.
1414template <class T> // Accept the matching input types and dimensions.
1415typename std::enable_if<detail::integer32<T>::value, std::int32_t>::type findMSB(T x) { // Enable this overload only for compatible input types.
1416    std::uint32_t v = static_cast<std::uint32_t>(x); // Hold the exact integer bits used by this operation.
1417    if (std::is_signed<T>::value && x < T(0)) // Handle the exceptional or boundary case before continuing.
1418        v = ~v; // For negative values, search for the highest zero bit.
1419    std::int32_t position = -1; // Hold the exact integer bits used by this operation.
1420    while (v) { // Continue until the remaining bits reach the required form.
1421        v >>= 1; // Move the next bit into the least significant position.
1422        ++position; // Advance the bit position being tested.
1423    } // Finish this component or matrix pass.
1424    return position; // Find the highest bit that differs from the sign bit.
1425} // Finish the findMSB operation.
1426SHDR_DETAIL_BIT_VECTOR(bitCount, std::int32_t) // Count the set bits in a 32-bit value.
1427SHDR_DETAIL_BIT_VECTOR(findLSB, std::int32_t) // Find the first set bit from the least significant end.
1428SHDR_DETAIL_BIT_VECTOR(findMSB, std::int32_t) // Find the highest bit that differs from the sign bit.
1429#undef SHDR_DETAIL_BIT_VECTOR // Remove this local code generator macro.
1430template <class T> // Accept the matching input types and dimensions.
1431typename std::enable_if<detail::integer32<T>::value, T>::type bitfieldReverse(T x) { // Enable this overload only for compatible input types.
1432    std::uint32_t v = static_cast<std::uint32_t>(x), out = 0; // Hold the exact integer bits used by this operation.
1433    for (int i = 0; i < 32; ++i) { // Visit all 32 bits of the value.
1434        out = (out << 1) | (v & 1u); // Append the current low bit in reversed order.
1435        v >>= 1; // Move the next bit into the least significant position.
1436    } // Finish this component or matrix pass.
1437    return detail::bit_copy<T>(out); // Reverse all 32 bits.
1438} // Finish the bitfieldReverse operation.
1439template <class A> // Accept the matching input types and dimensions.
1440typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1441bitfieldReverse(const A& a) { // Reverse all 32 bits.
1442    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1443    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1444        out[i] = glsl::bitfieldReverse(a[i]); // Store the computed component in the independent result.
1445    return out; // Return the completed result.
1446} // Finish the bitfieldReverse operation.
1447template <class T> // Accept the matching input types and dimensions.
1448typename std::enable_if<detail::integer32<T>::value, T>::type // Enable this overload only for compatible input types.
1449bitfieldExtract(T value, int offset, int bits) { // Extract the requested bit range.
1450    if (bits == 0 || offset < 0 || bits < 0 || offset > 32 - bits) // Handle an empty bit field separately.
1451        return T(0); // Extract the requested bit range.
1452    std::uint32_t mask = detail::bit_mask(bits), // Prepare the mask for the requested bit range.
1453                  out = (static_cast<std::uint32_t>(value) >> offset) & mask; // Shift the selected field down and discard other bits.
1454    if (std::is_signed<T>::value && bits < 32 && (out & (std::uint32_t(1) << (bits - 1)))) // Handle the exceptional or boundary case before continuing.
1455        out |= ~mask; // Add the encoded field to its packed bit position.
1456    return detail::bit_copy<T>(out); // Extract the requested bit range.
1457} // Finish the bitfieldExtract operation.
1458template <class A> // Accept the matching input types and dimensions.
1459typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1460bitfieldExtract(const A& a, int offset, int bits) { // Extract the requested bit range.
1461    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1462    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1463        out[i] = glsl::bitfieldExtract(a[i], offset, bits); // Store the computed component in the independent result.
1464    return out; // Return the completed result.
1465} // Finish the bitfieldExtract operation.
1466template <class T> // Accept the matching input types and dimensions.
1467typename std::enable_if<detail::integer32<T>::value, T>::type // Enable this overload only for compatible input types.
1468bitfieldInsert(T base, T insert, int offset, int bits) { // Replace the requested bit range.
1469    if (bits == 0 || offset < 0 || bits < 0 || offset > 32 - bits) // Handle an empty bit field separately.
1470        return base; // Replace the requested bit range.
1471    std::uint32_t mask = detail::bit_mask(bits) << offset; // Prepare the mask for the requested bit range.
1472    std::uint32_t out = (static_cast<std::uint32_t>(base) & ~mask) | // Prepare the mask for the requested bit range.
1473                        ((static_cast<std::uint32_t>(insert) << offset) & mask); // Keep only insertion bits that belong to the selected field.
1474    return detail::bit_copy<T>(out); // Replace the requested bit range.
1475} // Finish the bitfieldInsert operation.
1476template <class A, class B> // Accept the matching input types and dimensions.
1477typename std::enable_if<detail::binary<A, B>::valid, typename detail::binary<A, B>::result>::type // Enable this overload only for compatible input types.
1478bitfieldInsert(const A& base, const B& insert, int offset, int bits) { // Replace the requested bit range.
1479    typedef typename detail::binary<A, B>::scalar T; // Keep the chosen component type for the calculation.
1480    typename detail::binary<A, B>::result out; // Allocate an independent result with the correct shape.
1481    for (std::size_t i = 0; i < detail::binary<A, B>::size; ++i) // Visit each component needed by this calculation.
1482        out[i] = glsl::bitfieldInsert(static_cast<T>(detail::component(base, i)), // Store the computed component in the independent result.
1483                                      static_cast<T>(detail::component(insert, i)), // Use this component as the replacement bit pattern.
1484                                      offset, // Use the requested first bit position.
1485                                      bits); // Use the requested number of replacement bits.
1486    return out; // Return the completed result.
1487} // Finish the bitfieldInsert operation.
1488inline std::uint32_t uaddCarry(std::uint32_t x, std::uint32_t y, std::uint32_t& carry) { // Add unsigned values and report the carry.
1489    std::uint64_t sum = std::uint64_t(x) + y; // Use a wider integer to retain carry or product bits.
1490    carry = std::uint32_t(sum >> 32); // Publish the extra word after the input values have been copied.
1491    return std::uint32_t(sum); // Add unsigned values and report the carry.
1492} // Finish the uaddCarry operation.
1493inline std::uint32_t usubBorrow(std::uint32_t x, std::uint32_t y, std::uint32_t& borrow) { // Subtract unsigned values and report the borrow.
1494    borrow = x < y ? 1u : 0u; // Publish the extra word after the input values have been copied.
1495    return x - y; // Subtract unsigned values and report the borrow.
1496} // Finish the usubBorrow operation.
1497inline void umulExtended(std::uint32_t x, std::uint32_t y, std::uint32_t& msb, std::uint32_t& lsb) { // Split a full unsigned product into two words.
1498    std::uint64_t product = std::uint64_t(x) * y; // Use a wider integer to retain carry or product bits.
1499    msb = std::uint32_t(product >> 32); // Publish the extra word after the input values have been copied.
1500    lsb = std::uint32_t(product); // Publish the extra word after the input values have been copied.
1501} // Finish the umulExtended operation.
1502inline void imulExtended(std::int32_t x, std::int32_t y, std::int32_t& msb, std::int32_t& lsb) { // Split a full signed product into two words.
1503    std::uint64_t product = static_cast<std::uint64_t>(std::int64_t(x) * y); // Use a wider integer to retain carry or product bits.
1504    msb = detail::bit_copy<std::int32_t>(std::uint32_t(product >> 32)); // Publish the extra word after the input values have been copied.
1505    lsb = detail::bit_copy<std::int32_t>(std::uint32_t(product)); // Publish the extra word after the input values have been copied.
1506} // Finish the imulExtended operation.
1507/** @brief Add unsigned vectors modulo 2^32 and write their carry flags. */
1508template <class A, class B, class C> // Accept the matching input types and dimensions.
1509typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
1510                            detail::traits<C>::vector, // Complete the type and dimension rule for this overload.
1511                        vec<std::uint32_t, detail::traits<A>::size>>::type // Use the selected vector or matrix shape for this value.
1512uaddCarry(const A& x, const B& y, C&& carry) { // Add unsigned values and report the carry.
1513    static_assert(detail::traits<A>::size == detail::traits<B>::size && // Require matching component counts.
1514                      detail::traits<A>::size == detail::traits<C>::size, // Complete the type and dimension rule for this overload.
1515                  "uaddCarry dimensions mismatch"); // Explain the rejected input: uaddCarry dimensions mismatch.
1516    static_assert(std::is_same<typename detail::traits<A>::scalar, std::uint32_t>::value && // Check this type or dimension requirement at compile time.
1517                      std::is_same<typename detail::traits<B>::scalar, std::uint32_t>::value && // Require the second input to contain unsigned 32-bit components.
1518                      std::is_same<typename detail::traits<C>::scalar, std::uint32_t>::value, // Require an unsigned 32-bit carry or borrow output.
1519                  "uaddCarry requires unsigned integer components"); // Explain the rejected input: uaddCarry requires unsigned integer components.
1520    static_assert(detail::writable<C>::value, // Require distinct writable output components.
1521                  "uaddCarry output requires writable unique components"); // Explain the rejected input: uaddCarry output requires writable unique components.
1522    vec<std::uint32_t, detail::traits<A>::size> a(x), b(y), out, flags; // Keep an independent value for the result or aliased inputs.
1523    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1524        out[i] = glsl::uaddCarry(a[i], b[i], flags[i]); // Store the computed component in the independent result.
1525    carry = flags; // Publish the extra word after the input values have been copied.
1526    return out; // Return the completed result.
1527} // Finish the uaddCarry operation.
1528/** @brief Subtract unsigned vectors modulo 2^32 and write their borrow flags. */
1529template <class A, class B, class C> // Accept the matching input types and dimensions.
1530typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
1531                            detail::traits<C>::vector, // Complete the type and dimension rule for this overload.
1532                        vec<std::uint32_t, detail::traits<A>::size>>::type // Use the selected vector or matrix shape for this value.
1533usubBorrow(const A& x, const B& y, C&& borrow) { // Subtract unsigned values and report the borrow.
1534    static_assert(detail::traits<A>::size == detail::traits<B>::size && // Require matching component counts.
1535                      detail::traits<A>::size == detail::traits<C>::size, // Complete the type and dimension rule for this overload.
1536                  "usubBorrow dimensions mismatch"); // Explain the rejected input: usubBorrow dimensions mismatch.
1537    static_assert(std::is_same<typename detail::traits<A>::scalar, std::uint32_t>::value && // Check this type or dimension requirement at compile time.
1538                      std::is_same<typename detail::traits<B>::scalar, std::uint32_t>::value && // Require the second input to contain unsigned 32-bit components.
1539                      std::is_same<typename detail::traits<C>::scalar, std::uint32_t>::value, // Require an unsigned 32-bit carry or borrow output.
1540                  "usubBorrow requires unsigned integer components"); // Explain the rejected input: usubBorrow requires unsigned integer components.
1541    static_assert(detail::writable<C>::value, // Require distinct writable output components.
1542                  "usubBorrow output requires writable unique components"); // Explain the rejected input: usubBorrow output requires writable unique components.
1543    vec<std::uint32_t, detail::traits<A>::size> a(x), b(y), out, flags; // Keep an independent value for the result or aliased inputs.
1544    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1545        out[i] = glsl::usubBorrow(a[i], b[i], flags[i]); // Store the computed component in the independent result.
1546    borrow = flags; // Publish the extra word after the input values have been copied.
1547    return out; // Return the completed result.
1548} // Finish the usubBorrow operation.
1549#define SHDR_DETAIL_EXTENDED(NAME, T) /* Generate the matching scalar and vector overloads. */ \
1550    template <class A, class B, class C, class D> /* Accept the matching input types and dimensions. */ \
1551    typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && /* Enable this overload only for compatible input types. */ \
1552                            detail::traits<C>::vector && detail::traits<D>::vector>::type /* Complete the type and dimension rule for this overload. */ \
1553    NAME(const A& x, const B& y, C&& msb, D&& lsb) { /* Start the matching math overload. */ \
1554        static_assert(detail::traits<A>::size == detail::traits<B>::size && /* Require matching component counts. */ \
1555                          detail::traits<A>::size == detail::traits<C>::size && /* Complete the type and dimension rule for this overload. */ \
1556                          detail::traits<A>::size == detail::traits<D>::size, /* Complete the type and dimension rule for this overload. */ \
1557                      "extended multiplication dimensions mismatch"); /* Explain the rejected input: extended multiplication dimensions mismatch. */ \
1558        static_assert(std::is_same<typename detail::traits<A>::scalar, T>::value && /* Check this type or dimension requirement at compile time. */ \
1559                          std::is_same<typename detail::traits<B>::scalar, T>::value && /* Require the second input to use the selected integer type. */ \
1560                          std::is_same<typename detail::traits<C>::scalar, T>::value && /* Require the high output word to use the selected integer type. */ \
1561                          std::is_same<typename detail::traits<D>::scalar, T>::value, /* Require the low output word to use the selected integer type. */ \
1562                      "extended multiplication component types must match"); /* Explain the rejected input: extended multiplication component types must match. */ \
1563        static_assert(detail::writable<C>::value && detail::writable<D>::value, /* Require distinct writable output components. */ \
1564                      "extended multiplication requires writable unique output components"); /* Explain the rejected input: extended multiplication requires writable unique output components. */ \
1565        vec<T, detail::traits<A>::size> a(x), b(y), high, low; /* Keep an independent value for the result or aliased inputs. */ \
1566        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { /* Visit each component needed by this calculation. */ \
1567            glsl::NAME(a[i], b[i], high[i], low[i]); /* Compute both words for this pair of copied components. */ \
1568        } /* Finish this component or matrix pass. */ \
1569        msb = high; /* Publish the extra word after the input values have been copied. */ \
1570        lsb = low; /* Publish the extra word after the input values have been copied. */ \
1571    } /* Finish this generated overload. */
1572SHDR_DETAIL_EXTENDED(umulExtended, std::uint32_t) // Split a full unsigned product into two words.
1573SHDR_DETAIL_EXTENDED(imulExtended, std::int32_t) // Split a full signed product into two words.
1574#undef SHDR_DETAIL_EXTENDED // Remove this local code generator macro.
1575/** @} */
1576
1577/** @name Packing
1578 * Normalized packing follows the GLSL clamp-and-round formulas.  unpacking
1579 * places the least significant byte/halfword in x. Half-float encoding rounds
1580 * to nearest even and preserves infinities and a quiet-NaN representation.
1581 * @{ */
1582inline std::uint32_t packUnorm2x16(const vec2& v) { // Pack two normalized values into 16-bit fields.
1583    std::uint32_t x = std::uint32_t(std::round(glsl::clamp(v.x, 0.0f, 1.0f) * 65535.0f)); // Hold the exact integer bits used by this operation.
1584    std::uint32_t y = std::uint32_t(std::round(glsl::clamp(v.y, 0.0f, 1.0f) * 65535.0f)); // Hold the exact integer bits used by this operation.
1585    return x | (y << 16); // Pack two normalized values into 16-bit fields.
1586} // Finish the packUnorm2x16 operation.
1587inline vec2 unpackUnorm2x16(std::uint32_t p) { // Decode two unsigned normalized 16-bit fields.
1588    return vec2(float(p & 65535u), float(p >> 16)) / 65535.0f; // Decode two unsigned normalized 16-bit fields.
1589} // Finish the unpackUnorm2x16 operation.
1590inline std::uint32_t packSnorm2x16(const vec2& v) { // Pack two signed normalized values into 16-bit fields.
1591    std::int32_t x = std::int32_t(std::round(glsl::clamp(v.x, -1.0f, 1.0f) * 32767.0f)); // Hold the exact integer bits used by this operation.
1592    std::int32_t y = std::int32_t(std::round(glsl::clamp(v.y, -1.0f, 1.0f) * 32767.0f)); // Hold the exact integer bits used by this operation.
1593    return (std::uint32_t(x) & 65535u) | (std::uint32_t(y) << 16); // Pack two signed normalized values into 16-bit fields.
1594} // Finish the packSnorm2x16 operation.
1595inline vec2 unpackSnorm2x16(std::uint32_t p) { // Decode two signed normalized 16-bit fields.
1596    std::int32_t x = std::int32_t(p & 65535u), y = std::int32_t(p >> 16); // Hold the exact integer bits used by this operation.
1597    if (x & 32768) // Handle the exceptional or boundary case before continuing.
1598        x -= 65536; // Extend the stored signed field into a signed scalar.
1599    if (y & 32768) // Handle the exceptional or boundary case before continuing.
1600        y -= 65536; // Extend the stored signed field into a signed scalar.
1601    return glsl::clamp(vec2(x, y) / 32767.0f, -1.0f, 1.0f); // Decode two signed normalized 16-bit fields.
1602} // Finish the unpackSnorm2x16 operation.
1603inline std::uint32_t packUnorm4x8(const vec4& v) { // Pack four normalized values into bytes.
1604    std::uint32_t out = 0; // Hold the exact integer bits used by this operation.
1605    for (std::size_t i = 0; i < 4; ++i) // Visit each component needed by this calculation.
1606        out |= std::uint32_t(std::round(glsl::clamp(v[i], 0.0f, 1.0f) * 255.0f)) << (i * 8); // Add the encoded field to its packed bit position.
1607    return out; // Return the completed result.
1608} // Finish the packUnorm4x8 operation.
1609inline vec4 unpackUnorm4x8(std::uint32_t p) { // Decode four unsigned normalized bytes.
1610    vec4 out; // Allocate four independent unpacked components.
1611    for (std::size_t i = 0; i < 4; ++i) // Visit each component needed by this calculation.
1612        out[i] = float((p >> (i * 8)) & 255u) / 255.0f; // Store the computed component in the independent result.
1613    return out; // Return the completed result.
1614} // Finish the unpackUnorm4x8 operation.
1615inline std::uint32_t packSnorm4x8(const vec4& v) { // Pack four signed normalized values into bytes.
1616    std::uint32_t out = 0; // Hold the exact integer bits used by this operation.
1617    for (std::size_t i = 0; i < 4; ++i) // Visit each component needed by this calculation.
1618        out |= (std::uint32_t(std::int32_t(std::round(glsl::clamp(v[i], -1.0f, 1.0f) * 127.0f))) & // Add the encoded field to its packed bit position.
1619                255u) // Keep only the low byte of the signed normalized encoding.
1620               << (i * 8); // Move that byte into its component position.
1621    return out; // Return the completed result.
1622} // Finish the packSnorm4x8 operation.
1623inline vec4 unpackSnorm4x8(std::uint32_t p) { // Decode four signed normalized bytes.
1624    vec4 out; // Allocate four independent unpacked components.
1625    for (std::size_t i = 0; i < 4; ++i) { // Visit each component needed by this calculation.
1626        int v = int((p >> (i * 8)) & 255u); // Extract this byte into a signed-capable scalar.
1627        if (v & 128) // Handle the exceptional or boundary case before continuing.
1628            v -= 256; // Extend an eight-bit negative value to the scalar type.
1629        out[i] = glsl::max(float(v) / 127.0f, -1.0f); // Store the computed component in the independent result.
1630    } // Finish this component or matrix pass.
1631    return out; // Return the completed result.
1632} // Finish the unpackSnorm4x8 operation.
1633namespace detail { // Keep these names inside the detail namespace.
1634inline std::uint16_t float_to_half(float value) { // Encode an IEEE half with ties rounded to even.
1635    std::uint32_t bits = glsl::floatBitsToUint(value), sign = (bits >> 16) & 32768u; // Separate the sign and payload bits for the conversion.
1636    int exponent = int((bits >> 23) & 255u) - 127 + 15; // Translate the exponent bias to the target float format.
1637    std::uint32_t mantissa = bits & 8388607u; // Keep the floating-point significand bits for encoding.
1638    if (((bits >> 23) & 255u) == 255u) // Handle the exceptional or boundary case before continuing.
1639        return std::uint16_t(sign | 31744u | (mantissa ? 512u : 0u)); // Encode an IEEE half with ties rounded to even.
1640    if (exponent >= 31) // Select the matching half-float exponent range.
1641        return std::uint16_t(sign | 31744u); // Encode an IEEE half with ties rounded to even.
1642    if (exponent <= 0) { // Select the matching half-float exponent range.
1643        if (exponent < -10) // Select the matching half-float exponent range.
1644            return std::uint16_t(sign); // Encode an IEEE half with ties rounded to even.
1645        mantissa |= 8388608u; // Restore the implicit leading significand bit.
1646        unsigned shift = unsigned(14 - exponent); // Choose the right shift for a half-float subnormal.
1647        std::uint32_t truncated = mantissa >> shift, remainder = mantissa & ((1u << shift) - 1u), // Keep the floating-point significand bits for encoding.
1648                      halfway = 1u << (shift - 1); // Identify the exact halfway rounding bit.
1649        if (remainder > halfway || (remainder == halfway && (truncated & 1u))) // Round up above halfway or for an odd halfway result.
1650            ++truncated; // Round the retained encoding to the next representable value.
1651        return std::uint16_t(sign | truncated); // Encode an IEEE half with ties rounded to even.
1652    } // Finish handling this condition.
1653    std::uint32_t truncated = (std::uint32_t(exponent) << 10) | (mantissa >> 13), // Keep the floating-point significand bits for encoding.
1654                  remainder = mantissa & 8191u; // Retain the discarded low bits for the rounding decision.
1655    if (remainder > 4096u || (remainder == 4096u && (truncated & 1u))) // Round up above halfway or for an odd halfway result.
1656        ++truncated; // Round the retained encoding to the next representable value.
1657    return std::uint16_t(sign | truncated); // Encode an IEEE half with ties rounded to even.
1658} // Finish the float_to_half operation.
1659inline float half_to_float(std::uint16_t h) { // Expand an IEEE half into a float.
1660    std::uint32_t sign = (std::uint32_t(h) & 32768u) << 16, mantissa = h & 1023u; // Separate the sign and payload bits for the conversion.
1661    int exponent = (h >> 10) & 31; // Translate the exponent bias to the target float format.
1662    if (exponent == 0) { // Select the matching half-float exponent range.
1663        if (!mantissa) // Handle the exceptional or boundary case before continuing.
1664            return glsl::uintBitsToFloat(sign); // Expand an IEEE half into a float.
1665        exponent = -14; // Set the exponent for a subnormal source value.
1666        while (!(mantissa & 1024u)) { // Continue until the remaining bits reach the required form.
1667            mantissa <<= 1; // Move the first significand bit toward the normalized position.
1668            --exponent; // Adjust the exponent while normalizing the significand.
1669        } // Finish this component or matrix pass.
1670        mantissa &= 1023u; // Remove the leading bit before storing the fraction.
1671        return glsl::uintBitsToFloat(sign | (std::uint32_t(exponent + 127) << 23) | // Expand an IEEE half into a float.
1672                                     (mantissa << 13)); // Place the expanded significand in the float fraction field.
1673    } // Finish handling this condition.
1674    if (exponent == 31) // Select the matching half-float exponent range.
1675        return glsl::uintBitsToFloat(sign | 2139095040u | (mantissa << 13)); // Expand an IEEE half into a float.
1676    return glsl::uintBitsToFloat(sign | (std::uint32_t(exponent - 15 + 127) << 23) | // Expand an IEEE half into a float.
1677                                 (mantissa << 13)); // Place the expanded significand in the float fraction field.
1678} // Finish the half_to_float operation.
1679} // namespace detail
1680inline std::uint32_t packHalf2x16(const vec2& v) { // Pack two IEEE half encodings into one word.
1681    return std::uint32_t(detail::float_to_half(v.x)) | // Pack two IEEE half encodings into one word.
1682           (std::uint32_t(detail::float_to_half(v.y)) << 16); // Place the second half encoding in the upper word.
1683} // Finish the packHalf2x16 operation.
1684inline vec2 unpackHalf2x16(std::uint32_t v) { // Expand the two IEEE half encodings.
1685    return vec2(detail::half_to_float(std::uint16_t(v)), // Expand the two IEEE half encodings.
1686                detail::half_to_float(std::uint16_t(v >> 16))); // Expand the upper half encoding into the second component.
1687} // Finish the unpackHalf2x16 operation.
1688/** @} */
1689} // namespace glsl
1690} // namespace shdr
1691#endif // Finish the math layer include guard.