3 // This file defines nearly all constructors and operators for built-in data types, using
4 // extended language syntax. In general, compiler treats constructors and operators as
5 // ordinary functions with some exceptions. For example, the language does not allow
6 // functions to be called in constant expressions - here the exception is made to allow it.
8 // Each implementation provides its own version of this file. Each implementation can define
9 // the required set of operators and constructors in its own fashion.
11 // The extended language syntax is only present when compiling this file. It is implicitly
12 // included at the very beginning of the compiled shader, so no built-in functions can be
15 // To communicate with the implementation, a special extended "__asm" keyword is used, followed
16 // by an instruction name (any valid identifier), a destination variable identifier and a
17 // a list of zero or more source variable identifiers. A variable identifier is a variable name
18 // declared earlier in the code (as a function parameter, local or global variable).
19 // An instruction name designates an instruction that must be exported by the implementation.
20 // Each instruction receives data from destination and source variable identifiers and returns
21 // data in the destination variable identifier.
23 // It is up to the implementation how to define a particular operator or constructor. If it is
24 // expected to being used rarely, it can be defined in terms of other operators and constructors,
27 // ivec2 __operator + (const ivec2 x, const ivec2 y) {
28 // return ivec2 (x[0] + y[0], x[1] + y[1]);
31 // If a particular operator or constructor is expected to be used very often or is an atomic
32 // operation (that is, an operation that cannot be expressed in terms of other operations or
33 // would create a dependency cycle) it must be defined using one or more __asm constructs.
35 // Each implementation must define constructors for all scalar types (bool, float, int).
36 // There are 9 scalar-to-scalar constructors (including identity constructors). However,
37 // since the language introduces special constructors (like matrix constructor with a single
38 // scalar value), implementations must also implement these cases.
39 // The compiler provides the following algorithm when resolving a constructor:
40 // - try to find a constructor with a prototype matching ours,
41 // - if no constructor is found and this is a scalar-to-scalar constructor, raise an error,
42 // - if a constructor is found, execute it and return,
43 // - count the size of the constructor parameter list - if it is less than the size of
44 // our constructor's type, raise an error,
45 // - for each parameter in the list do a recursive constructor matching for appropriate
46 // scalar fields in the constructed variable,
48 // Each implementation must also define a set of operators that deal with built-in data types.
49 // There are four kinds of operators:
50 // 1) Operators that are implemented only by the compiler: "()" (function call), "," (sequence)
51 // and "?:" (selection).
52 // 2) Operators that are implemented by the compiler by expressing it in terms of other operators:
53 // - "." (field selection) - translated to subscript access,
54 // - "&&" (logical and) - translated to "<left_expr> ? <right_expr> : false",
55 // - "||" (logical or) - translated to "<left_expr> ? true : <right_expr>",
56 // 3) Operators that can be defined by the implementation and if the required prototype is not
57 // found, standard behaviour is used:
58 // - "==", "!=", "=" (equality, assignment) - compare or assign matching fields one-by-one;
59 // note that at least operators for scalar data types must be defined by the implementation
61 // 4) All other operators not mentioned above. If no required prototype is found, an error is
62 // raised. An implementation must follow the language specification to provide all valid
63 // operator prototypes.
67 // From Shader Spec, ver. 1.10, rev. 59
71 // 5.4.1 Conversion and Scalar Constructors
75 // When constructors are used to convert a float to an int, the fractional part of the
76 // floating-point value is dropped.
79 int __constructor (const float _f) {
81 __asm float_to_int _i, _f;
86 // When a constructor is used to convert an int or a float to bool, 0 and 0.0 are converted to
87 // false, and nonzero values are converted to true.
90 bool __constructor (const int _i) {
94 bool __constructor (const float _f) {
99 // When a constructor is used to convert a bool to an int or float, false is converted to 0 or
100 // 0.0, and true is converted to 1 or 1.0.
103 int __constructor (const bool _b) {
107 float __constructor (const bool _b) {
108 return _b ? 1.0 : 0.0;
112 // Int to float constructor.
115 float __constructor (const int _i) {
117 __asm int_to_float _f, _i;
122 // Identity constructors, like float(float) are also legal, but of little use.
125 bool __constructor (const bool _b) {
129 int __constructor (const int _i) {
133 float __constructor (const float _f) {
138 // Scalar constructors with non-scalar parameters can be used to take the first element from
139 // a non-scalar. For example, the constructor float(vec3) will select the first component of the
143 // [These scalar conversions will be handled internally by the compiler.]
146 // 5.4.2 Vector and Matrix Constructors
148 // Constructors can be used to create vectors or matrices from a set of scalars, vectors,
149 // or matrices. This includes the ability to shorten vectors.
153 // If there is a single scalar parameter to a vector constructor, it is used to initialize all
154 // components of the constructed vector to that scalar
\92s value.
156 // If the basic type (bool, int, or float) of a parameter to a constructor does not match the basic
157 // type of the object being constructed, the scalar construction rules (above) are used to convert
161 vec2 __constructor (const float _f) {
162 return vec2 (_f, _f);
165 vec2 __constructor (const int _i) {
166 return vec2 (_i, _i);
169 vec2 __constructor (const bool _b) {
170 return vec2 (_b, _b);
173 vec3 __constructor (const float _f) {
174 return vec3 (_f, _f, _f);
177 vec3 __constructor (const int _i) {
178 return vec3 (_i, _i, _i);
181 vec3 __constructor (const bool _b) {
182 return vec3 (_b, _b, _b);
185 vec4 __constructor (const float _f) {
186 return vec4 (_f, _f, _f, _f);
189 vec4 __constructor (const int _i) {
190 return vec4 (_i, _i, _i, _i);
193 vec4 __constructor (const bool _b) {
194 return vec4 (_b, _b, _b, _b);
197 ivec2 __constructor (const int _i) {
198 return ivec2 (_i, _i);
201 ivec2 __constructor (const float _f) {
202 return ivec2 (_f, _f);
205 ivec2 __constructor (const bool _b) {
206 return ivec2 (_b, _b);
209 ivec3 __constructor (const int _i) {
210 return ivec3 (_i, _i, _i);
213 ivec3 __constructor (const float _f) {
214 return ivec3 (_f, _f, _f);
217 ivec3 __constructor (const bool _b) {
218 return ivec3 (_b, _b, _b);
221 ivec4 __constructor (const int _i) {
222 return ivec4 (_i, _i, _i, _i);
225 ivec4 __constructor (const float _f) {
226 return ivec4 (_f, _f, _f, _f);
229 ivec4 __constructor (const bool _b) {
230 return ivec4 (_b, _b, _b, _b);
233 bvec2 __constructor (const bool _b) {
234 return bvec2 (_b, _b);
237 bvec2 __constructor (const float _f) {
238 return bvec2 (_f, _f);
241 bvec2 __constructor (const int _i) {
242 return bvec2 (_i, _i);
245 bvec3 __constructor (const bool _b) {
246 return bvec3 (_b, _b, _b);
249 bvec3 __constructor (const float _f) {
250 return bvec3 (_f, _f, _f);
253 bvec3 __constructor (const int _i) {
254 return bvec3 (_i, _i, _i);
257 bvec4 __constructor (const bool _b) {
258 return bvec4 (_b, _b, _b, _b);
261 bvec4 __constructor (const float _f) {
262 return bvec4 (_f, _f, _f, _f);
265 bvec4 __constructor (const int _i) {
266 return bvec4 (_i, _i, _i, _i);
270 // If there is a single scalar parameter to a matrix constructor, it is used to initialize all the
271 // components on the matrix
\92s diagonal, with the remaining components initialized to 0.0.
272 // (...) Matrices will be constructed in column major order. It is an error to construct matrices
273 // from other matrices. This is reserved for future use.
275 // If the basic type (bool, int, or float) of a parameter to a constructor does not match the basic
276 // type of the object being constructed, the scalar construction rules (above) are used to convert
280 mat2 __constructor (const float _f) {
287 mat2 __constructor (const int _i) {
294 mat2 __constructor (const bool _b) {
301 mat3 __constructor (const float _f) {
309 mat3 __constructor (const int _i) {
317 mat3 __constructor (const bool _b) {
325 mat4 __constructor (const float _f) {
334 mat4 __constructor (const int _i) {
343 mat4 __constructor (const bool _b) {
355 // Assignments of values to variable names are done with the assignment operator ( = ), like
357 // lvalue = expression
359 // The assignment operator stores the value of expression into lvalue. It will compile only if
360 // expression and lvalue have the same type. All desired type-conversions must be specified
361 // explicitly via a constructor. Lvalues must be writable. Variables that are built-in types,
362 // entire structures, structure fields, l-values with the field selector ( . ) applied to select
363 // components or swizzles without repeated fields, and l-values dereferenced with the array
364 // subscript operator ( [ ] ) are all possible l-values. Other binary or unary expressions,
365 // non-dereferenced arrays, function names, swizzles with repeated fields, and constants cannot
368 // Expressions on the left of an assignment are evaluated before expressions on the right of the
372 void __operator = (inout float a, const float b) {
373 __asm float_copy a, b;
376 void __operator = (inout int a, const int b) {
380 void __operator = (inout bool a, const bool b) {
381 __asm bool_copy a, b;
384 void __operator = (inout vec2 v, const vec2 u) {
385 v.x = u.x, v.y = u.y;
388 void __operator = (inout vec3 v, const vec3 u) {
389 v.x = u.x, v.y = u.y, v.z = u.z;
392 void __operator = (inout vec4 v, const vec4 u) {
393 v.x = u.x, v.y = u.y, v.z = u.z, v.w = u.w;
396 void __operator = (inout ivec2 v, const ivec2 u) {
397 v.x = u.x, v.y = u.y;
400 void __operator = (inout ivec3 v, const ivec3 u) {
401 v.x = u.x, v.y = u.y, v.z = u.z;
404 void __operator = (inout ivec4 v, const ivec4 u) {
405 v.x = u.x, v.y = u.y, v.z = u.z, v.w = u.w;
408 void __operator = (inout bvec2 v, const bvec2 u) {
409 v.x = u.x, v.y = u.y;
412 void __operator = (inout bvec3 v, const bvec3 u) {
413 v.x = u.x, v.y = u.y, v.z = u.z;
416 void __operator = (inout bvec4 v, const bvec4 u) {
417 v.x = u.x, v.y = u.y, v.z = u.z, v.w = u.w;
420 void __operator = (inout mat2 m, const mat2 n) {
421 m[0] = n[0], m[1] = n[1];
424 void __operator = (inout mat3 m, const mat3 n) {
425 m[0] = n[0], m[1] = n[1], m[2] = n[2];
428 void __operator = (inout mat4 m, const mat4 n) {
429 m[0] = n[0], m[1] = n[1], m[2] = n[2], m[3] = n[3];
433 //
\95 The arithmetic assignments add into (+=), subtract from (-=), multiply into (*=), and divide
434 // into (/=). The variable and expression must be the same floating-point or integer type, ...
437 void __operator += (inout float a, const float b) {
438 __asm float_add a, b;
441 void __operator -= (inout float a, const float b) {
445 void __operator *= (inout float a, const float b) {
446 __asm float_multiply a, b;
449 void __operator /= (inout float a, const float b) {
450 __asm float_divide a, b;
453 void __operator += (inout int x, const int y) {
457 void __operator -= (inout int x, const int y) {
461 void __operator *= (inout int x, const int y) {
462 __asm int_multiply x, y;
465 void __operator /= (inout int x, const int y) {
466 __asm int_divide x, y;
469 void __operator += (inout vec2 v, const vec2 u) {
470 v.x += u.x, v.y += u.y;
473 void __operator -= (inout vec2 v, const vec2 u) {
474 v.x -= u.x, v.y -= u.y;
477 void __operator *= (inout vec2 v, const vec2 u) {
478 v.x *= u.x, v.y *= u.y;
481 void __operator /= (inout vec2 v, const vec2 u) {
482 v.x /= u.x, v.y /= u.y;
485 void __operator += (inout vec3 v, const vec3 u) {
486 v.x += u.x, v.y += u.y, v.z += u.z;
489 void __operator -= (inout vec3 v, const vec3 u) {
490 v.x -= u.x, v.y -= u.y, v.z -= u.z;
493 void __operator *= (inout vec3 v, const vec3 u) {
494 v.x *= u.x, v.y *= u.y, v.z *= u.z;
497 void __operator /= (inout vec3 v, const vec3 u) {
498 v.x /= u.x, v.y /= u.y, v.z /= u.z;
501 void __operator += (inout vec4 v, const vec4 u) {
502 v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;
505 void __operator -= (inout vec4 v, const vec4 u) {
506 v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;
509 void __operator *= (inout vec4 v, const vec4 u) {
510 v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;
513 void __operator /= (inout vec4 v, const vec4 u) {
514 v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;
517 void __operator += (inout ivec2 v, const ivec2 u) {
518 v.x += u.x, v.y += u.y;
521 void __operator -= (inout ivec2 v, const ivec2 u) {
522 v.x -= u.x, v.y -= u.y;
525 void __operator *= (inout ivec2 v, const ivec2 u) {
526 v.x *= u.x, v.y *= u.y;
529 void __operator /= (inout ivec2 v, const ivec2 u) {
530 v.x /= u.x, v.y /= u.y;
533 void __operator += (inout ivec3 v, const ivec3 u) {
534 v.x += u.x, v.y += u.y, v.z += u.z;
537 void __operator -= (inout ivec3 v, const ivec3 u) {
538 v.x -= u.x, v.y -= u.y, v.z -= u.z;
541 void __operator *= (inout ivec3 v, const ivec3 u) {
542 v.x *= u.x, v.y *= u.y, v.z *= u.z;
545 void __operator /= (inout ivec3 v, const ivec3 u) {
546 v.x /= u.x, v.y /= u.y, v.z /= u.z;
549 void __operator += (inout ivec4 v, const ivec4 u) {
550 v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;
553 void __operator -= (inout ivec4 v, const ivec4 u) {
554 v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;
557 void __operator *= (inout ivec4 v, const ivec4 u) {
558 v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;
561 void __operator /= (inout ivec4 v, const ivec4 u) {
562 v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;
565 void __operator += (inout mat2 m, const mat2 n) {
566 m[0] += n[0], m[1] += n[1];
569 void __operator -= (inout mat2 v, const mat2 n) {
570 m[0] -= n[0], m[1] -= n[1];
573 void __operator *= (inout mat2 m, const mat2 n) {
577 void __operator /= (inout mat2 m, const mat2 n) {
578 m[0] /= n[0], m[1] /= n[1];
581 void __operator += (inout mat3 m, const mat3 n) {
582 m[0] += n[0], m[1] += n[1], m[2] += n[2];
585 void __operator -= (inout mat3 m, const mat3 n) {
586 m[0] -= n[0], m[1] -= n[1], m[2] -= n[2];
589 void __operator *= (inout mat3 m, const mat3 n) {
593 void __operator /= (inout mat3 m, const mat3 n) {
594 m[0] /= n[0], m[1] /= n[1], m[2] /= n[2];
597 void __operator += (inout mat4 m, const mat4 n) {
598 m[0] += n[0], m[1] += n[1], m[2] += n[2], m[3] += n[3];
601 void __operator -= (inout mat4 m, const mat4 n) {
602 m[0] -= n[0], m[1] -= n[1], m[2] -= n[2], m[3] -= n[3];
605 void __operator *= (inout mat4 m, const mat4 n) {
609 void __operator /= (inout mat4 m, const mat4 n) {
610 m[0] /= n[0], m[1] /= n[1], m[2] /= n[2], m[3] /= n[3];
614 // ... or if the expression is a float, then the variable can be floating-point, a vector, or
618 void __operator += (inout vec2 v, const float a) {
622 void __operator -= (inout vec2 v, const float a) {
626 void __operator *= (inout vec2 v, const float a) {
630 void __operator /= (inout vec2 v, const float a) {
634 void __operator += (inout vec3 v, const float a) {
635 v.x += a, v.y += a, v.z += a;
638 void __operator -= (inout vec3 v, const float a) {
639 v.x -= a, v.y -= a, v.z -= a;
642 void __operator *= (inout vec3 v, const float a) {
643 v.x *= a, v.y *= a, v.z *= a;
646 void __operator /= (inout vec3 v, const float a) {
647 v.x /= a, v.y /= a, v.z /= a;
650 void __operator += (inout vec4 v, const float a) {
651 v.x += a, v.y += a, v.z += a, v.w += a;
654 void __operator -= (inout vec4 v, const float a) {
655 v.x -= a, v.y -= a, v.z -= a, v.w -= a;
658 void __operator *= (inout vec4 v, const float a) {
659 v.x *= a, v.y *= a, v.z *= a, v.w *= a;
662 void __operator /= (inout vec4 v, const float a) {
663 v.x /= a, v.y /= a, v.z /= a, v.w /= a;
666 void __operator += (inout mat2 m, const float a) {
667 m[0] += a, m[1] += a;
670 void __operator -= (inout mat2 m, const float a) {
671 m[0] -= a, m[1] -= a;
674 void __operator *= (inout mat2 m, const float a) {
675 m[0] *= a, m[1] *= a;
678 void __operator /= (inout mat2 m, const float a) {
679 m[0] /= a, m[1] /= a;
682 void __operator += (inout mat3 m, const float a) {
683 m[0] += a, m[1] += a, m[2] += a;
686 void __operator -= (inout mat3 m, const float a) {
687 m[0] -= a, m[1] -= a, m[2] -= a;
690 void __operator *= (inout mat3 m, const float a) {
691 m[0] *= a, m[1] *= a, m[2] *= a;
694 void __operator /= (inout mat3 m, const float a) {
695 m[0] /= a, m[1] /= a, m[2] /= a;
698 void __operator += (inout mat4 m, const float a) {
699 m[0] += a, m[1] += a, m[2] += a, m[3] += a;
702 void __operator -= (inout mat4 m, const float a) {
703 m[0] -= a, m[1] -= a, m[2] -= a, m[3] -= a;
706 void __operator *= (inout mat4 m, const float a) {
707 m[0] *= a, m[1] *= a, m[2] *= a, m[3] *= a;
710 void __operator /= (inout mat4 m, const float a) {
711 m[0] /= a, m[1] /= a, m[2] /= a, m[3] /= a;
715 // ... or if the operation is multiply into (*=), then the variable can be a vector and the
716 // expression can be a matrix of matching size.
719 void __operator *= (inout vec2 v, const mat2 m) {
723 void __operator *= (inout vec3 v, const mat3 m) {
727 void __operator *= (inout vec4 v, const mat4 m) {
734 // Expressions in the shading language include the following:
738 //
\95 The arithmetic binary operators add (+), subtract (-), multiply (*), and divide (/), that
739 // operate on integer and floating-point typed expressions (including vectors and matrices).
740 // The two operands must be the same type, (...) Additionally, for multiply (*) (...) If one
741 // operand is scalar and the other is a vector or matrix, the scalar is applied component-wise
742 // to the vector or matrix, resulting in the same type as the vector or matrix.
745 float __operator + (const float a, const float b) {
750 float __operator - (const float a, const float b) {
754 float __operator * (const float a, const float b) {
759 float __operator / (const float a, const float b) {
764 int __operator + (const int a, const int b) {
769 int __operator - (const int x, const int y) {
773 int __operator * (const int x, const int y) {
778 int __operator / (const int x, const int y) {
783 vec2 __operator + (const vec2 v, const vec2 u) {
784 return vec2 (v.x + u.x, v.y + u.y);
787 vec2 __operator - (const vec2 v, const vec2 u) {
788 return vec2 (v.x - u.x, v.y - u.y);
791 vec3 __operator + (const vec3 v, const vec3 u) {
792 return vec3 (v.x + u.x, v.y + u.y, v.z + u.z);
795 vec3 __operator - (const vec3 v, const vec3 u) {
796 return vec3 (v.x - u.x, v.y - u.y, v.z - u.z);
799 vec4 __operator + (const vec4 v, const vec4 u) {
800 return vec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);
803 vec4 __operator - (const vec4 v, const vec4 u) {
804 return vec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);
807 ivec2 __operator + (const ivec2 v, const ivec2 u) {
808 return ivec2 (v.x + u.x, v.y + u.y);
811 ivec2 __operator - (const ivec2 v, const ivec2 u) {
812 return ivec2 (v.x - u.x, v.y - u.y);
815 ivec3 __operator + (const ivec3 v, const ivec3 u) {
816 return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z);
819 ivec3 __operator - (const ivec3 v, const ivec3 u) {
820 return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z);
823 ivec4 __operator + (const ivec4 v, const ivec4 u) {
824 return ivec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);
827 ivec4 __operator - (const ivec4 v, const ivec4 u) {
828 return ivec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);
831 mat2 __operator + (const mat2 m, const mat2 n) {
832 return mat2 (m[0] + n[0], m[1] + n[1]);
835 mat2 __operator - (const mat2 m, const mat2 n) {
836 return mat2 (m[0] - n[0], m[1] - n[1]);
839 mat3 __operator + (const mat3 m, const mat3 n) {
840 return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
843 mat3 __operator - (const mat3 m, const mat3 n) {
844 return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
847 mat4 __operator + (const mat4 m, const mat4 n) {
848 return mat4 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
851 mat4 __operator - (const mat4 m, const mat4 n) {
852 return mat4 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
856 // ... or one can be a scalar float and the other a float vector or matrix, ...
859 vec2 __operator + (const float a, const vec2 u) {
860 return vec2 (a + u.x, a + u.y);
863 vec2 __operator + (const vec2 v, const float b) {
864 return vec2 (v.x + b, v.y + b);
867 vec2 __operator - (const float a, const vec2 u) {
868 return vec2 (a - u.x, a - u.y);
871 vec2 __operator - (const vec2 v, const float b) {
872 return vec2 (v.x - b, v.y - b);
875 vec2 __operator * (const float a, const vec2 u) {
876 return vec2 (a * u.x, a * u.y);
879 vec2 __operator * (const vec2 v, const float b) {
880 return vec2 (v.x * b, v.y * b);
883 vec2 __operator / (const float a, const vec2 u) {
884 return vec2 (a / u.x, a / u.y);
887 vec2 __operator / (const vec2 v, const float b) {
888 return vec2 (v.x / b, v.y / b);
891 vec3 __operator + (const float a, const vec3 u) {
892 return vec3 (a + u.x, a + u.y, a + u.z);
895 vec3 __operator + (const vec3 v, const float b) {
896 return vec3 (v.x + b, v.y + b, v.z + b);
899 vec3 __operator - (const float a, const vec3 u) {
900 return vec3 (a - u.x, a - u.y, a - u.z);
903 vec3 __operator - (const vec3 v, const float b) {
904 return vec3 (v.x - b, v.y - b, v.z - b);
907 vec3 __operator * (const float a, const vec3 u) {
908 return vec3 (a * u.x, a * u.y, a * u.z);
911 vec3 __operator * (const vec3 v, const float b) {
912 return vec3 (v.x * b, v.y * b, v.z * b);
915 vec3 __operator / (const float a, const vec3 u) {
916 return vec3 (a / u.x, a / u.y, a / u.z);
919 vec3 __operator / (const vec3 v, const float b) {
920 return vec3 (v.x / b, v.y / b, v.z / b);
923 vec4 __operator + (const float a, const vec4 u) {
924 return vec4 (a + u.x, a + u.y, a + u.z, a + u.w);
927 vec4 __operator + (const vec4 v, const float b) {
928 return vec4 (v.x + b, v.y + b, v.z + b, v.w + b);
931 vec4 __operator - (const float a, const vec4 u) {
932 return vec4 (a - u.x, a - u.y, a - u.z, a - u.w);
935 vec4 __operator - (const vec4 v, const float b) {
936 return vec4 (v.x - b, v.y - b, v.z - b, v.w - b);
939 vec4 __operator * (const float a, const vec4 u) {
940 return vec4 (a * u.x, a * u.y, a * u.z, a * u.w);
943 vec4 __operator * (const vec4 v, const float b) {
944 return vec4 (v.x * b, v.y * b, v.z * b, v.w * b);
947 vec4 __operator / (const float a, const vec4 u) {
948 return vec4 (a / u.x, a / u.y, a / u.z, a / u.w);
951 vec4 __operator / (const vec4 v, const float b) {
952 return vec4 (v.x / b, v.y / b, v.z / b, v.w / b);
955 mat2 __operator + (const float a, const mat2 n) {
956 return mat2 (a + n[0], a + n[1]);
959 mat2 __operator + (const mat2 m, const float b) {
960 return mat2 (m[0] + b, m[1] + b);
963 mat2 __operator - (const float a, const mat2 n) {
964 return mat2 (a - n[0], a - n[1]);
967 mat2 __operator - (const mat2 m, const float b) {
968 return mat2 (m[0] - b, m[1] - b);
971 mat2 __operator * (const float a, const mat2 n) {
972 return mat2 (a * n[0], a * n[1]);
975 mat2 __operator * (const mat2 m, const float b) {
976 return mat2 (m[0] * b, m[1] * b);
979 mat2 __operator / (const float a, const mat2 n) {
980 return mat2 (a / n[0], a / n[1]);
983 mat2 __operator / (const mat2 m, const float b) {
984 return mat2 (m[0] / b, m[1] / b);
987 mat3 __operator + (const float a, const mat3 n) {
988 return mat3 (a + n[0], a + n[1], a + n[2]);
991 mat3 __operator + (const mat3 m, const float b) {
992 return mat3 (m[0] + b, m[1] + b, m[2] + b);
995 mat3 __operator - (const float a, const mat3 n) {
996 return mat3 (a - n[0], a - n[1], a - n[2]);
999 mat3 __operator - (const mat3 m, const float b) {
1000 return mat3 (m[0] - b, m[1] - b, m[2] - b);
1003 mat3 __operator * (const float a, const mat3 n) {
1004 return mat3 (a * n[0], a * n[1], a * n[2]);
1007 mat3 __operator * (const mat3 m, const float b) {
1008 return mat3 (m[0] * b, m[1] * b, m[2] * b);
1011 mat3 __operator / (const float a, const mat3 n) {
1012 return mat3 (a / n[0], a / n[1], a / n[2]);
1015 mat3 __operator / (const mat3 m, const float b) {
1016 return mat3 (m[0] / b, m[1] / b, m[2] / b);
1019 mat4 __operator + (const float a, const mat4 n) {
1020 return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]);
1023 mat4 __operator + (const mat4 m, const float b) {
1024 return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
1027 mat4 __operator - (const float a, const mat4 n) {
1028 return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]);
1031 mat4 __operator - (const mat4 m, const float b) {
1032 return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
1035 mat4 __operator * (const float a, const mat4 n) {
1036 return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]);
1039 mat4 __operator * (const mat4 m, const float b) {
1040 return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
1043 mat4 __operator / (const float a, const mat4 n) {
1044 return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]);
1047 mat4 __operator / (const mat4 m, const float b) {
1048 return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
1052 // ... or one can be a scalar integer and the other an integer vector.
1055 ivec2 __operator + (const int a, const ivec2 u) {
1056 return ivec2 (a + u.x, a + u.y);
1059 ivec2 __operator + (const ivec2 v, const int b) {
1060 return ivec2 (v.x + b, v.y + b);
1063 ivec2 __operator - (const int a, const ivec2 u) {
1064 return ivec2 (a - u.x, a - u.y);
1067 ivec2 __operator - (const ivec2 v, const int b) {
1068 return ivec2 (v.x - b, v.y - b);
1071 ivec2 __operator * (const int a, const ivec2 u) {
1072 return ivec2 (a * u.x, a * u.y);
1075 ivec2 __operator * (const ivec2 v, const int b) {
1076 return ivec2 (v.x * b, v.y * b);
1079 ivec2 __operator / (const int a, const ivec2 u) {
1080 return ivec2 (a / u.x, a / u.y);
1083 ivec2 __operator / (const ivec2 v, const int b) {
1084 return ivec2 (v.x / b, v.y / b);
1087 ivec3 __operator + (const int a, const ivec3 u) {
1088 return ivec3 (a + u.x, a + u.y, a + u.z);
1091 ivec3 __operator + (const ivec3 v, const int b) {
1092 return ivec3 (v.x + b, v.y + b, v.z + b);
1095 ivec3 __operator - (const int a, const ivec3 u) {
1096 return ivec3 (a - u.x, a - u.y, a - u.z);
1099 ivec3 __operator - (const ivec3 v, const int b) {
1100 return ivec3 (v.x - b, v.y - b, v.z - b);
1103 ivec3 __operator * (const int a, const ivec3 u) {
1104 return ivec3 (a * u.x, a * u.y, a * u.z);
1107 ivec3 __operator * (const ivec3 v, const int b) {
1108 return ivec3 (v.x * b, v.y * b, v.z * b);
1111 ivec3 __operator / (const int a, const ivec3 u) {
1112 return ivec3 (a / u.x, a / u.y, a / u.z);
1115 ivec3 __operator / (const ivec3 v, const int b) {
1116 return ivec3 (v.x / b, v.y / b, v.z / b);
1119 ivec4 __operator + (const int a, const ivec4 u) {
1120 return ivec4 (a + u.x, a + u.y, a + u.z, a + u.w);
1123 ivec4 __operator + (const ivec4 v, const int b) {
1124 return ivec4 (v.x + b, v.y + b, v.z + b, v.w + b);
1127 ivec4 __operator - (const int a, const ivec4 u) {
1128 return ivec4 (a - u.x, a - u.y, a - u.z, a - u.w);
1131 ivec4 __operator - (const ivec4 v, const int b) {
1132 return ivec4 (v.x - b, v.y - b, v.z - b, v.w - b);
1135 ivec4 __operator * (const int a, const ivec4 u) {
1136 return ivec4 (a * u.x, a * u.y, a * u.z, a * u.w);
1139 ivec4 __operator * (const ivec4 v, const int b) {
1140 return ivec4 (v.x * b, v.y * b, v.z * b, v.w * b);
1143 ivec4 __operator / (const int a, const ivec4 u) {
1144 return ivec4 (a / u.x, a / u.y, a / u.z, a / u.w);
1147 ivec4 __operator / (const ivec4 v, const int b) {
1148 return ivec4 (v.x / b, v.y / b, v.z / b, v.w / b);
1152 // Additionally, for multiply (*) one can be a vector and the other a matrix with the same
1153 // dimensional size of the vector. These result in the same fundamental type (integer or float)
1154 // as the expressions they operate on.
1157 //
\95 the left argument is a floating-point vector and the right is a matrix with a compatible
1158 // dimension in which case the * operator will do a row vector matrix multiplication.
1159 //
\95 the left argument is a matrix and the right is a floating-point vector with a compatible
1160 // dimension in which case the * operator will do a column vector matrix multiplication.
1163 vec2 __operator * (const mat2 m, const vec2 v) {
1165 v.x * m[0].x + v.y * m[1].x,
1166 v.x * m[0].y + v.y * m[1].y
1170 vec2 __operator * (const vec2 v, const mat2 m) {
1172 v.x * m[0].x + v.y * m[0].y,
1173 v.x * m[1].x + v.y * m[1].y
1177 vec3 __operator * (const mat3 m, const vec3 v) {
1179 v.x * m[0].x + v.y * m[1].x + v.z * m[2].x,
1180 v.x * m[0].y + v.y * m[1].y + v.z * m[2].y,
1181 v.x * m[0].z + v.y * m[1].z + v.z * m[2].z
1185 vec3 __operator * (const vec3 v, const mat3 m) {
1187 v.x * m[0].x + v.y * m[0].y + v.z * m[0].z,
1188 v.x * m[1].x + v.y * m[1].y + v.z * m[1].z,
1189 v.x * m[2].x + v.y * m[2].y + v.z * m[2].z
1193 vec4 __operator * (const mat4 m, const vec4 v) {
1195 v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x,
1196 v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y,
1197 v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z,
1198 v.x * m[0].w + v.y * m[1].w + v.z * m[2].w + v.w * m[3].w
1202 vec4 __operator * (const vec4 v, const mat4 m) {
1204 v.x * m[0].x + v.y * m[0].y + v.z * m[0].z + v.w * m[0].w,
1205 v.x * m[1].x + v.y * m[1].y + v.z * m[1].z + v.w * m[1].w,
1206 v.x * m[2].x + v.y * m[2].y + v.z * m[2].z + v.w * m[2].w,
1207 v.x * m[3].x + v.y * m[3].y + v.z * m[3].z + v.w * m[3].w
1212 // Multiply (*) applied to two vectors yields a component-wise multiply.
1215 vec2 __operator * (const vec2 v, const vec2 u) {
1216 return vec2 (v.x * u.x, v.y * u.y);
1219 vec3 __operator * (const vec3 v, const vec3 u) {
1220 return vec3 (v.x * u.x, v.y * u.y, v.z * u.z);
1223 vec4 __operator * (const vec4 v, const vec4 u) {
1224 return vec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);
1227 ivec2 __operator * (const ivec2 v, const ivec2 u) {
1228 return ivec2 (v.x * u.x, v.y * u.y);
1231 ivec3 __operator * (const ivec3 v, const ivec3 u) {
1232 return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z);
1235 ivec4 __operator * (const ivec4 v, const ivec4 u) {
1236 return ivec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);
1240 // Dividing by zero does not cause an exception but does result in an unspecified value.
1243 vec2 __operator / (const vec2 v, const vec2 u) {
1244 return vec2 (v.x / u.x, v.y / u.y);
1247 vec3 __operator / (const vec3 v, const vec3 u) {
1248 return vec3 (v.x / u.x, v.y / u.y, v.z / u.z);
1251 vec4 __operator / (const vec4 v, const vec4 u) {
1252 return vec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);
1255 ivec2 __operator / (const ivec2 v, const ivec2 u) {
1256 return ivec2 (v.x / u.x, v.y / u.y);
1259 ivec3 __operator / (const ivec3 v, const ivec3 u) {
1260 return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z);
1263 ivec4 __operator / (const ivec4 v, const ivec4 u) {
1264 return ivec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);
1267 mat2 __operator / (const mat2 m, const mat2 n) {
1268 return mat2 (m[0] / n[0], m[1] / n[1]);
1271 mat3 __operator / (const mat3 m, const mat3 n) {
1272 return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
1275 mat4 __operator / (const mat4 m, const mat4 n) {
1276 return mat4 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
1280 // Multiply (*) applied to two matrices yields a linear algebraic matrix multiply, not
1281 // a component-wise multiply.
1284 mat2 __operator * (const mat2 m, const mat2 n) {
1285 return mat2 (m * n[0], m * n[1]);
1288 mat3 __operator * (const mat3 m, const mat3 n) {
1289 return mat3 (m * n[0], m * n[1], m * n[2]);
1292 mat4 __operator * (const mat4 m, const mat4 n) {
1293 return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
1297 //
\95 The arithmetic unary operators negate (-), post- and pre-increment and decrement (-- and
1298 // ++) that operate on integer or floating-point values (including vectors and matrices). These
1299 // result with the same type they operated on. For post- and pre-increment and decrement, the
1300 // expression must be one that could be assigned to (an l-value). Pre-increment and predecrement
1301 // add or subtract 1 or 1.0 to the contents of the expression they operate on, and the
1302 // value of the pre-increment or pre-decrement expression is the resulting value of that
1303 // modification. Post-increment and post-decrement expressions add or subtract 1 or 1.0 to
1304 // the contents of the expression they operate on, but the resulting expression has the
1305 // expression
\92s value before the post-increment or post-decrement was executed.
1307 // [NOTE: postfix increment and decrement operators take additional dummy int parameter to
1308 // distinguish their prototypes from prefix ones.]
1311 float __operator - (const float a) {
1313 __asm float_negate c;
1317 int __operator - (const int a) {
1323 vec2 __operator - (const vec2 v) {
1324 return vec2 (-v.x, -v.y);
1327 vec3 __operator - (const vec3 v) {
1328 return vec3 (-v.x, -v.y, -v.z);
1331 vec4 __operator - (const vec4 v) {
1332 return vec4 (-v.x, -v.y, -v.z, -v.w);
1335 ivec2 __operator - (const ivec2 v) {
1336 return ivec2 (-v.x, -v.y);
1339 ivec3 __operator - (const ivec3 v) {
1340 return ivec3 (-v.x, -v.y, -v.z);
1343 ivec4 __operator - (const ivec4 v) {
1344 return ivec4 (-v.x, -v.y, -v.z, -v.w);
1347 mat2 __operator - (const mat2 m) {
1348 return mat2 (-m[0], -m[1]);
1351 mat3 __operator - (const mat3 m) {
1352 return mat3 (-m[0], -m[1], -m[2]);
1355 mat4 __operator - (const mat4 m) {
1356 return mat4 (-m[0], -m[1], -m[2], -m[3]);
1359 void __operator -- (inout float a) {
1363 void __operator -- (inout int a) {
1367 void __operator -- (inout vec2 v) {
1371 void __operator -- (inout vec3 v) {
1372 --v.x, --v.y, --v.z;
1375 void __operator -- (inout vec4 v) {
1376 --v.x, --v.y, --v.z, --v.w;
1379 void __operator -- (inout ivec2 v) {
1383 void __operator -- (inout ivec3 v) {
1384 --v.x, --v.y, --v.z;
1387 void __operator -- (inout ivec4 v) {
1388 --v.x, --v.y, --v.z, --v.w;
1391 void __operator -- (inout mat2 m) {
1395 void __operator -- (inout mat3 m) {
1396 --m[0], --m[1], --m[2];
1399 void __operator -- (inout mat4 m) {
1400 --m[0], --m[1], --m[2], --m[3];
1403 void __operator ++ (inout float a) {
1407 void __operator ++ (inout int a) {
1411 void __operator ++ (inout vec2 v) {
1415 void __operator ++ (inout vec3 v) {
1416 ++v.x, ++v.y, ++v.z;
1419 void __operator ++ (inout vec4 v) {
1420 ++v.x, ++v.y, ++v.z, ++v.w;
1423 void __operator ++ (inout ivec2 v) {
1427 void __operator ++ (inout ivec3 v) {
1428 ++v.x, ++v.y, ++v.z;
1431 void __operator ++ (inout ivec4 v) {
1432 ++v.x, ++v.y, ++v.z, ++v.w;
1435 void __operator ++ (inout mat2 m) {
1439 void __operator ++ (inout mat3 m) {
1440 ++m[0], ++m[1], ++m[2];
1443 void __operator ++ (inout mat4 m) {
1444 ++m[0], ++m[1], ++m[2], ++m[3];
1447 float __operator -- (inout float a, const int) {
1453 int __operator -- (inout int a, const int) {
1459 vec2 __operator -- (inout vec2 v, const int) {
1460 return vec2 (v.x--, v.y--);
1463 vec3 __operator -- (inout vec3 v, const int) {
1464 return vec3 (v.x--, v.y--, v.z--);
1467 vec4 __operator -- (inout vec4 v, const int) {
1468 return vec4 (v.x--, v.y--, v.z--, v.w--);
1471 ivec2 __operator -- (inout ivec2 v, const int) {
1472 return ivec2 (v.x--, v.y--);
1475 ivec3 __operator -- (inout ivec3 v, const int) {
1476 return ivec3 (v.x--, v.y--, v.z--);
1479 ivec4 __operator -- (inout ivec4 v, const int) {
1480 return ivec4 (v.x--, v.y--, v.z--, v.w--);
1483 mat2 __operator -- (inout mat2 m, const int) {
1484 return mat2 (m[0]--, m[1]--);
1487 mat3 __operator -- (inout mat3 m, const int) {
1488 return mat3 (m[0]--, m[1]--, m[2]--);
1491 mat4 __operator -- (inout mat4 m, const int) {
1492 return mat4 (m[0]--, m[1]--, m[2]--, m[3]--);
1495 float __operator ++ (inout float a, const int) {
1501 int __operator ++ (inout int a, const int) {
1507 vec2 __operator ++ (inout vec2 v, const int) {
1508 return vec2 (v.x++, v.y++);
1511 vec3 __operator ++ (inout vec3 v, const int) {
1512 return vec3 (v.x++, v.y++, v.z++);
1515 vec4 __operator ++ (inout vec4 v, const int) {
1516 return vec4 (v.x++, v.y++, v.z++, v.w++);
1519 ivec2 __operator ++ (inout ivec2 v, const int) {
1520 return ivec2 (v.x++, v.y++);
1523 ivec3 __operator ++ (inout ivec3 v, const int) {
1524 return ivec3 (v.x++, v.y++, v.z++);
1527 ivec4 __operator ++ (inout ivec4 v, const int) {
1528 return ivec4 (v.x++, v.y++, v.z++, v.w++);
1531 mat2 __operator ++ (inout mat2 m, const int) {
1532 return mat2 (m[0]++, m[1]++);
1535 mat3 __operator ++ (inout mat3 m, const int) {
1536 return mat3 (m[0]++, m[1]++, m[2]++);
1539 mat4 __operator ++ (inout mat4 m, const int) {
1540 return mat4 (m[0]++, m[1]++, m[2]++, m[3]++);
1544 //
\95 The relational operators greater than (>), less than (<), greater than or equal (>=), and less
1545 // than or equal (<=) operate only on scalar integer and scalar floating-point expressions. The
1546 // result is scalar Boolean. The operands
\92 types must match. To do component-wise
1547 // comparisons on vectors, use the built-in functions lessThan, lessThanEqual,
1548 // greaterThan, and greaterThanEqual.
1551 bool __operator < (const float a, const float b) {
1553 __asm float_less c, a, b;
1557 bool __operator < (const int a, const int b) {
1559 __asm int_less c, a, b;
1563 bool __operator > (const float a, const float b) {
1567 bool __operator > (const int a, const int b) {
1571 bool __operator >= (const float a, const float b) {
1572 return a > b || a == b;
1575 bool __operator >= (const int a, const int b) {
1576 return a > b || a == b;
1579 bool __operator <= (const float a, const float b) {
1580 return a < b || a == b;
1583 bool __operator <= (const int a, const int b) {
1584 return a < b || a == b;
1588 //
\95 The equality operators equal (==), and not equal (!=) operate on all types except arrays.
1589 // They result in a scalar Boolean. For vectors, matrices, and structures, all components of the
1590 // operands must be equal for the operands to be considered equal. To get component-wise
1591 // equality results for vectors, use the built-in functions equal and notEqual.
1594 bool __operator == (const float a, const float b) {
1596 __asm float_equal c, a, b;
1600 bool __operator == (const int a, const int b) {
1602 __asm int_equal c, a, b;
1606 bool __operator == (const bool a, const bool b) {
1608 __asm bool_equal c, a, b;
1612 bool __operator == (const vec2 v, const vec2 u) {
1613 return v.x == u.x && v.y == u.y;
1616 bool __operator == (const vec3 v, const vec3 u) {
1617 return v.x == u.x && v.y == u.y && v.z == u.z;
1620 bool __operator == (const vec4 v, const vec4 u) {
1621 return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;
1624 bool __operator == (const ivec2 v, const ivec2 u) {
1625 return v.x == u.x && v.y == u.y;
1628 bool __operator == (const ivec3 v, const ivec3 u) {
1629 return v.x == u.x && v.y == u.y && v.z == u.z;
1632 bool __operator == (const ivec4 v, const ivec4 u) {
1633 return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;
1636 bool __operator == (const bvec2 v, const bvec2 u) {
1637 return v.x == u.x && v.y == u.y;
1640 bool __operator == (const bvec3 v, const bvec3 u) {
1641 return v.x == u.x && v.y == u.y && v.z == u.z;
1644 bool __operator == (const bvec4 v, const bvec4 u) {
1645 return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;
1648 bool __operator == (const mat2 m, const mat2 n) {
1649 return m[0] == n[0] && m[1] == n[1];
1652 bool __operator == (const mat3 m, const mat3 n) {
1653 return m[0] == n[0] && m[1] == n[1] && m[2] == n[2];
1656 bool __operator == (const mat4 m, const mat4 n) {
1657 return m[0] == n[0] && m[1] == n[1] && m[2] == n[2] && m[3] == n[3];
1660 bool __operator != (const float a, const float b) {
1664 bool __operator != (const int a, const int b) {
1668 bool __operator != (const bool a, const bool b) {
1672 bool __operator != (const vec2 v, const vec2 u) {
1673 return v.x != u.x || v.y != u.y;
1676 bool __operator != (const vec3 v, const vec3 u) {
1677 return v.x != u.x || v.y != u.y || v.z != u.z;
1680 bool __operator != (const vec4 v, const vec4 u) {
1681 return v.x != u.x || v.y != u.y || v.z != u.z || v.w != u.w;
1684 bool __operator != (const ivec2 v, const ivec2 u) {
1685 return v.x != u.x || v.y != u.y;
1688 bool __operator != (const ivec3 v, const ivec3 u) {
1689 return v.x != u.x || v.y != u.y || v.z != u.z;
1692 bool __operator != (const ivec4 v, const ivec4 u) {
1693 return v.x != u.x || v.y != u.y || v.z != u.z || v.w != u.w;
1696 bool __operator != (const bvec2 v, const bvec2 u) {
1697 return v.x != u.x || v.y != u.y;
1700 bool __operator != (const bvec3 v, const bvec3 u) {
1701 return v.x != u.x || v.y != u.y || v.z != u.z;
1704 bool __operator != (const bvec4 v, const bvec4 u) {
1705 return v.x != u.x || v.y != u.y || v.z != u.z || v.w != u.w;
1708 bool __operator != (const mat2 m, const mat2 n) {
1709 return m[0] != n[0] || m[1] != n[1];
1712 bool __operator != (const mat3 m, const mat3 n) {
1713 return m[0] != n[0] || m[1] != n[1] || m[2] != n[2];
1716 bool __operator != (const mat4 m, const mat4 n) {
1717 return m[0] != n[0] || m[1] != n[1] || m[2] != n[2] || m[3] != n[3];
1721 //
\95 The logical binary operators and (&&), or ( | | ), and exclusive or (^^). They operate only
1722 // on two Boolean expressions and result in a Boolean expression. And (&&) will only
1723 // evaluate the right hand operand if the left hand operand evaluated to true. Or ( | | ) will
1724 // only evaluate the right hand operand if the left hand operand evaluated to false. Exclusive or
1725 // (^^) will always evaluate both operands.
1728 bool __operator ^^ (const bool a, const bool b) {
1733 // [These operators are handled internally by the compiler:]
1735 // bool __operator && (bool a, bool b) {
1736 // return a ? b : false;
1738 // bool __operator || (bool a, bool b) {
1739 // return a ? true : b;
1744 //
\95 The logical unary operator not (!). It operates only on a Boolean expression and results in a
1745 // Boolean expression. To operate on a vector, use the built-in function not.
1748 bool __operator ! (const bool a) {