1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import jdk.internal.vm.annotation.ForceInline;
  28 
  29 import java.nio.ByteBuffer;
  30 import java.nio.ByteOrder;
  31 #if[!byte]
  32 import java.nio.$Type$Buffer;
  33 #end[!byte]
  34 import java.util.Objects;
  35 import java.util.concurrent.ThreadLocalRandom;
  36 
  37 
  38 /**
  39  * A specialized {@link Vector} representing an ordered immutable sequence of
  40  * {@code $type$} values.
  41  *
  42  * @param <S> the type of shape of this vector
  43  */
  44 @SuppressWarnings("cast")
  45 public abstract class $abstractvectortype$<S extends Vector.Shape> extends Vector<$Boxtype$,S> {
  46 
  47     $abstractvectortype$() {}
  48 
  49     // Unary operator
  50 
  51     interface FUnOp {
  52         $type$ apply(int i, $type$ a);
  53     }
  54 
  55     abstract $abstractvectortype$<S> uOp(FUnOp f);
  56 
  57     abstract $abstractvectortype$<S> uOp(Mask<$Boxtype$, S> m, FUnOp f);
  58 
  59     // Binary operator
  60 
  61     interface FBinOp {
  62         $type$ apply(int i, $type$ a, $type$ b);
  63     }
  64 
  65     abstract $abstractvectortype$<S> bOp(Vector<$Boxtype$,S> v, FBinOp f);
  66 
  67     abstract $abstractvectortype$<S> bOp(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m, FBinOp f);
  68 
  69     // Trinary operator
  70 
  71     interface FTriOp {
  72         $type$ apply(int i, $type$ a, $type$ b, $type$ c);
  73     }
  74 
  75     abstract $abstractvectortype$<S> tOp(Vector<$Boxtype$,S> v1, Vector<$Boxtype$,S> v2, FTriOp f);
  76 
  77     abstract $abstractvectortype$<S> tOp(Vector<$Boxtype$,S> v1, Vector<$Boxtype$,S> v2, Mask<$Boxtype$, S> m, FTriOp f);
  78 
  79     // Reduction operator
  80 
  81     abstract $type$ rOp($type$ v, FBinOp f);
  82 
  83     // Binary test
  84 
  85     interface FBinTest {
  86         boolean apply(int i, $type$ a, $type$ b);
  87     }
  88 
  89     abstract Mask<$Boxtype$, S> bTest(Vector<$Boxtype$,S> v, FBinTest f);
  90 
  91     // Foreach
  92 
  93     interface FUnCon {
  94         void apply(int i, $type$ a);
  95     }
  96 
  97     abstract void forEach(FUnCon f);
  98 
  99     abstract void forEach(Mask<$Boxtype$, S> m, FUnCon f);
 100 
 101     //
 102 
 103     @Override
 104     public abstract $abstractvectortype$<S> add(Vector<$Boxtype$,S> v);
 105 
 106     /**
 107      * Adds this vector to the broadcast of an input scalar.
 108      * <p>
 109      * This is a vector binary operation where the primitive addition operation
 110      * ({@code +}) is applied to lane elements.
 111      *
 112      * @param s the input scalar
 113      * @return the result of adding this vector to the broadcast of an input
 114      * scalar
 115      */
 116     public abstract $abstractvectortype$<S> add($type$ s);
 117 
 118     @Override
 119     public abstract $abstractvectortype$<S> add(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
 120 
 121     /**
 122      * Adds this vector to broadcast of an input scalar,
 123      * selecting lane elements controlled by a mask.
 124      * <p>
 125      * This is a vector binary operation where the primitive addition operation
 126      * ({@code +}) is applied to lane elements.
 127      *
 128      * @param s the input scalar
 129      * @param m the mask controlling lane selection
 130      * @return the result of adding this vector to the broadcast of an input
 131      * scalar
 132      */
 133     public abstract $abstractvectortype$<S> add($type$ s, Mask<$Boxtype$, S> m);
 134 
 135     @Override
 136     public abstract $abstractvectortype$<S> sub(Vector<$Boxtype$,S> v);
 137 
 138     /**
 139      * Subtracts the broadcast of an input scalar from this vector.
 140      * <p>
 141      * This is a vector binary operation where the primitive subtraction
 142      * operation ({@code -}) is applied to lane elements.
 143      *
 144      * @param s the input scalar
 145      * @return the result of subtracting the broadcast of an input
 146      * scalar from this vector
 147      */
 148     public abstract $abstractvectortype$<S> sub($type$ s);
 149 
 150     @Override
 151     public abstract $abstractvectortype$<S> sub(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
 152 
 153     /**
 154      * Subtracts the broadcast of an input scalar from this vector, selecting
 155      * lane elements controlled by a mask.
 156      * <p>
 157      * This is a vector binary operation where the primitive subtraction
 158      * operation ({@code -}) is applied to lane elements.
 159      *
 160      * @param s the input scalar
 161      * @param m the mask controlling lane selection
 162      * @return the result of subtracting the broadcast of an input
 163      * scalar from this vector
 164      */
 165     public abstract $abstractvectortype$<S> sub($type$ s, Mask<$Boxtype$, S> m);
 166 
 167     @Override
 168     public abstract $abstractvectortype$<S> mul(Vector<$Boxtype$,S> v);
 169 
 170     /**
 171      * Multiplies this vector with the broadcast of an input scalar.
 172      * <p>
 173      * This is a vector binary operation where the primitive multiplication
 174      * operation ({@code *}) is applied to lane elements.
 175      *
 176      * @param s the input scalar
 177      * @return the result of multiplying this vector with the broadcast of an
 178      * input scalar
 179      */
 180     public abstract $abstractvectortype$<S> mul($type$ s);
 181 
 182     @Override
 183     public abstract $abstractvectortype$<S> mul(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
 184 
 185     /**
 186      * Multiplies this vector with the broadcast of an input scalar, selecting
 187      * lane elements controlled by a mask.
 188      * <p>
 189      * This is a vector binary operation where the primitive multiplication
 190      * operation ({@code *}) is applied to lane elements.
 191      *
 192      * @param s the input scalar
 193      * @param m the mask controlling lane selection
 194      * @return the result of multiplying this vector with the broadcast of an
 195      * input scalar
 196      */
 197     public abstract $abstractvectortype$<S> mul($type$ s, Mask<$Boxtype$, S> m);
 198 
 199     @Override
 200     public abstract $abstractvectortype$<S> neg();
 201 
 202     @Override
 203     public abstract $abstractvectortype$<S> neg(Mask<$Boxtype$, S> m);
 204 
 205     @Override
 206     public abstract $abstractvectortype$<S> abs();
 207 
 208     @Override
 209     public abstract $abstractvectortype$<S> abs(Mask<$Boxtype$, S> m);
 210 
 211     @Override
 212     public abstract $abstractvectortype$<S> min(Vector<$Boxtype$,S> v);
 213 
 214     /**
 215      * Returns the minimum of this vector and the broadcast of an input scalar.
 216      * <p>
 217      * This is a vector binary operation where the operation
 218      * {@code (a, b) -> a < b ? a : b}  is applied to lane elements.
 219      *
 220      * @param s the input scalar
 221      * @return the minimum of this vector and the broadcast of an input scalar
 222      */
 223     public abstract $abstractvectortype$<S> min($type$ s);
 224 
 225     @Override
 226     public abstract $abstractvectortype$<S> max(Vector<$Boxtype$,S> v);
 227 
 228     /**
 229      * Returns the maximum of this vector and the broadcast of an input scalar.
 230      * <p>
 231      * This is a vector binary operation where the operation
 232      * {@code (a, b) -> a > b ? a : b}  is applied to lane elements.
 233      *
 234      * @param s the input scalar
 235      * @return the maximum of this vector and the broadcast of an input scalar
 236      */
 237     public abstract $abstractvectortype$<S> max($type$ s);
 238 
 239     @Override
 240     public abstract Mask<$Boxtype$, S> equal(Vector<$Boxtype$,S> v);
 241 
 242     /**
 243      * Tests if this vector is equal to the broadcast of an input scalar.
 244      * <p>
 245      * This is a vector binary test operation where the primitive equals
 246      * operation ({@code ==}) is applied to lane elements.
 247      *
 248      * @param s the input scalar
 249      * @return the result mask of testing if this vector is equal to the
 250      * broadcast of an input scalar
 251      */
 252     public abstract Mask<$Boxtype$, S> equal($type$ s);
 253 
 254     @Override
 255     public abstract Mask<$Boxtype$, S> notEqual(Vector<$Boxtype$,S> v);
 256 
 257     /**
 258      * Tests if this vector is not equal to the broadcast of an input scalar.
 259      * <p>
 260      * This is a vector binary test operation where the primitive not equals
 261      * operation ({@code !=}) is applied to lane elements.
 262      *
 263      * @param s the input scalar
 264      * @return the result mask of testing if this vector is not equal to the
 265      * broadcast of an input scalar
 266      */
 267     public abstract Mask<$Boxtype$, S> notEqual($type$ s);
 268 
 269     @Override
 270     public abstract Mask<$Boxtype$, S> lessThan(Vector<$Boxtype$,S> v);
 271 
 272     /**
 273      * Tests if this vector is less than the broadcast of an input scalar.
 274      * <p>
 275      * This is a vector binary test operation where the primitive less than
 276      * operation ({@code <}) is applied to lane elements.
 277      *
 278      * @param s the input scalar
 279      * @return the mask result of testing if this vector is less than the
 280      * broadcast of an input scalar
 281      */
 282     public abstract Mask<$Boxtype$, S> lessThan($type$ s);
 283 
 284     @Override
 285     public abstract Mask<$Boxtype$, S> lessThanEq(Vector<$Boxtype$,S> v);
 286 
 287     /**
 288      * Tests if this vector is less or equal to the broadcast of an input scalar.
 289      * <p>
 290      * This is a vector binary test operation where the primitive less than
 291      * or equal to operation ({@code <=}) is applied to lane elements.
 292      *
 293      * @param s the input scalar
 294      * @return the mask result of testing if this vector is less than or equal
 295      * to the broadcast of an input scalar
 296      */
 297     public abstract Mask<$Boxtype$, S> lessThanEq($type$ s);
 298 
 299     @Override
 300     public abstract Mask<$Boxtype$, S> greaterThan(Vector<$Boxtype$,S> v);
 301 
 302     /**
 303      * Tests if this vector is greater than the broadcast of an input scalar.
 304      * <p>
 305      * This is a vector binary test operation where the primitive greater than
 306      * operation ({@code >}) is applied to lane elements.
 307      *
 308      * @param s the input scalar
 309      * @return the mask result of testing if this vector is greater than the
 310      * broadcast of an input scalar
 311      */
 312     public abstract Mask<$Boxtype$, S> greaterThan($type$ s);
 313 
 314     @Override
 315     public abstract Mask<$Boxtype$, S> greaterThanEq(Vector<$Boxtype$,S> v);
 316 
 317     /**
 318      * Tests if this vector is greater than or equal to the broadcast of an
 319      * input scalar.
 320      * <p>
 321      * This is a vector binary test operation where the primitive greater than
 322      * or equal to operation ({@code >=}) is applied to lane elements.
 323      *
 324      * @param s the input scalar
 325      * @return the mask result of testing if this vector is greater than or
 326      * equal to the broadcast of an input scalar
 327      */
 328     public abstract Mask<$Boxtype$, S> greaterThanEq($type$ s);
 329 
 330     @Override
 331     public abstract $abstractvectortype$<S> blend(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
 332 
 333     /**
 334      * Blends the lane elements of this vector with those of the broadcast of an
 335      * input scalar, selecting lanes controlled by a mask.
 336      * <p>
 337      * For each lane of the mask, at lane index {@code N}, if the mask lane
 338      * is set then the lane element at {@code N} from the input vector is
 339      * selected and placed into the resulting vector at {@code N},
 340      * otherwise the the lane element at {@code N} from this input vector is
 341      * selected and placed into the resulting vector at {@code N}.
 342      *
 343      * @param s the input scalar
 344      * @param m the mask controlling lane selection
 345      * @return the result of blending the lane elements of this vector with
 346      * those of the broadcast of an input scalar
 347      */
 348     public abstract $abstractvectortype$<S> blend($type$ s, Mask<$Boxtype$, S> m);
 349 
 350     @Override
 351     public abstract $abstractvectortype$<S> rearrange(Vector<$Boxtype$, S> v,
 352                                                       Shuffle<$Boxtype$, S> s, Mask<$Boxtype$, S> m);
 353 
 354     @Override
 355     public abstract $abstractvectortype$<S> rearrange(Shuffle<$Boxtype$, S> m);
 356 
 357     @Override
 358     @ForceInline
 359     public <T extends Shape> $abstractvectortype$<T> resize(Species<$Boxtype$, T> species) {
 360         return ($abstractvectortype$<T>) species.resize(this);
 361     }
 362 
 363     @Override
 364     public abstract $abstractvectortype$<S> rotateEL(int i);
 365 
 366     @Override
 367     public abstract $abstractvectortype$<S> rotateER(int i);
 368 
 369     @Override
 370     public abstract $abstractvectortype$<S> shiftEL(int i);
 371 
 372     @Override
 373     public abstract $abstractvectortype$<S> shiftER(int i);
 374 
 375 #if[FP]
 376     /**
 377      * Divides this vector by an input vector.
 378      * <p>
 379      * This is a vector binary operation where the primitive division
 380      * operation ({@code /}) is applied to lane elements.
 381      *
 382      * @param v the input vector
 383      * @return the result of dividing this vector by the input vector
 384      */
 385     public abstract $abstractvectortype$<S> div(Vector<$Boxtype$,S> v);
 386 
 387     /**
 388      * Divides this vector by the broadcast of an input scalar.
 389      * <p>
 390      * This is a vector binary operation where the primitive division
 391      * operation ({@code /}) is applied to lane elements.
 392      *
 393      * @param v the input scalar
 394      * @return the result of dividing this vector by the broadcast of an input
 395      * scalar
 396      */
 397     public abstract $abstractvectortype$<S> div($type$ s);
 398 
 399     /**
 400      * Divides this vector by an input vector, selecting lane elements
 401      * controlled by a mask.
 402      * <p>
 403      * This is a vector binary operation where the primitive division
 404      * operation ({@code /}) is applied to lane elements.
 405      *
 406      * @param v the input vector
 407      * @param m the mask controlling lane selection
 408      * @return the result of dividing this vector by the input vector
 409      */
 410     public abstract $abstractvectortype$<S> div(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
 411 
 412     /**
 413      * Divides this vector by the broadcast of an input scalar, selecting lane
 414      * elements controlled by a mask.
 415      * <p>
 416      * This is a vector binary operation where the primitive division
 417      * operation ({@code /}) is applied to lane elements.
 418      *
 419      * @param v the input scalar
 420      * @param m the mask controlling lane selection
 421      * @return the result of dividing this vector by the broadcast of an input
 422      * scalar
 423      */
 424     public abstract $abstractvectortype$<S> div($type$ s, Mask<$Boxtype$, S> m);
 425 
 426 // @@@ Many methods are refer to Math or StrictMath functions that only accept
 427 //     double values, what should be the behaviour for lane elements of float
 428 //     vectors? down and then upcast? Or will some numeric algorithms differ?
 429 //     The answers might also depend if strict definitions are required
 430 //     to ensure portability.
 431 //     Leveraging the existing defintions in Math/StrictMath is very convenient
 432 //     but its unclear if it is t
 433 
 434     /**
 435      * Calculates the square root of this vector.
 436      * <p>
 437      * This is a vector unary operation where the {@link Math#sqrt} operation
 438      * is applied to lane elements.
 439      *
 440      * @return the square root of this vector
 441      */
 442     public abstract $abstractvectortype$<S> sqrt();
 443 
 444     /**
 445      * Calculates the square root of this vector, selecting lane elements
 446      * controlled by a mask.
 447      * <p>
 448      * This is a vector unary operation where the {@link Math#sqrt} operation
 449      * ({@code -}) is applied to lane elements.
 450      *
 451      * @param m the mask controlling lane selection
 452      * @return the square root of this vector
 453      */
 454     public $abstractvectortype$<S> sqrt(Mask<$Boxtype$,S> m) {
 455         return uOp(m, (i, a) -> ($type$) Math.sqrt((double) a));
 456     }
 457 
 458     /**
 459      * Calculates the trigonometric tangent of this vector.
 460      * <p>
 461      * This is a vector unary operation where the {@link Math#tan} operation
 462      * is applied to lane elements.
 463      *
 464      * @return the tangent of this vector
 465      */
 466     public $abstractvectortype$<S> tan() {
 467         return uOp((i, a) -> ($type$) Math.tan((double) a));
 468     }
 469 
 470     /**
 471      * Calculates the trigonometric tangent of this vector, selecting lane
 472      * elements controlled by a mask.
 473      * <p>
 474      * This is a vector unary operation where the {@link Math#tan} operation
 475      * is applied to lane elements.
 476      *
 477      * @param m the mask controlling lane selection
 478      * @return the tangent of this vector
 479      */
 480     public $abstractvectortype$<S> tan(Mask<$Boxtype$,S> m) {
 481         return uOp(m, (i, a) -> ($type$) Math.tan((double) a));
 482     }
 483 
 484     /**
 485      * Calculates the hyperbolic tangent of this vector.
 486      * <p>
 487      * This is a vector unary operation where the {@link Math#tanh} operation
 488      * is applied to lane elements.
 489      *
 490      * @return the hyperbolic tangent of this vector
 491      */
 492     public $abstractvectortype$<S> tanh() {
 493         return uOp((i, a) -> ($type$) Math.tanh((double) a));
 494     }
 495 
 496     /**
 497      * Calculates the hyperbolic tangent of this vector, selecting lane elements
 498      * controlled by a mask.
 499      * <p>
 500      * This is a vector unary operation where the {@link Math#tanh} operation
 501      * is applied to lane elements.
 502      *
 503      * @param m the mask controlling lane selection
 504      * @return the hyperbolic tangent of this vector
 505      */
 506     public $abstractvectortype$<S> tanh(Mask<$Boxtype$,S> m) {
 507         return uOp(m, (i, a) -> ($type$) Math.tanh((double) a));
 508     }
 509 
 510     /**
 511      * Calculates the trigonometric sine of this vector.
 512      * <p>
 513      * This is a vector unary operation where the {@link Math#sin} operation
 514      * is applied to lane elements.
 515      *
 516      * @return the sine of this vector
 517      */
 518     public $abstractvectortype$<S> sin() {
 519         return uOp((i, a) -> ($type$) Math.sin((double) a));
 520     }
 521 
 522     /**
 523      * Calculates the trigonometric sine of this vector, selecting lane elements
 524      * controlled by a mask.
 525      * <p>
 526      * This is a vector unary operation where the {@link Math#sin} operation
 527      * is applied to lane elements.
 528      *
 529      * @param m the mask controlling lane selection
 530      * @return the sine of this vector
 531      */
 532     public $abstractvectortype$<S> sin(Mask<$Boxtype$,S> m) {
 533         return uOp(m, (i, a) -> ($type$) Math.sin((double) a));
 534     }
 535 
 536     /**
 537      * Calculates the hyperbolic sine of this vector.
 538      * <p>
 539      * This is a vector unary operation where the {@link Math#sinh} operation
 540      * is applied to lane elements.
 541      *
 542      * @return the hyperbolic sine of this vector
 543      */
 544     public $abstractvectortype$<S> sinh() {
 545         return uOp((i, a) -> ($type$) Math.sinh((double) a));
 546     }
 547 
 548     /**
 549      * Calculates the hyperbolic sine of this vector, selecting lane elements
 550      * controlled by a mask.
 551      * <p>
 552      * This is a vector unary operation where the {@link Math#sinh} operation
 553      * is applied to lane elements.
 554      *
 555      * @param m the mask controlling lane selection
 556      * @return the hyperbolic sine of this vector
 557      */
 558     public $abstractvectortype$<S> sinh(Mask<$Boxtype$,S> m) {
 559         return uOp(m, (i, a) -> ($type$) Math.sinh((double) a));
 560     }
 561 
 562     /**
 563      * Calculates the trigonometric cosine of this vector.
 564      * <p>
 565      * This is a vector unary operation where the {@link Math#cos} operation
 566      * is applied to lane elements.
 567      *
 568      * @return the cosine of this vector
 569      */
 570     public $abstractvectortype$<S> cos() {
 571         return uOp((i, a) -> ($type$) Math.cos((double) a));
 572     }
 573 
 574     /**
 575      * Calculates the trigonometric cosine of this vector, selecting lane
 576      * elements controlled by a mask.
 577      * <p>
 578      * This is a vector unary operation where the {@link Math#cos} operation
 579      * is applied to lane elements.
 580      *
 581      * @param m the mask controlling lane selection
 582      * @return the cosine of this vector
 583      */
 584     public $abstractvectortype$<S> cos(Mask<$Boxtype$,S> m) {
 585         return uOp(m, (i, a) -> ($type$) Math.cos((double) a));
 586     }
 587 
 588     /**
 589      * Calculates the hyperbolic cosine of this vector.
 590      * <p>
 591      * This is a vector unary operation where the {@link Math#cosh} operation
 592      * is applied to lane elements.
 593      *
 594      * @return the hyperbolic cosine of this vector
 595      */
 596     public $abstractvectortype$<S> cosh() {
 597         return uOp((i, a) -> ($type$) Math.cosh((double) a));
 598     }
 599 
 600     /**
 601      * Calculates the hyperbolic cosine of this vector, selecting lane elements
 602      * controlled by a mask.
 603      * <p>
 604      * This is a vector unary operation where the {@link Math#cosh} operation
 605      * is applied to lane elements.
 606      *
 607      * @param m the mask controlling lane selection
 608      * @return the hyperbolic cosine of this vector
 609      */
 610     public $abstractvectortype$<S> cosh(Mask<$Boxtype$,S> m) {
 611         return uOp(m, (i, a) -> ($type$) Math.cosh((double) a));
 612     }
 613 
 614     /**
 615      * Calculates the arc sine of this vector.
 616      * <p>
 617      * This is a vector unary operation where the {@link Math#asin} operation
 618      * is applied to lane elements.
 619      *
 620      * @return the arc sine of this vector
 621      */
 622     public $abstractvectortype$<S> asin() {
 623         return uOp((i, a) -> ($type$) Math.asin((double) a));
 624     }
 625 
 626     /**
 627      * Calculates the arc sine of this vector, selecting lane elements
 628      * controlled by a mask.
 629      * <p>
 630      * This is a vector unary operation where the {@link Math#asin} operation
 631      * is applied to lane elements.
 632      *
 633      * @param m the mask controlling lane selection
 634      * @return the arc sine of this vector
 635      */
 636     public $abstractvectortype$<S> asin(Mask<$Boxtype$,S> m) {
 637         return uOp(m, (i, a) -> ($type$) Math.asin((double) a));
 638     }
 639 
 640     /**
 641      * Calculates the arc cosine of this vector.
 642      * <p>
 643      * This is a vector unary operation where the {@link Math#acos} operation
 644      * is applied to lane elements.
 645      *
 646      * @return the arc cosine of this vector
 647      */
 648     public $abstractvectortype$<S> acos() {
 649         return uOp((i, a) -> ($type$) Math.acos((double) a));
 650     }
 651 
 652     /**
 653      * Calculates the arc cosine of this vector, selecting lane elements
 654      * controlled by a mask.
 655      * <p>
 656      * This is a vector unary operation where the {@link Math#acos} operation
 657      * is applied to lane elements.
 658      *
 659      * @param m the mask controlling lane selection
 660      * @return the arc cosine of this vector
 661      */
 662     public $abstractvectortype$<S> acos(Mask<$Boxtype$,S> m) {
 663         return uOp(m, (i, a) -> ($type$) Math.acos((double) a));
 664     }
 665 
 666     /**
 667      * Calculates the arc tangent of this vector.
 668      * <p>
 669      * This is a vector unary operation where the {@link Math#atan} operation
 670      * is applied to lane elements.
 671      *
 672      * @return the arc tangent of this vector
 673      */
 674     public $abstractvectortype$<S> atan() {
 675         return uOp((i, a) -> ($type$) Math.atan((double) a));
 676     }
 677 
 678     /**
 679      * Calculates the arc tangent of this vector, selecting lane elements
 680      * controlled by a mask.
 681      * <p>
 682      * This is a vector unary operation where the {@link Math#atan} operation
 683      * is applied to lane elements.
 684      *
 685      * @param m the mask controlling lane selection
 686      * @return the arc tangent of this vector
 687      */
 688     public $abstractvectortype$<S> atan(Mask<$Boxtype$,S> m) {
 689         return uOp(m, (i, a) -> ($type$) Math.atan((double) a));
 690     }
 691 
 692     /**
 693      * Calculates the arc tangent of this vector divided by an input vector.
 694      * <p>
 695      * This is a vector binary operation where the {@link Math#atan2} operation
 696      * is applied to lane elements.
 697      *
 698      * @param v the input vector
 699      * @return the arc tangent of this vector divided by the input vector
 700      */
 701     public $abstractvectortype$<S> atan2(Vector<$Boxtype$,S> v) {
 702         return bOp(v, (i, a, b) -> ($type$) Math.atan2((double) a, (double) b));
 703     }
 704 
 705     /**
 706      * Calculates the arc tangent of this vector divided by the broadcast of an
 707      * an input scalar.
 708      * <p>
 709      * This is a vector binary operation where the {@link Math#atan2} operation
 710      * is applied to lane elements.
 711      *
 712      * @param s the input scalar
 713      * @return the arc tangent of this vector over the input vector
 714      */
 715     public abstract $abstractvectortype$<S> atan2($type$ s);
 716 
 717     /**
 718      * Calculates the arc tangent of this vector divided by an input vector,
 719      * selecting lane elements controlled by a mask.
 720      * <p>
 721      * This is a vector binary operation where the {@link Math#atan2} operation
 722      * is applied to lane elements.
 723      *
 724      * @param v the input vector
 725      * @param m the mask controlling lane selection
 726      * @return the arc tangent of this vector divided by the input vector
 727      */
 728     public $abstractvectortype$<S> atan2(Vector<$Boxtype$,S> v, Mask<$Boxtype$,S> m) {
 729         return bOp(v, m, (i, a, b) -> ($type$) Math.atan2((double) a, (double) b));
 730     }
 731 
 732     /**
 733      * Calculates the arc tangent of this vector divided by the broadcast of an
 734      * an input scalar, selecting lane elements controlled by a mask.
 735      * <p>
 736      * This is a vector binary operation where the {@link Math#atan2} operation
 737      * is applied to lane elements.
 738      *
 739      * @param s the input scalar
 740      * @param m the mask controlling lane selection
 741      * @return the arc tangent of this vector over the input vector
 742      */
 743     public abstract $abstractvectortype$<S> atan2($type$ s, Mask<$Boxtype$,S> m);
 744 
 745     /**
 746      * Calculates the cube root of this vector.
 747      * <p>
 748      * This is a vector unary operation where the {@link Math#cbrt} operation
 749      * is applied to lane elements.
 750      *
 751      * @return the cube root of this vector
 752      */
 753     public $abstractvectortype$<S> cbrt() {
 754         return uOp((i, a) -> ($type$) Math.cbrt((double) a));
 755     }
 756 
 757     /**
 758      * Calculates the cube root of this vector, selecting lane elements
 759      * controlled by a mask.
 760      * <p>
 761      * This is a vector unary operation where the {@link Math#cbrt} operation
 762      * is applied to lane elements.
 763      *
 764      * @param m the mask controlling lane selection
 765      * @return the cube root of this vector
 766      */
 767     public $abstractvectortype$<S> cbrt(Mask<$Boxtype$,S> m) {
 768         return uOp(m, (i, a) -> ($type$) Math.cbrt((double) a));
 769     }
 770 
 771     /**
 772      * Calculates the natural logarithm of this vector.
 773      * <p>
 774      * This is a vector unary operation where the {@link Math#log} operation
 775      * is applied to lane elements.
 776      *
 777      * @return the natural logarithm of this vector
 778      */
 779     public $abstractvectortype$<S> log() {
 780         return uOp((i, a) -> ($type$) Math.log((double) a));
 781     }
 782 
 783     /**
 784      * Calculates the natural logarithm of this vector, selecting lane elements
 785      * controlled by a mask.
 786      * <p>
 787      * This is a vector unary operation where the {@link Math#log} operation
 788      * is applied to lane elements.
 789      *
 790      * @param m the mask controlling lane selection
 791      * @return the natural logarithm of this vector
 792      */
 793     public $abstractvectortype$<S> log(Mask<$Boxtype$,S> m) {
 794         return uOp(m, (i, a) -> ($type$) Math.log((double) a));
 795     }
 796 
 797     /**
 798      * Calculates the base 10 logarithm of this vector.
 799      * <p>
 800      * This is a vector unary operation where the {@link Math#log10} operation
 801      * is applied to lane elements.
 802      *
 803      * @return the base 10 logarithm of this vector
 804      */
 805     public $abstractvectortype$<S> log10() {
 806         return uOp((i, a) -> ($type$) Math.log10((double) a));
 807     }
 808 
 809     /**
 810      * Calculates the base 10 logarithm of this vector, selecting lane elements
 811      * controlled by a mask.
 812      * <p>
 813      * This is a vector unary operation where the {@link Math#log10} operation
 814      * is applied to lane elements.
 815      *
 816      * @param m the mask controlling lane selection
 817      * @return the base 10 logarithm of this vector
 818      */
 819     public $abstractvectortype$<S> log10(Mask<$Boxtype$,S> m) {
 820         return uOp(m, (i, a) -> ($type$) Math.log10((double) a));
 821     }
 822 
 823     /**
 824      * Calculates the natural logarithm of the sum of this vector and the
 825      * broadcast of {@code 1}.
 826      * <p>
 827      * This is a vector unary operation where the {@link Math#log1p} operation
 828      * is applied to lane elements.
 829      *
 830      * @return the natural logarithm of the sum of this vector and the broadcast
 831      * of {@code 1}
 832      */
 833     public $abstractvectortype$<S> log1p() {
 834         return uOp((i, a) -> ($type$) Math.log1p((double) a));
 835     }
 836 
 837     /**
 838      * Calculates the natural logarithm of the sum of this vector and the
 839      * broadcast of {@code 1}, selecting lane elements controlled by a mask.
 840      * <p>
 841      * This is a vector unary operation where the {@link Math#log1p} operation
 842      * is applied to lane elements.
 843      *
 844      * @param m the mask controlling lane selection
 845      * @return the natural logarithm of the sum of this vector and the broadcast
 846      * of {@code 1}
 847      */
 848     public $abstractvectortype$<S> log1p(Mask<$Boxtype$,S> m) {
 849         return uOp(m, (i, a) -> ($type$) Math.log1p((double) a));
 850     }
 851 
 852     /**
 853      * Calculates this vector raised to the power of an input vector.
 854      * <p>
 855      * This is a vector binary operation where the {@link Math#pow} operation
 856      * is applied to lane elements.
 857      *
 858      * @param v the input vector
 859      * @return this vector raised to the power of an input vector
 860      */
 861     public $abstractvectortype$<S> pow(Vector<$Boxtype$,S> v) {
 862         return bOp(v, (i, a, b) -> ($type$) Math.pow((double) a, (double) b));
 863     }
 864 
 865     /**
 866      * Calculates this vector raised to the power of the broadcast of an input
 867      * scalar.
 868      * <p>
 869      * This is a vector binary operation where the {@link Math#pow} operation
 870      * is applied to lane elements.
 871      *
 872      * @param s the input scalar
 873      * @return this vector raised to the power of the broadcast of an input
 874      * scalar.
 875      */
 876     public abstract $abstractvectortype$<S> pow($type$ s);
 877 
 878     /**
 879      * Calculates this vector raised to the power of an input vector, selecting
 880      * lane elements controlled by a mask.
 881      * <p>
 882      * This is a vector binary operation where the {@link Math#pow} operation
 883      * is applied to lane elements.
 884      *
 885      * @param v the input vector
 886      * @param m the mask controlling lane selection
 887      * @return this vector raised to the power of an input vector
 888      */
 889     public $abstractvectortype$<S> pow(Vector<$Boxtype$,S> v, Mask<$Boxtype$,S> m) {
 890         return bOp(v, m, (i, a, b) -> ($type$) Math.pow((double) a, (double) b));
 891     }
 892 
 893     /**
 894      * Calculates this vector raised to the power of the broadcast of an input
 895      * scalar, selecting lane elements controlled by a mask.
 896      * <p>
 897      * This is a vector binary operation where the {@link Math#pow} operation
 898      * is applied to lane elements.
 899      *
 900      * @param s the input scalar
 901      * @param m the mask controlling lane selection
 902      * @return this vector raised to the power of the broadcast of an input
 903      * scalar.
 904      */
 905     public abstract $abstractvectortype$<S> pow($type$ s, Mask<$Boxtype$,S> m);
 906 
 907     /**
 908      * Calculates the broadcast of Euler's number {@code e} raised to the power
 909      * of this vector.
 910      * <p>
 911      * This is a vector unary operation where the {@link Math#exp} operation
 912      * is applied to lane elements.
 913      *
 914      * @return the broadcast of Euler's number {@code e} raised to the power of
 915      * this vector
 916      */
 917     public $abstractvectortype$<S> exp() {
 918         return uOp((i, a) -> ($type$) Math.exp((double) a));
 919     }
 920 
 921     /**
 922      * Calculates the broadcast of Euler's number {@code e} raised to the power
 923      * of this vector, selecting lane elements controlled by a mask.
 924      * <p>
 925      * This is a vector unary operation where the {@link Math#exp} operation
 926      * is applied to lane elements.
 927      *
 928      * @param m the mask controlling lane selection
 929      * @return the broadcast of Euler's number {@code e} raised to the power of
 930      * this vector
 931      */
 932     public $abstractvectortype$<S> exp(Mask<$Boxtype$,S> m) {
 933         return uOp(m, (i, a) -> ($type$) Math.exp((double) a));
 934     }
 935 
 936     /**
 937      * Calculates the broadcast of Euler's number {@code e} raised to the power
 938      * of this vector minus the broadcast of {@code -1}.
 939      * More specifically as if the following (ignoring any differences in
 940      * numerical accuracy):
 941      * <pre>{@code
 942      *   this.exp().sub(this.species().broadcast(1))
 943      * }</pre>
 944      * <p>
 945      * This is a vector unary operation where the {@link Math#expm1} operation
 946      * is applied to lane elements.
 947      *
 948      * @return the broadcast of Euler's number {@code e} raised to the power of
 949      * this vector minus the broadcast of {@code -1}
 950      */
 951     public $abstractvectortype$<S> expm1() {
 952         return uOp((i, a) -> ($type$) Math.expm1((double) a));
 953     }
 954 
 955     /**
 956      * Calculates the broadcast of Euler's number {@code e} raised to the power
 957      * of this vector minus the broadcast of {@code -1}, selecting lane elements
 958      * controlled by a mask
 959      * More specifically as if the following (ignoring any differences in
 960      * numerical accuracy):
 961      * <pre>{@code
 962      *   this.exp(m).sub(this.species().broadcast(1), m)
 963      * }</pre>
 964      * <p>
 965      * This is a vector unary operation where the {@link Math#expm1} operation
 966      * is applied to lane elements.
 967      *
 968      * @param m the mask controlling lane selection
 969      * @return the broadcast of Euler's number {@code e} raised to the power of
 970      * this vector minus the broadcast of {@code -1}
 971      */
 972     public $abstractvectortype$<S> expm1(Mask<$Boxtype$,S> m) {
 973         return uOp(m, (i, a) -> ($type$) Math.expm1((double) a));
 974     }
 975 
 976     /**
 977      * Calculates the product of this vector and a first input vector summed
 978      * with a second input vector.
 979      * More specifically as if the following (ignoring any differences in
 980      * numerical accuracy):
 981      * <pre>{@code
 982      *   this.mul(v1).add(v2)
 983      * }</pre>
 984      * <p>
 985      * This is a vector ternary operation where the {@link Math#fma} operation
 986      * is applied to lane elements.
 987      *
 988      * @param v1 the first input vector
 989      * @param v2 the second input vector
 990      * @return the product of this vector and the first input vector summed with
 991      * the second input vector
 992      */
 993     public abstract $abstractvectortype$<S> fma(Vector<$Boxtype$,S> v1, Vector<$Boxtype$,S> v2);
 994 
 995     /**
 996      * Calculates the product of this vector and the broadcast of a first input
 997      * scalar summed with the broadcast of a second input scalar.
 998      * More specifically as if the following:
 999      * <pre>{@code
1000      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2))
1001      * }</pre>
1002      * <p>
1003      * This is a vector ternary operation where the {@link Math#fma} operation
1004      * is applied to lane elements.
1005      *
1006      * @param s1 the first input scalar
1007      * @param s2 the second input scalar
1008      * @return the product of this vector and the broadcast of a first input
1009      * scalar summed with the broadcast of a second input scalar
1010      */
1011     public abstract $abstractvectortype$<S> fma($type$ s1, $type$ s2);
1012 
1013     /**
1014      * Calculates the product of this vector and a first input vector summed
1015      * with a second input vector, selecting lane elements controlled by a mask.
1016      * More specifically as if the following (ignoring any differences in
1017      * numerical accuracy):
1018      * <pre>{@code
1019      *   this.mul(v1, m).add(v2, m)
1020      * }</pre>
1021      * <p>
1022      * This is a vector ternary operation where the {@link Math#fma} operation
1023      * is applied to lane elements.
1024      *
1025      * @param v1 the first input vector
1026      * @param v2 the second input vector
1027      * @param m the mask controlling lane selection
1028      * @return the product of this vector and the first input vector summed with
1029      * the second input vector
1030      */
1031     public $abstractvectortype$<S> fma(Vector<$Boxtype$,S> v1, Vector<$Boxtype$,S> v2, Mask<$Boxtype$,S> m) {
1032         return tOp(v1, v2, m, (i, a, b, c) -> Math.fma(a, b, c));
1033     }
1034 
1035     /**
1036      * Calculates the product of this vector and the broadcast of a first input
1037      * scalar summed with the broadcast of a second input scalar, selecting lane
1038      * elements controlled by a mask
1039      * More specifically as if the following:
1040      * <pre>{@code
1041      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2), m)
1042      * }</pre>
1043      * <p>
1044      * This is a vector ternary operation where the {@link Math#fma} operation
1045      * is applied to lane elements.
1046      *
1047      * @param s1 the first input scalar
1048      * @param s2 the second input scalar
1049      * @param m the mask controlling lane selection
1050      * @return the product of this vector and the broadcast of a first input
1051      * scalar summed with the broadcast of a second input scalar
1052      */
1053     public abstract $abstractvectortype$<S> fma($type$ s1, $type$ s2, Mask<$Boxtype$,S> m);
1054 
1055 // Computes the square root of the sum of the squares of x and y
1056 
1057     /**
1058      * Calculates square root of the sum of the squares of this vector and an
1059      * input vector.
1060      * More specifically as if the following (ignoring any differences in
1061      * numerical accuracy):
1062      * <pre>{@code
1063      *   this.mul(this).add(v.mul(v)).sqrt()
1064      * }</pre>
1065      * <p>
1066      * This is a vector binary operation where the {@link Math#hypot} operation
1067      * is applied to lane elements.
1068      *
1069      * @param v the input vector
1070      * @return square root of the sum of the squares of this vector and an input
1071      * vector
1072      */
1073     public $abstractvectortype$<S> hypot(Vector<$Boxtype$,S> v) {
1074         return bOp(v, (i, a, b) -> ($type$) Math.hypot((double) a, (double) b));
1075     }
1076 
1077     /**
1078      * Calculates square root of the sum of the squares of this vector and the
1079      * broadcast of an input scalar.
1080      * More specifically as if the following (ignoring any differences in
1081      * numerical accuracy):
1082      * <pre>{@code
1083      *   this.mul(this).add(this.species().broadcast(v * v)).sqrt()
1084      * }</pre>
1085      * <p>
1086      * This is a vector binary operation where the {@link Math#hypot} operation
1087      * is applied to lane elements.
1088      *
1089      * @param s the input scalar
1090      * @return square root of the sum of the squares of this vector and the
1091      * broadcast of an input scalar
1092      */
1093     public abstract $abstractvectortype$<S> hypot($type$ s);
1094 
1095     /**
1096      * Calculates square root of the sum of the squares of this vector and an
1097      * input vector, selecting lane elements controlled by a mask.
1098      * More specifically as if the following (ignoring any differences in
1099      * numerical accuracy):
1100      * <pre>{@code
1101      *   this.mul(this, m).add(v.mul(v), m).sqrt(m)
1102      * }</pre>
1103      * <p>
1104      * This is a vector binary operation where the {@link Math#hypot} operation
1105      * is applied to lane elements.
1106      *
1107      * @param v the input vector
1108      * @param m the mask controlling lane selection
1109      * @return square root of the sum of the squares of this vector and an input
1110      * vector
1111      */
1112     public $abstractvectortype$<S> hypot(Vector<$Boxtype$,S> v, Mask<$Boxtype$,S> m) {
1113         return bOp(v, m, (i, a, b) -> ($type$) Math.hypot((double) a, (double) b));
1114     }
1115 
1116     /**
1117      * Calculates square root of the sum of the squares of this vector and the
1118      * broadcast of an input scalar, selecting lane elements controlled by a
1119      * mask.
1120      * More specifically as if the following (ignoring any differences in
1121      * numerical accuracy):
1122      * <pre>{@code
1123      *   this.mul(this, m).add(this.species().broadcast(v * v), m).sqrt(m)
1124      * }</pre>
1125      * <p>
1126      * This is a vector binary operation where the {@link Math#hypot} operation
1127      * is applied to lane elements.
1128      *
1129      * @param s the input scalar
1130      * @param m the mask controlling lane selection
1131      * @return square root of the sum of the squares of this vector and the
1132      * broadcast of an input scalar
1133      */
1134     public abstract $abstractvectortype$<S> hypot($type$ s, Mask<$Boxtype$,S> m);
1135 #end[FP]
1136 
1137 #if[BITWISE]
1138 
1139     /**
1140      * Bitwise ANDs this vector with an input vector.
1141      * <p>
1142      * This is a vector binary operation where the primitive bitwise AND
1143      * operation ({@code &}) is applied to lane elements.
1144      *
1145      * @param v the input vector
1146      * @return the bitwise AND of this vector with the input vector
1147      */
1148     public abstract $abstractvectortype$<S> and(Vector<$Boxtype$,S> v);
1149 
1150     /**
1151      * Bitwise ANDs this vector with the broadcast of an input scalar.
1152      * <p>
1153      * This is a vector binary operation where the primitive bitwise AND
1154      * operation ({@code &}) is applied to lane elements.
1155      *
1156      * @param s the input scalar
1157      * @return the bitwise AND of this vector with the broadcast of an input
1158      * scalar
1159      */
1160     public abstract $abstractvectortype$<S> and($type$ s);
1161 
1162     /**
1163      * Bitwise ANDs this vector with an input vector, selecting lane elements
1164      * controlled by a mask.
1165      * <p>
1166      * This is a vector binary operation where the primitive bitwise AND
1167      * operation ({@code &}) is applied to lane elements.
1168      *
1169      * @param v the input vector
1170      * @param m the mask controlling lane selection
1171      * @return the bitwise AND of this vector with the input vector
1172      */
1173     public abstract $abstractvectortype$<S> and(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
1174 
1175     /**
1176      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
1177      * lane elements controlled by a mask.
1178      * <p>
1179      * This is a vector binary operation where the primitive bitwise AND
1180      * operation ({@code &}) is applied to lane elements.
1181      *
1182      * @param s the input scalar
1183      * @param m the mask controlling lane selection
1184      * @return the bitwise AND of this vector with the broadcast of an input
1185      * scalar
1186      */
1187     public abstract $abstractvectortype$<S> and($type$ s, Mask<$Boxtype$, S> m);
1188 
1189     /**
1190      * Bitwise ORs this vector with an input vector.
1191      * <p>
1192      * This is a vector binary operation where the primitive bitwise OR
1193      * operation ({@code |}) is applied to lane elements.
1194      *
1195      * @param v the input vector
1196      * @return the bitwise OR of this vector with the input vector
1197      */
1198     public abstract $abstractvectortype$<S> or(Vector<$Boxtype$,S> v);
1199 
1200     /**
1201      * Bitwise ORs this vector with the broadcast of an input scalar.
1202      * <p>
1203      * This is a vector binary operation where the primitive bitwise OR
1204      * operation ({@code |}) is applied to lane elements.
1205      *
1206      * @param s the input scalar
1207      * @return the bitwise OR of this vector with the broadcast of an input
1208      * scalar
1209      */
1210     public abstract $abstractvectortype$<S> or($type$ s);
1211 
1212     /**
1213      * Bitwise ORs this vector with an input vector, selecting lane elements
1214      * controlled by a mask.
1215      * <p>
1216      * This is a vector binary operation where the primitive bitwise OR
1217      * operation ({@code |}) is applied to lane elements.
1218      *
1219      * @param v the input vector
1220      * @param m the mask controlling lane selection
1221      * @return the bitwise OR of this vector with the input vector
1222      */
1223     public abstract $abstractvectortype$<S> or(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
1224 
1225     /**
1226      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
1227      * lane elements controlled by a mask.
1228      * <p>
1229      * This is a vector binary operation where the primitive bitwise OR
1230      * operation ({@code |}) is applied to lane elements.
1231      *
1232      * @param s the input scalar
1233      * @param m the mask controlling lane selection
1234      * @return the bitwise OR of this vector with the broadcast of an input
1235      * scalar
1236      */
1237     public abstract $abstractvectortype$<S> or($type$ s, Mask<$Boxtype$, S> m);
1238 
1239     /**
1240      * Bitwise XORs this vector with an input vector.
1241      * <p>
1242      * This is a vector binary operation where the primitive bitwise XOR
1243      * operation ({@code ^}) is applied to lane elements.
1244      *
1245      * @param v the input vector
1246      * @return the bitwise XOR of this vector with the input vector
1247      */
1248     public abstract $abstractvectortype$<S> xor(Vector<$Boxtype$,S> v);
1249 
1250     /**
1251      * Bitwise XORs this vector with the broadcast of an input scalar.
1252      * <p>
1253      * This is a vector binary operation where the primitive bitwise XOR
1254      * operation ({@code ^}) is applied to lane elements.
1255      *
1256      * @param s the input scalar
1257      * @return the bitwise XOR of this vector with the broadcast of an input
1258      * scalar
1259      */
1260     public abstract $abstractvectortype$<S> xor($type$ s);
1261 
1262     /**
1263      * Bitwise XORs this vector with an input vector, selecting lane elements
1264      * controlled by a mask.
1265      * <p>
1266      * This is a vector binary operation where the primitive bitwise XOR
1267      * operation ({@code ^}) is applied to lane elements.
1268      *
1269      * @param v the input vector
1270      * @param m the mask controlling lane selection
1271      * @return the bitwise XOR of this vector with the input vector
1272      */
1273     public abstract $abstractvectortype$<S> xor(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m);
1274 
1275     /**
1276      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1277      * lane elements controlled by a mask.
1278      * <p>
1279      * This is a vector binary operation where the primitive bitwise XOR
1280      * operation ({@code ^}) is applied to lane elements.
1281      *
1282      * @param s the input scalar
1283      * @param m the mask controlling lane selection
1284      * @return the bitwise XOR of this vector with the broadcast of an input
1285      * scalar
1286      */
1287     public abstract $abstractvectortype$<S> xor($type$ s, Mask<$Boxtype$, S> m);
1288 
1289     /**
1290      * Bitwise NOTs this vector.
1291      * <p>
1292      * This is a vector unary operation where the primitive bitwise NOT
1293      * operation ({@code ~}) is applied to lane elements.
1294      *
1295      * @return the bitwise NOT of this vector
1296      */
1297     public abstract $abstractvectortype$<S> not();
1298 
1299     /**
1300      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1301      * <p>
1302      * This is a vector unary operation where the primitive bitwise NOT
1303      * operation ({@code ~}) is applied to lane elements.
1304      *
1305      * @param m the mask controlling lane selection
1306      * @return the bitwise NOT of this vector
1307      */
1308     public abstract $abstractvectortype$<S> not(Mask<$Boxtype$, S> m);
1309 
1310 /*
1311 @@@ Check the shift operations against the JLS definition and vector
1312     instructions.
1313 
1314     For int values the low 5 bits of s are used.
1315     For long values the low 6 bits of s are used.
1316  */
1317 
1318 #if[intOrLong]
1319     /**
1320      * Logically left shifts this vector by the broadcast of an input scalar.
1321      * <p>
1322      * This is a vector binary operation where the primitive logical left shift
1323      * operation ({@code <<}) is applied to lane elements.
1324      *
1325      * @param s the input scalar; the number of the bits to left shift
1326      * @return the result of logically left shifting left this vector by the
1327      * broadcast of an input scalar
1328      */
1329     public abstract $abstractvectortype$<S> shiftL(int s);
1330 
1331     /**
1332      * Logically left shifts this vector by the broadcast of an input scalar,
1333      * selecting lane elements controlled by a mask.
1334      * <p>
1335      * This is a vector binary operation where the primitive logical left shift
1336      * operation ({@code <<}) is applied to lane elements.
1337      *
1338      * @param s the input scalar; the number of the bits to left shift
1339      * @param m the mask controlling lane selection
1340      * @return the result of logically left shifting this vector by the
1341      * broadcast of an input scalar
1342      */
1343     public $abstractvectortype$<S> shiftL(int s, Mask<$Boxtype$, S> m) {
1344         return uOp(m, (i, a) -> ($type$) (a << s));
1345     }
1346 
1347     /**
1348      * Logically left shifts this vector by an input vector.
1349      * <p>
1350      * This is a vector binary operation where the primitive logical left shift
1351      * operation ({@code <<}) is applied to lane elements.
1352      *
1353      * @param v the input vector
1354      * @return the result of logically left shifting this vector by the input
1355      * vector
1356      */
1357     public abstract $abstractvectortype$<S> shiftL(Vector<$Boxtype$,S> v);
1358 
1359     /**
1360      * Logically left shifts this vector by an input vector, selecting lane
1361      * elements controlled by a mask.
1362      * <p>
1363      * This is a vector binary operation where the primitive logical left shift
1364      * operation ({@code <<}) is applied to lane elements.
1365      *
1366      * @param v the input vector
1367      * @param m the mask controlling lane selection
1368      * @return the result of logically left shifting this vector by the input
1369      * vector
1370      */
1371     public $abstractvectortype$<S> shiftL(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m) {
1372         return bOp(v, m, (i, a, b) -> ($type$) (a << b));
1373     }
1374 
1375     // logical, or unsigned, shift right
1376 
1377     /**
1378      * Logically right shifts (or unsigned right shifts) this vector by the
1379      * broadcast of an input scalar.
1380      * <p>
1381      * This is a vector binary operation where the primitive logical right shift
1382      * operation ({@code >>>}) is applied to lane elements.
1383      *
1384      * @param s the input scalar; the number of the bits to right shift
1385      * @return the result of logically right shifting this vector by the
1386      * broadcast of an input scalar
1387      */
1388     public abstract $abstractvectortype$<S> shiftR(int s);
1389 
1390     /**
1391      * Logically right shifts (or unsigned right shifts) this vector by the
1392      * broadcast of an input scalar, selecting lane elements controlled by a
1393      * mask.
1394      * <p>
1395      * This is a vector binary operation where the primitive logical right shift
1396      * operation ({@code >>>}) is applied to lane elements.
1397      *
1398      * @param s the input scalar; the number of the bits to right shift
1399      * @return the result of logically right shifting this vector by the
1400      * broadcast of an input scalar
1401      */
1402     public $abstractvectortype$<S> shiftR(int s, Mask<$Boxtype$, S> m) {
1403         return uOp(m, (i, a) -> ($type$) (a >>> s));
1404     }
1405 
1406     /**
1407      * Logically right shifts (or unsigned right shifts) this vector by an
1408      * input vector.
1409      * <p>
1410      * This is a vector binary operation where the primitive logical right shift
1411      * operation ({@code >>>}) is applied to lane elements.
1412      *
1413      * @param v the input vector
1414      * @return the result of logically right shifting this vector by the
1415      * input vector
1416      */
1417     public abstract $abstractvectortype$<S> shiftR(Vector<$Boxtype$,S> v);
1418 
1419     /**
1420      * Logically right shifts (or unsigned right shifts) this vector by an
1421      * input vector, selecting lane elements controlled by a mask.
1422      * <p>
1423      * This is a vector binary operation where the primitive logical right shift
1424      * operation ({@code >>>}) is applied to lane elements.
1425      *
1426      * @param v the input vector
1427      * @param m the mask controlling lane selection
1428      * @return the result of logically right shifting this vector by the
1429      * input vector
1430      */
1431     public $abstractvectortype$<S> shiftR(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m) {
1432         return bOp(v, m, (i, a, b) -> ($type$) (a >>> b));
1433     }
1434 
1435     /**
1436      * Arithmetically right shifts (or signed right shifts) this vector by the
1437      * broadcast of an input scalar.
1438      * <p>
1439      * This is a vector binary operation where the primitive arithmetic right
1440      * shift operation ({@code >>}) is applied to lane elements.
1441      *
1442      * @param s the input scalar; the number of the bits to right shift
1443      * @return the result of arithmetically right shifting this vector by the
1444      * broadcast of an input scalar
1445      */
1446     public abstract $abstractvectortype$<S> aShiftR(int s);
1447 
1448     /**
1449      * Arithmetically right shifts (or signed right shifts) this vector by the
1450      * broadcast of an input scalar, selecting lane elements controlled by a
1451      * mask.
1452      * <p>
1453      * This is a vector binary operation where the primitive arithmetic right
1454      * shift operation ({@code >>}) is applied to lane elements.
1455      *
1456      * @param s the input scalar; the number of the bits to right shift
1457      * @param m the mask controlling lane selection
1458      * @return the result of arithmetically right shifting this vector by the
1459      * broadcast of an input scalar
1460      */
1461     public $abstractvectortype$<S> aShiftR(int s, Mask<$Boxtype$, S> m) {
1462         return uOp(m, (i, a) -> ($type$) (a >> s));
1463     }
1464 
1465     /**
1466      * Arithmetically right shifts (or signed right shifts) this vector by an
1467      * input vector.
1468      * <p>
1469      * This is a vector binary operation where the primitive arithmetic right
1470      * shift operation ({@code >>}) is applied to lane elements.
1471      *
1472      * @param v the input vector
1473      * @return the result of arithmetically right shifting this vector by the
1474      * input vector
1475      */
1476     public abstract $abstractvectortype$<S> aShiftR(Vector<$Boxtype$,S> v);
1477 
1478     /**
1479      * Arithmetically right shifts (or signed right shifts) this vector by an
1480      * input vector, selecting lane elements controlled by a mask.
1481      * <p>
1482      * This is a vector binary operation where the primitive arithmetic right
1483      * shift operation ({@code >>}) is applied to lane elements.
1484      *
1485      * @param v the input vector
1486      * @param m the mask controlling lane selection
1487      * @return the result of arithmetically right shifting this vector by the
1488      * input vector
1489      */
1490     public $abstractvectortype$<S> aShiftR(Vector<$Boxtype$,S> v, Mask<$Boxtype$, S> m) {
1491         return bOp(v, m, (i, a, b) -> ($type$) (a >> b));
1492     }
1493 
1494     /**
1495      * Rotates left this vector by the broadcast of an input scalar.
1496      * <p>
1497      * This is a vector binary operation where the operation
1498      * {@link $Wideboxtype$#rotateLeft} is applied to lane elements and where
1499      * lane elements of this vector apply to the first argument, and lane
1500      * elements of the broadcast vector apply to the second argument (the
1501      * rotation distance).
1502      *
1503      * @param s the input scalar; the number of the bits to rotate left
1504      * @return the result of rotating left this vector by the broadcast of an
1505      * input scalar
1506      */
1507     @ForceInline
1508     public final $abstractvectortype$<S> rotateL(int s) {
1509         return shiftL(s).or(shiftR(-s));
1510     }
1511 
1512     /**
1513      * Rotates left this vector by the broadcast of an input scalar, selecting
1514      * lane elements controlled by a mask.
1515      * <p>
1516      * This is a vector binary operation where the operation
1517      * {@link $Wideboxtype$#rotateLeft} is applied to lane elements and where
1518      * lane elements of this vector apply to the first argument, and lane
1519      * elements of the broadcast vector apply to the second argument (the
1520      * rotation distance).
1521      *
1522      * @param s the input scalar; the number of the bits to rotate left
1523      * @param m the mask controlling lane selection
1524      * @return the result of rotating left this vector by the broadcast of an
1525      * input scalar
1526      */
1527     @ForceInline
1528     public final $abstractvectortype$<S> rotateL(int s, Mask<$Boxtype$, S> m) {
1529         return shiftL(s, m).or(shiftR(-s, m), m);
1530     }
1531 
1532     /**
1533      * Rotates right this vector by the broadcast of an input scalar.
1534      * <p>
1535      * This is a vector binary operation where the operation
1536      * {@link $Wideboxtype$#rotateRight} is applied to lane elements and where
1537      * lane elements of this vector apply to the first argument, and lane
1538      * elements of the broadcast vector apply to the second argument (the
1539      * rotation distance).
1540      *
1541      * @param s the input scalar; the number of the bits to rotate right
1542      * @return the result of rotating right this vector by the broadcast of an
1543      * input scalar
1544      */
1545     @ForceInline
1546     public final $abstractvectortype$<S> rotateR(int s) {
1547         return shiftR(s).or(shiftL(-s));
1548     }
1549 
1550     /**
1551      * Rotates right this vector by the broadcast of an input scalar, selecting
1552      * lane elements controlled by a mask.
1553      * <p>
1554      * This is a vector binary operation where the operation
1555      * {@link $Wideboxtype$#rotateRight} is applied to lane elements and where
1556      * lane elements of this vector apply to the first argument, and lane
1557      * elements of the broadcast vector apply to the second argument (the
1558      * rotation distance).
1559      *
1560      * @param s the input scalar; the number of the bits to rotate right
1561      * @param m the mask controlling lane selection
1562      * @return the result of rotating right this vector by the broadcast of an
1563      * input scalar
1564      */
1565     @ForceInline
1566     public final $abstractvectortype$<S> rotateR(int s, Mask<$Boxtype$, S> m) {
1567         return shiftR(s, m).or(shiftL(-s, m), m);
1568     }
1569 #end[intOrLong]
1570 #end[BITWISE]
1571 
1572     @Override
1573     public abstract void intoByteArray(byte[] a, int ix);
1574 
1575     @Override
1576     public abstract void intoByteArray(byte[] a, int ix, Mask<$Boxtype$, S> m);
1577 
1578     @Override
1579     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1580 
1581     @Override
1582     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$, S> m);
1583 
1584 
1585     // Type specific horizontal reductions
1586 
1587 // @@@ For floating point vectors order matters for reproducibility
1588 //     with equivalent sequential reduction. Some order needs to be specified
1589 //     by default. If that default is sequential encounter order then there
1590 //     could be a "go faster" option that is unspecified, essentially giving
1591 //     implementation flexibility at the expense of reproducibility and/or
1592 //     accuracy.
1593 // @@@ Mask versions?
1594 
1595     /**
1596      * Adds all lane elements of this vector.
1597      * <p>
1598      * This is an associative vector reduction operation where the addition
1599      * operation ({@code +}) is applied to lane elements,
1600      * and the identity value is {@code 0}.
1601      *
1602      * @return the addition of all the lane elements of this vector
1603      */
1604     public abstract $type$ addAll();
1605 
1606     /**
1607      * Adds all lane elements of this vector, selecting lane elements
1608      * controlled by a mask.
1609      * <p>
1610      * This is an associative vector reduction operation where the addition
1611      * operation ({@code +}) is applied to lane elements,
1612      * and the identity value is {@code 0}.
1613      *
1614      * @param m the mask controlling lane selection
1615      * @return the addition of all the lane elements of this vector
1616      */
1617     public abstract $type$ addAll(Mask<$Boxtype$, S> m);
1618 
1619     /**
1620      * Subtracts all lane elements of this vector.
1621      * <p>
1622      * This is an associative vector reduction operation where the subtraction
1623      * operation ({@code -}) is applied to lane elements,
1624      * and the identity value is {@code 0}.
1625      *
1626      * @return the subtraction of all the lane elements of this vector
1627      */
1628     public abstract $type$ subAll();
1629 
1630     /**
1631      * Subtracts all lane elements of this vector, selecting lane elements
1632      * controlled by a mask.
1633      * <p>
1634      * This is an associative vector reduction operation where the subtraction
1635      * operation ({@code -}) is applied to lane elements,
1636      * and the identity value is {@code 0}.
1637      *
1638      * @param m the mask controlling lane selection
1639      * @return the subtraction of all the lane elements of this vector
1640      */
1641     public abstract $type$ subAll(Mask<$Boxtype$, S> m);
1642 
1643     /**
1644      * Multiplies all lane elements of this vector.
1645      * <p>
1646      * This is an associative vector reduction operation where the
1647      * multiplication operation ({@code *}) is applied to lane elements,
1648      * and the identity value is {@code 1}.
1649      *
1650      * @return the multiplication of all the lane elements of this vector
1651      */
1652     public abstract $type$ mulAll();
1653 
1654     /**
1655      * Multiplies all lane elements of this vector, selecting lane elements
1656      * controlled by a mask.
1657      * <p>
1658      * This is an associative vector reduction operation where the
1659      * multiplication operation ({@code *}) is applied to lane elements,
1660      * and the identity value is {@code 1}.
1661      *
1662      * @param m the mask controlling lane selection
1663      * @return the multiplication of all the lane elements of this vector
1664      */
1665     public abstract $type$ mulAll(Mask<$Boxtype$, S> m);
1666 
1667     /**
1668      * Returns the minimum lane element of this vector.
1669      * <p>
1670      * This is an associative vector reduction operation where the operation
1671      * {@code (a, b) -> a > b ? b : a} is applied to lane elements,
1672      * and the identity value is {@link $Boxtype$.MAX_VALUE}.
1673      *
1674      * @return the minimum lane element of this vector
1675      */
1676     public abstract $type$ minAll();
1677 
1678     /**
1679      * Returns the minimum lane element of this vector, selecting lane elements
1680      * controlled by a mask.
1681      * <p>
1682      * This is an associative vector reduction operation where the operation
1683      * {@code (a, b) -> a > b ? b : a} is applied to lane elements,
1684      * and the identity value is {@link $Boxtype$.MAX_VALUE}.
1685      *
1686      * @param m the mask controlling lane selection
1687      * @return the minimum lane element of this vector
1688      */
1689     public abstract $type$ minAll(Mask<$Boxtype$, S> m);
1690 
1691     /**
1692      * Returns the maximum lane element of this vector.
1693      * <p>
1694      * This is an associative vector reduction operation where the operation
1695      * {@code (a, b) -> a < b ? b : a} is applied to lane elements,
1696      * and the identity value is {@link $Boxtype$.MIN_VALUE}.
1697      *
1698      * @return the maximum lane element of this vector
1699      */
1700     public abstract $type$ maxAll();
1701 
1702     /**
1703      * Returns the maximum lane element of this vector, selecting lane elements
1704      * controlled by a mask.
1705      * <p>
1706      * This is an associative vector reduction operation where the operation
1707      * {@code (a, b) -> a < b ? b : a} is applied to lane elements,
1708      * and the identity value is {@link $Boxtype$.MIN_VALUE}.
1709      *
1710      * @param m the mask controlling lane selection
1711      * @return the maximum lane element of this vector
1712      */
1713     public abstract $type$ maxAll(Mask<$Boxtype$, S> m);
1714 
1715 #if[BITWISE]
1716     /**
1717      * Logically ORs all lane elements of this vector.
1718      * <p>
1719      * This is an associative vector reduction operation where the logical OR
1720      * operation ({@code |}) is applied to lane elements,
1721      * and the identity value is {@code 0}.
1722      *
1723      * @return the logical OR all the lane elements of this vector
1724      */
1725     public abstract $type$ orAll();
1726 
1727     /**
1728      * Logically ORs all lane elements of this vector, selecting lane elements
1729      * controlled by a mask.
1730      * <p>
1731      * This is an associative vector reduction operation where the logical OR
1732      * operation ({@code |}) is applied to lane elements,
1733      * and the identity value is {@code 0}.
1734      *
1735      * @param m the mask controlling lane selection
1736      * @return the logical OR all the lane elements of this vector
1737      */
1738     public abstract $type$ orAll(Mask<$Boxtype$, S> m);
1739 
1740     /**
1741      * Logically ANDs all lane elements of this vector.
1742      * <p>
1743      * This is an associative vector reduction operation where the logical AND
1744      * operation ({@code |}) is applied to lane elements,
1745      * and the identity value is {@code -1}.
1746      *
1747      * @return the logical AND all the lane elements of this vector
1748      */
1749     public abstract $type$ andAll();
1750 
1751     /**
1752      * Logically ANDs all lane elements of this vector, selecting lane elements
1753      * controlled by a mask.
1754      * <p>
1755      * This is an associative vector reduction operation where the logical AND
1756      * operation ({@code |}) is applied to lane elements,
1757      * and the identity value is {@code -1}.
1758      *
1759      * @param m the mask controlling lane selection
1760      * @return the logical AND all the lane elements of this vector
1761      */
1762     public abstract $type$ andAll(Mask<$Boxtype$, S> m);
1763 
1764     /**
1765      * Logically XORs all lane elements of this vector.
1766      * <p>
1767      * This is an associative vector reduction operation where the logical XOR
1768      * operation ({@code ^}) is applied to lane elements,
1769      * and the identity value is {@code 0}.
1770      *
1771      * @return the logical XOR all the lane elements of this vector
1772      */
1773     public abstract $type$ xorAll();
1774 
1775     /**
1776      * Logically XORs all lane elements of this vector, selecting lane elements
1777      * controlled by a mask.
1778      * <p>
1779      * This is an associative vector reduction operation where the logical XOR
1780      * operation ({@code ^}) is applied to lane elements,
1781      * and the identity value is {@code 0}.
1782      *
1783      * @param m the mask controlling lane selection
1784      * @return the logical XOR all the lane elements of this vector
1785      */
1786     public abstract $type$ xorAll(Mask<$Boxtype$, S> m);
1787 #end[BITWISE]
1788 
1789     // Type specific accessors
1790 
1791     /**
1792      * Gets the lane element at lane index {@code i}
1793      *
1794      * @param i the lane index
1795      * @return the lane element at lane index {@code i}
1796      * @throws IllegalArgumentException if the index is is out of range
1797      * ({@code < 0 || >= length()})
1798      */
1799     public abstract $type$ get(int i);
1800 
1801     /**
1802      * Replaces the lane element of this vector at lane index {@code i} with
1803      * value {@code e}.
1804      * <p>
1805      * This is a cross-lane operation and behaves as if it returns the result
1806      * of blending this vector with an input vector that is the result of
1807      * broadcasting {@code e} and a mask that has only one lane set at lane
1808      * index {@code i}.
1809      *
1810      * @param i the lane index of the lane element to be replaced
1811      * @param e the value to be placed
1812      * @return the result of replacing the lane element of this vector at lane
1813      * index {@code i} with value {@code e}.
1814      * @throws IllegalArgumentException if the index is is out of range
1815      * ({@code < 0 || >= length()})
1816      */
1817     public abstract $abstractvectortype$<S> with(int i, $type$ e);
1818 
1819     // Type specific extractors
1820 
1821     /**
1822      * Returns an array containing the lane elements of this vector.
1823      * <p>
1824      * This method behaves as if it {@link #intoArray($type$[], int)} stores}
1825      * this vector into an allocated array and returns the array as follows:
1826      * <pre>{@code
1827      *   $type$[] a = new $type$[this.length()];
1828      *   this.intoArray(a, 0);
1829      *   return a;
1830      * }</pre>
1831      *
1832      * @return an array containing the the lane elements of this vector
1833      */
1834     @ForceInline
1835     public final $type$[] toArray() {
1836         // @@@ could allocate without zeroing, see Unsafe.allocateUninitializedArray
1837         $type$[] a = new $type$[species().length()];
1838         intoArray(a, 0);
1839         return a;
1840     }
1841 
1842     /**
1843      * Stores this vector into an array starting at offset.
1844      * <p>
1845      * For each vector lane, where {@code N} is the vector lane index,
1846      * the lane element at index {@code N} is stored into the array at index
1847      * {@code i + N}.
1848      *
1849      * @param a the array
1850      * @param i the offset into the array
1851      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1852      * {@code i > a.length - this.length()}
1853      */
1854     public abstract void intoArray($type$[] a, int i);
1855 
1856     /**
1857      * Stores this vector into an array starting at offset and using a mask.
1858      * <p>
1859      * For each vector lane, where {@code N} is the vector lane index,
1860      * if the mask lane at index {@code N} is set then the lane element at
1861      * index {@code N} is stored into the array index {@code i + N}.
1862      *
1863      * @param a the array
1864      * @param i the offset into the array
1865      * @param m the mask
1866      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1867      * for any vector lane index {@code N} where the mask at lane {@code N}
1868      * is set {@code i >= a.length - N}
1869      */
1870     public abstract void intoArray($type$[] a, int i, Mask<$Boxtype$, S> m);
1871 
1872     /**
1873      * Stores this vector into an array using indexes obtained from an index
1874      * map.
1875      * <p>
1876      * For each vector lane, where {@code N} is the vector lane index, the
1877      * lane element at index {@code N} is stored into the array at index
1878      * {@code i + indexMap[j + N]}.
1879      *
1880      * @param a the array
1881      * @param i the offset into the array, may be negative if relative
1882      * indexes in the index map compensate to produce a value within the
1883      * array bounds
1884      * @param indexMap the index map
1885      * @param j the offset into the index map
1886      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1887      * {@code j > indexMap.length - this.length()},
1888      * or for any vector lane index {@code N} the result of
1889      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1890      */
1891     public void intoArray($type$[] a, int i, int[] indexMap, int j) {
1892         forEach((n, e) -> a[i + indexMap[j + n]] = e);
1893     }
1894 
1895     /**
1896      * Stores this vector into an array using indexes obtained from an index
1897      * map and using a mask.
1898      * <p>
1899      * For each vector lane, where {@code N} is the vector lane index,
1900      * if the mask lane at index {@code N} is set then the lane element at
1901      * index {@code N} is stored into the array at index
1902      * {@code i + indexMap[j + N]}.
1903      *
1904      * @param a the array
1905      * @param i the offset into the array, may be negative if relative
1906      * indexes in the index map compensate to produce a value within the
1907      * array bounds
1908      * @param m the mask
1909      * @param indexMap the index map
1910      * @param j the offset into the index map
1911      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1912      * {@code j > indexMap.length - this.length()},
1913      * or for any vector lane index {@code N} where the mask at lane
1914      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1915      * {@code < 0} or {@code >= a.length}
1916      */
1917     public void intoArray($type$[] a, int i, Mask<$Boxtype$, S> m, int[] indexMap, int j) {
1918         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
1919     }
1920 
1921     // Species
1922 
1923     @Override
1924     public abstract $Type$Species<S> species();
1925 
1926     /**
1927      * A specialized factory for creating {@link $Type$Vector} value of the same
1928      * shape, and a {@link Mask} and {@link Shuffle} values of the same shape
1929      * and {@code int} element type.
1930      *
1931      * @param <S> the type of shape of this species
1932      */
1933     public static abstract class $Type$Species<S extends Vector.Shape> extends Vector.Species<$Boxtype$, S> {
1934         interface FOp {
1935             $type$ apply(int i);
1936         }
1937 
1938         abstract $abstractvectortype$<S> op(FOp f);
1939 
1940         abstract $abstractvectortype$<S> op(Mask<$Boxtype$, S> m, FOp f);
1941 
1942         // Factories
1943 
1944         @Override
1945         public abstract $abstractvectortype$<S> zero();
1946 
1947         /**
1948          * Returns a vector where all lane elements are set to the primitive
1949          * value {@code e}.
1950          *
1951          * @param e the value
1952          * @return a vector of vector where all lane elements are set to
1953          * the primitive value {@code e}
1954          */
1955         public abstract $abstractvectortype$<S> broadcast($type$ e);
1956 
1957         /**
1958          * Returns a vector where the first lane element is set to the primtive
1959          * value {@code e}, all other lane elements are set to the default
1960          * value.
1961          *
1962          * @param e the value
1963          * @return a vector where the first lane element is set to the primitive
1964          * value {@code e}
1965          */
1966         @ForceInline
1967         public final $abstractvectortype$<S> single($type$ e) {
1968             return zero().with(0, e);
1969         }
1970 
1971         /**
1972          * Returns a vector where each lane element is set to a randomly
1973          * generated primitive value.
1974          * @@@ what are the properties of the random number generator?
1975          *
1976          * @return a vector where each lane elements is set to a randomly
1977          * generated primitive value
1978          */
1979 #if[intOrLong]
1980         public $abstractvectortype$<S> random() {
1981             ThreadLocalRandom r = ThreadLocalRandom.current();
1982             return op(i -> r.next$Type$());
1983         }
1984 #else[intOrLong]
1985 #if[FP]
1986         public $abstractvectortype$<S> random() {
1987             ThreadLocalRandom r = ThreadLocalRandom.current();
1988             return op(i -> r.next$Type$());
1989         }
1990 #else[FP]
1991         public $abstractvectortype$<S> random() {
1992             ThreadLocalRandom r = ThreadLocalRandom.current();
1993             return op(i -> ($type$) r.nextInt());
1994         }
1995 #end[FP]
1996 #end[intOrLong]
1997 
1998         /**
1999          * Returns a vector where each lane element is set to a given
2000          * primitive value.
2001          * <p>
2002          * For each vector lane, where {@code N} is the vector lane index, the
2003          * the primitive value at index {@code N} is placed into the resulting
2004          * vector at lane index {@code N}.
2005          *
2006          * @@@ What should happen if es.length < this.length() ? use the default
2007          * value or throw IndexOutOfBoundsException
2008          *
2009          * @param es the given primitive values
2010          * @return a vector where each lane element is set to a given primitive
2011          * value
2012          */
2013         public abstract $abstractvectortype$<S> scalars($type$... es);
2014 
2015         /**
2016          * Loads a vector from an array starting at offset.
2017          * <p>
2018          * For each vector lane, where {@code N} is the vector lane index, the
2019          * array element at index {@code i + N} is placed into the
2020          * resulting vector at lane index {@code N}.
2021          *
2022          * @param a the array
2023          * @param i the offset into the array
2024          * @return the vector loaded from an array
2025          * @throws IndexOutOfBoundsException if {@code i < 0}, or
2026          * {@code i > a.length - this.length()}
2027          */
2028         public abstract $abstractvectortype$<S> fromArray($type$[] a, int i);
2029 
2030         /**
2031          * Loads a vector from an array starting at offset and using a mask.
2032          * <p>
2033          * For each vector lane, where {@code N} is the vector lane index,
2034          * if the mask lane at index {@code N} is set then the array element at
2035          * index {@code i + N} is placed into the resulting vector at lane index
2036          * {@code N}, otherwise the default element value is placed into the
2037          * resulting vector at lane index {@code N}.
2038          *
2039          * @param a the array
2040          * @param i the offset into the array
2041          * @param m the mask
2042          * @return the vector loaded from an array
2043          * @throws IndexOutOfBoundsException if {@code i < 0}, or
2044          * for any vector lane index {@code N} where the mask at lane {@code N}
2045          * is set {@code i > a.length - N}
2046          */
2047         public abstract $abstractvectortype$<S> fromArray($type$[] a, int i, Mask<$Boxtype$, S> m);
2048 
2049         /**
2050          * Loads a vector from an array using indexes obtained from an index
2051          * map.
2052          * <p>
2053          * For each vector lane, where {@code N} is the vector lane index, the
2054          * array element at index {@code i + indexMap[j + N]} is placed into the
2055          * resulting vector at lane index {@code N}.
2056          *
2057          * @param a the array
2058          * @param i the offset into the array, may be negative if relative
2059          * indexes in the index map compensate to produce a value within the
2060          * array bounds
2061          * @param indexMap the index map
2062          * @param j the offset into the index map
2063          * @return the vector loaded from an array
2064          * @throws IndexOutOfBoundsException if {@code j < 0}, or
2065          * {@code j > indexMap.length - this.length()},
2066          * or for any vector lane index {@code N} the result of
2067          * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
2068          */
2069         public $abstractvectortype$<S> fromArray($type$[] a, int i, int[] indexMap, int j) {
2070             return op(n -> a[i + indexMap[j + n]]);
2071         }
2072 
2073         /**
2074          * Loads a vector from an array using indexes obtained from an index
2075          * map and using a mask.
2076          * <p>
2077          * For each vector lane, where {@code N} is the vector lane index,
2078          * if the mask lane at index {@code N} is set then the array element at
2079          * index {@code i + indexMap[j + N]} is placed into the resulting vector
2080          * at lane index {@code N}.
2081          *
2082          * @param a the array
2083          * @param i the offset into the array, may be negative if relative
2084          * indexes in the index map compensate to produce a value within the
2085          * array bounds
2086          * @param indexMap the index map
2087          * @param j the offset into the index map
2088          * @return the vector loaded from an array
2089          * @throws IndexOutOfBoundsException if {@code j < 0}, or
2090          * {@code j > indexMap.length - this.length()},
2091          * or for any vector lane index {@code N} where the mask at lane
2092          * {@code N} is set the result of {@code i + indexMap[j + N]} is
2093          * {@code < 0} or {@code >= a.length}
2094          */
2095         public $abstractvectortype$<S> fromArray($type$[] a, int i, Mask<$Boxtype$, S> m, int[] indexMap, int j) {
2096             return op(m, n -> a[i + indexMap[j + n]]);
2097         }
2098 
2099         @Override
2100         public abstract $abstractvectortype$<S> fromByteArray(byte[] a, int ix);
2101 
2102         @Override
2103         public abstract $abstractvectortype$<S> fromByteArray(byte[] a, int ix, Mask<$Boxtype$, S> m);
2104 
2105         @Override
2106         public abstract $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, int ix);
2107 
2108         @Override
2109         public abstract $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$, S> m);
2110 
2111         @Override
2112         public <F, T extends Shape> $abstractvectortype$<S> reshape(Vector<F, T> o) {
2113             int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE;
2114             ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
2115             o.intoByteBuffer(bb, 0);
2116             return fromByteBuffer(bb, 0);
2117         }
2118 
2119         @Override
2120         public abstract <F> $abstractvectortype$<S> rebracket(Vector<F, S> o);
2121 
2122         @Override
2123         public abstract <T extends Shape> $abstractvectortype$<S> resize(Vector<$Boxtype$, T> o);
2124 
2125         @Override
2126         public abstract <F, T extends Shape> $abstractvectortype$<S> cast(Vector<F, T> v);
2127 
2128     }
2129 
2130     /**
2131      * Finds the preferred species for an element type of {@code $type$}.
2132      * <p>
2133      * A preferred species is a species chosen by the platform that has a
2134      * shape of maximal bit size.  A preferred species for different element
2135      * types will have the same shape, and therefore vectors, masks, and
2136      * shuffles created from such species will be shape compatible.
2137      *
2138      * @return the preferred species for an element type of {@code $type$}
2139      */
2140     @SuppressWarnings("unchecked")
2141     public static $Type$Species<?> preferredSpecies() {
2142         return ($Type$Species<?>) Vector.preferredSpecies($type$.class);
2143     }
2144 
2145     /**
2146      * Finds a species for an element type of {@code $type$} and shape.
2147      *
2148      * @param s the shape
2149      * @param <S> the type of shape
2150      * @return a species for an element type of {@code $type$} and shape
2151      * @throws IllegalArgumentException if no such species exists for the shape
2152      */
2153     @SuppressWarnings("unchecked")
2154     public static <S extends Shape> $Type$Species<S> species(S s) {
2155         Objects.requireNonNull(s);
2156         if (s == Shapes.S_64_BIT) {
2157             return ($Type$Species<S>) $Type$64Vector.SPECIES;
2158         } else if (s == Shapes.S_128_BIT) {
2159             return ($Type$Species<S>) $Type$128Vector.SPECIES;
2160         } else if (s == Shapes.S_256_BIT) {
2161             return ($Type$Species<S>) $Type$256Vector.SPECIES;
2162         } else if (s == Shapes.S_512_BIT) {
2163             return ($Type$Species<S>) $Type$512Vector.SPECIES;
2164         } else {
2165             throw new IllegalArgumentException("Bad shape: " + s);
2166         }
2167     }
2168 }