1. my class X::MustBeParametric { ... }
  2. my class X::TooManyDimensions { ... }
  3. my class X::TypeCheck::Assignment { ... }
  4. my class array does Iterable {
  5. multi method new(array:) { self!create }
  6. multi method new(array: @v) { self!create.STORE(@v) }
  7. multi method new(array: **@v) { self!create.STORE(@v) }
  8. multi method new(array: :$shape!) { self!create-ws($shape) }
  9. multi method new(array: @v, :$shape!) { self!create-ws($shape).STORE(@v) }
  10. multi method new(array: **@v, :$shape!) { self!create-ws($shape).STORE(@v) }
  11. method !create() {
  12. nqp::isnull(nqp::typeparameterized(self))
  13. ?? X::MustBeParametric.new(:type(self)).throw
  14. !! nqp::create(self)
  15. }
  16. method !create-ws($shape) {
  17. nqp::isnull(nqp::typeparameterized(self))
  18. ?? X::MustBeParametric.new(:type(self)).throw
  19. !! nqp::isconcrete($shape)
  20. ?? self!shaped($shape)
  21. !! Metamodel::EnumHOW.ACCEPTS($shape.HOW)
  22. ?? self!shaped($shape.^elems)
  23. !! nqp::create(self)
  24. }
  25. proto method STORE(|) { * }
  26. multi method STORE(array:D: *@values) { self.STORE(@values) }
  27. multi method push(array:D: **@values) { self.append(@values) }
  28. multi method append(array:D: *@values) { self.append(@values) }
  29. multi method unshift(array:D: **@values) { self.unshift(@values) }
  30. multi method prepend(array:D: *@values) { self.unshift(@values) }
  31. sub EQV_DIMENSIONS(Mu \one, Mu \two) is raw {
  32. nqp::iseq_i( # much faster than one.shape eqv two.shape
  33. (my int $dims = nqp::elems(
  34. my $onedims := nqp::dimensions(one)
  35. )),
  36. nqp::elems(my $twodims := nqp::dimensions(two))
  37. ) && nqp::stmts(
  38. (my int $i = -1),
  39. nqp::while(
  40. nqp::islt_i(($i = nqp::add_i($i,1)),$dims)
  41. && nqp::iseq_i(
  42. nqp::atpos_i($onedims,$i),
  43. nqp::atpos_i($twodims,$i)
  44. ),
  45. nqp::null
  46. ),
  47. nqp::iseq_i($i,$dims)
  48. )
  49. }
  50. my role strarray[::T] does Positional[T] is array_type(T) {
  51. #- start of generated part of strarray role -----------------------------------
  52. #- Generated on 2017-04-09T22:40:33+02:00 by tools/build/makeNATIVE_ARRAY.pl6
  53. #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE
  54. multi method AT-POS(strarray:D: int $idx) is raw {
  55. nqp::atposref_s(self, $idx)
  56. }
  57. multi method AT-POS(strarray:D: Int:D $idx) is raw {
  58. nqp::atposref_s(self, $idx)
  59. }
  60. multi method ASSIGN-POS(strarray:D: int $idx, str $value) {
  61. nqp::bindpos_s(self, $idx, $value)
  62. }
  63. multi method ASSIGN-POS(strarray:D: Int:D $idx, str $value) {
  64. nqp::bindpos_s(self, $idx, $value)
  65. }
  66. multi method ASSIGN-POS(strarray:D: int $idx, Str:D $value) {
  67. nqp::bindpos_s(self, $idx, $value)
  68. }
  69. multi method ASSIGN-POS(strarray:D: Int:D $idx, Str:D $value) {
  70. nqp::bindpos_s(self, $idx, $value)
  71. }
  72. multi method ASSIGN-POS(strarray:D: Any $idx, Mu \value) {
  73. X::TypeCheck.new(
  74. operation => "assignment to str array element #$idx",
  75. got => value,
  76. expected => T,
  77. ).throw;
  78. }
  79. multi method STORE(strarray:D: $value) {
  80. nqp::bindpos_s(self, 0, nqp::unbox_s($value));
  81. self
  82. }
  83. multi method STORE(strarray:D: str @values) {
  84. nqp::splice(self,@values,0,0)
  85. }
  86. multi method STORE(strarray:D: @values) {
  87. my int $elems = @values.elems;
  88. nqp::setelems(self, $elems);
  89. my int $i = -1;
  90. nqp::bindpos_s(self, $i,
  91. nqp::unbox_s(@values.AT-POS($i)))
  92. while nqp::islt_i($i = nqp::add_i($i,1),$elems);
  93. self
  94. }
  95. multi method push(strarray:D: str $value) {
  96. nqp::push_s(self, $value);
  97. self
  98. }
  99. multi method push(strarray:D: Str:D $value) {
  100. nqp::push_s(self, $value);
  101. self
  102. }
  103. multi method push(strarray:D: Mu \value) {
  104. X::TypeCheck.new(
  105. operation => 'push to str array',
  106. got => value,
  107. expected => T,
  108. ).throw;
  109. }
  110. multi method append(strarray:D: str $value) {
  111. nqp::push_s(self, $value);
  112. self
  113. }
  114. multi method append(strarray:D: Str:D $value) {
  115. nqp::push_s(self, $value);
  116. self
  117. }
  118. multi method append(strarray:D: str @values) {
  119. nqp::splice(self,@values,nqp::elems(self),0)
  120. }
  121. multi method append(strarray:D: @values) {
  122. fail X::Cannot::Lazy.new(:action<append>, :what(self.^name))
  123. if @values.is-lazy;
  124. nqp::push_s(self, $_) for flat @values;
  125. self
  126. }
  127. method pop(strarray:D: --> str) {
  128. nqp::elems(self) > 0
  129. ?? nqp::pop_s(self)
  130. !! die X::Cannot::Empty.new(:action<pop>, :what(self.^name));
  131. }
  132. method shift(strarray:D: --> str) {
  133. nqp::elems(self) > 0
  134. ?? nqp::shift_s(self)
  135. !! die X::Cannot::Empty.new(:action<shift>, :what(self.^name));
  136. }
  137. multi method unshift(strarray:D: str $value) {
  138. nqp::unshift_s(self, $value);
  139. self
  140. }
  141. multi method unshift(strarray:D: Str:D $value) {
  142. nqp::unshift_s(self, $value);
  143. self
  144. }
  145. multi method unshift(strarray:D: @values) {
  146. fail X::Cannot::Lazy.new(:action<unshift>, :what(self.^name))
  147. if @values.is-lazy;
  148. nqp::unshift_s(self, @values.pop) while @values;
  149. self
  150. }
  151. multi method unshift(strarray:D: Mu \value) {
  152. X::TypeCheck.new(
  153. operation => 'unshift to str array',
  154. got => value,
  155. expected => T,
  156. ).throw;
  157. }
  158. multi method splice(strarray:D: $offset=0, $size=Whatever, *@values) {
  159. fail X::Cannot::Lazy.new(:action('splice in'))
  160. if @values.is-lazy;
  161. my $elems = self.elems;
  162. my int $o = nqp::istype($offset,Callable)
  163. ?? $offset($elems)
  164. !! nqp::istype($offset,Whatever)
  165. ?? $elems
  166. !! $offset.Int;
  167. X::OutOfRange.new(
  168. :what('Offset argument to splice'),
  169. :got($o),
  170. :range("0..$elems"),
  171. ).fail if $o < 0 || $o > $elems; # one after list allowed for "push"
  172. my int $s = nqp::istype($size,Callable)
  173. ?? $size($elems - $o)
  174. !! !defined($size) || nqp::istype($size,Whatever)
  175. ?? $elems - ($o min $elems)
  176. !! $size.Int;
  177. X::OutOfRange.new(
  178. :what('Size argument to splice'),
  179. :got($s),
  180. :range("0..^{$elems - $o}"),
  181. ).fail if $s < 0;
  182. my @ret := nqp::create(self);
  183. my int $i = $o;
  184. my int $n = ($elems min $o + $s) - 1;
  185. while $i <= $n {
  186. nqp::push_s(@ret, nqp::atpos_s(self, $i));
  187. $i = $i + 1;
  188. }
  189. my @splicees := nqp::create(self);
  190. nqp::push_s(@splicees, @values.shift) while @values;
  191. nqp::splice(self, @splicees, $o, $s);
  192. @ret;
  193. }
  194. multi method min(strarray:D:) {
  195. nqp::if(
  196. (my int $elems = self.elems),
  197. nqp::stmts(
  198. (my int $i),
  199. (my str $min = nqp::atpos_s(self,0)),
  200. nqp::while(
  201. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  202. nqp::if(
  203. nqp::islt_s(nqp::atpos_s(self,$i),$min),
  204. ($min = nqp::atpos_s(self,$i))
  205. )
  206. ),
  207. $min
  208. ),
  209. Inf
  210. )
  211. }
  212. multi method max(strarray:D:) {
  213. nqp::if(
  214. (my int $elems = self.elems),
  215. nqp::stmts(
  216. (my int $i),
  217. (my str $max = nqp::atpos_s(self,0)),
  218. nqp::while(
  219. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  220. nqp::if(
  221. nqp::isgt_s(nqp::atpos_s(self,$i),$max),
  222. ($max = nqp::atpos_s(self,$i))
  223. )
  224. ),
  225. $max
  226. ),
  227. -Inf
  228. )
  229. }
  230. multi method minmax(strarray:D:) {
  231. nqp::if(
  232. (my int $elems = self.elems),
  233. nqp::stmts(
  234. (my int $i),
  235. (my str $min =
  236. my str $max = nqp::atpos_s(self,0)),
  237. nqp::while(
  238. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  239. nqp::if(
  240. nqp::islt_s(nqp::atpos_s(self,$i),$min),
  241. ($min = nqp::atpos_s(self,$i)),
  242. nqp::if(
  243. nqp::isgt_s(nqp::atpos_s(self,$i),$max),
  244. ($max = nqp::atpos_s(self,$i))
  245. )
  246. )
  247. ),
  248. Range.new($min,$max)
  249. ),
  250. Range.new(Inf,-Inf)
  251. )
  252. }
  253. method iterator(strarray:D:) {
  254. class :: does Iterator {
  255. has int $!i;
  256. has $!array; # Native array we're iterating
  257. method !SET-SELF(\array) {
  258. $!array := nqp::decont(array);
  259. $!i = -1;
  260. self
  261. }
  262. method new(\array) { nqp::create(self)!SET-SELF(array) }
  263. method pull-one() is raw {
  264. ($!i = $!i + 1) < nqp::elems($!array)
  265. ?? nqp::atposref_s($!array,$!i)
  266. !! IterationEnd
  267. }
  268. method push-all($target --> IterationEnd) {
  269. my int $i = $!i;
  270. my int $elems = nqp::elems($!array);
  271. $target.push(nqp::atposref_s($!array,$i))
  272. while ($i = $i + 1) < $elems;
  273. $!i = $i;
  274. }
  275. }.new(self)
  276. }
  277. method reverse(strarray:D:) is nodal {
  278. nqp::stmts(
  279. (my int $elems = nqp::elems(self)),
  280. (my int $last = nqp::sub_i($elems,1)),
  281. (my int $i = -1),
  282. (my $to := nqp::clone(self)),
  283. nqp::while(
  284. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  285. nqp::bindpos_s($to,nqp::sub_i($last,$i),
  286. nqp::atpos_s(self,$i))
  287. ),
  288. $to
  289. )
  290. }
  291. method rotate(strarray:D: Int(Cool) $rotate = 1) is nodal {
  292. nqp::stmts(
  293. (my int $elems = nqp::elems(self)),
  294. (my $to := nqp::clone(self)),
  295. (my int $i = -1),
  296. (my int $j =
  297. nqp::mod_i(nqp::sub_i(nqp::sub_i($elems,1),$rotate),$elems)),
  298. nqp::if(nqp::islt_i($j,0),($j = nqp::add_i($j,$elems))),
  299. nqp::while(
  300. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  301. nqp::bindpos_s(
  302. $to,
  303. ($j = nqp::mod_i(nqp::add_i($j,1),$elems)),
  304. nqp::atpos_s(self,$i)
  305. ),
  306. ),
  307. $to
  308. )
  309. }
  310. multi method sort(strarray:D:) {
  311. Rakudo::Sorting.MERGESORT-str(nqp::clone(self))
  312. }
  313. #- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE
  314. #- end of generated part of strarray role -------------------------------------
  315. method join(strarray:D: $delim = '') {
  316. my str $empty = "";
  317. my int $elems = nqp::elems(self);
  318. my int $i = -1;
  319. nqp::bindpos_s(self,$i,$empty)
  320. if nqp::isnull_s(nqp::atposref_s(self,$i))
  321. while nqp::islt_i(++$i,$elems);
  322. nqp::join($delim.Str,self)
  323. }
  324. }
  325. my role intarray[::T] does Positional[T] is array_type(T) {
  326. #- start of generated part of intarray role -----------------------------------
  327. #- Generated on 2017-04-09T22:40:33+02:00 by tools/build/makeNATIVE_ARRAY.pl6
  328. #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE
  329. multi method AT-POS(intarray:D: int $idx) is raw {
  330. nqp::atposref_i(self, $idx)
  331. }
  332. multi method AT-POS(intarray:D: Int:D $idx) is raw {
  333. nqp::atposref_i(self, $idx)
  334. }
  335. multi method ASSIGN-POS(intarray:D: int $idx, int $value) {
  336. nqp::bindpos_i(self, $idx, $value)
  337. }
  338. multi method ASSIGN-POS(intarray:D: Int:D $idx, int $value) {
  339. nqp::bindpos_i(self, $idx, $value)
  340. }
  341. multi method ASSIGN-POS(intarray:D: int $idx, Int:D $value) {
  342. nqp::bindpos_i(self, $idx, $value)
  343. }
  344. multi method ASSIGN-POS(intarray:D: Int:D $idx, Int:D $value) {
  345. nqp::bindpos_i(self, $idx, $value)
  346. }
  347. multi method ASSIGN-POS(intarray:D: Any $idx, Mu \value) {
  348. X::TypeCheck.new(
  349. operation => "assignment to int array element #$idx",
  350. got => value,
  351. expected => T,
  352. ).throw;
  353. }
  354. multi method STORE(intarray:D: $value) {
  355. nqp::bindpos_i(self, 0, nqp::unbox_i($value));
  356. self
  357. }
  358. multi method STORE(intarray:D: int @values) {
  359. nqp::splice(self,@values,0,0)
  360. }
  361. multi method STORE(intarray:D: @values) {
  362. my int $elems = @values.elems;
  363. nqp::setelems(self, $elems);
  364. my int $i = -1;
  365. nqp::bindpos_i(self, $i,
  366. nqp::unbox_i(@values.AT-POS($i)))
  367. while nqp::islt_i($i = nqp::add_i($i,1),$elems);
  368. self
  369. }
  370. multi method push(intarray:D: int $value) {
  371. nqp::push_i(self, $value);
  372. self
  373. }
  374. multi method push(intarray:D: Int:D $value) {
  375. nqp::push_i(self, $value);
  376. self
  377. }
  378. multi method push(intarray:D: Mu \value) {
  379. X::TypeCheck.new(
  380. operation => 'push to int array',
  381. got => value,
  382. expected => T,
  383. ).throw;
  384. }
  385. multi method append(intarray:D: int $value) {
  386. nqp::push_i(self, $value);
  387. self
  388. }
  389. multi method append(intarray:D: Int:D $value) {
  390. nqp::push_i(self, $value);
  391. self
  392. }
  393. multi method append(intarray:D: int @values) {
  394. nqp::splice(self,@values,nqp::elems(self),0)
  395. }
  396. multi method append(intarray:D: @values) {
  397. fail X::Cannot::Lazy.new(:action<append>, :what(self.^name))
  398. if @values.is-lazy;
  399. nqp::push_i(self, $_) for flat @values;
  400. self
  401. }
  402. method pop(intarray:D: --> int) {
  403. nqp::elems(self) > 0
  404. ?? nqp::pop_i(self)
  405. !! die X::Cannot::Empty.new(:action<pop>, :what(self.^name));
  406. }
  407. method shift(intarray:D: --> int) {
  408. nqp::elems(self) > 0
  409. ?? nqp::shift_i(self)
  410. !! die X::Cannot::Empty.new(:action<shift>, :what(self.^name));
  411. }
  412. multi method unshift(intarray:D: int $value) {
  413. nqp::unshift_i(self, $value);
  414. self
  415. }
  416. multi method unshift(intarray:D: Int:D $value) {
  417. nqp::unshift_i(self, $value);
  418. self
  419. }
  420. multi method unshift(intarray:D: @values) {
  421. fail X::Cannot::Lazy.new(:action<unshift>, :what(self.^name))
  422. if @values.is-lazy;
  423. nqp::unshift_i(self, @values.pop) while @values;
  424. self
  425. }
  426. multi method unshift(intarray:D: Mu \value) {
  427. X::TypeCheck.new(
  428. operation => 'unshift to int array',
  429. got => value,
  430. expected => T,
  431. ).throw;
  432. }
  433. multi method splice(intarray:D: $offset=0, $size=Whatever, *@values) {
  434. fail X::Cannot::Lazy.new(:action('splice in'))
  435. if @values.is-lazy;
  436. my $elems = self.elems;
  437. my int $o = nqp::istype($offset,Callable)
  438. ?? $offset($elems)
  439. !! nqp::istype($offset,Whatever)
  440. ?? $elems
  441. !! $offset.Int;
  442. X::OutOfRange.new(
  443. :what('Offset argument to splice'),
  444. :got($o),
  445. :range("0..$elems"),
  446. ).fail if $o < 0 || $o > $elems; # one after list allowed for "push"
  447. my int $s = nqp::istype($size,Callable)
  448. ?? $size($elems - $o)
  449. !! !defined($size) || nqp::istype($size,Whatever)
  450. ?? $elems - ($o min $elems)
  451. !! $size.Int;
  452. X::OutOfRange.new(
  453. :what('Size argument to splice'),
  454. :got($s),
  455. :range("0..^{$elems - $o}"),
  456. ).fail if $s < 0;
  457. my @ret := nqp::create(self);
  458. my int $i = $o;
  459. my int $n = ($elems min $o + $s) - 1;
  460. while $i <= $n {
  461. nqp::push_i(@ret, nqp::atpos_i(self, $i));
  462. $i = $i + 1;
  463. }
  464. my @splicees := nqp::create(self);
  465. nqp::push_i(@splicees, @values.shift) while @values;
  466. nqp::splice(self, @splicees, $o, $s);
  467. @ret;
  468. }
  469. multi method min(intarray:D:) {
  470. nqp::if(
  471. (my int $elems = self.elems),
  472. nqp::stmts(
  473. (my int $i),
  474. (my int $min = nqp::atpos_i(self,0)),
  475. nqp::while(
  476. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  477. nqp::if(
  478. nqp::islt_i(nqp::atpos_i(self,$i),$min),
  479. ($min = nqp::atpos_i(self,$i))
  480. )
  481. ),
  482. $min
  483. ),
  484. Inf
  485. )
  486. }
  487. multi method max(intarray:D:) {
  488. nqp::if(
  489. (my int $elems = self.elems),
  490. nqp::stmts(
  491. (my int $i),
  492. (my int $max = nqp::atpos_i(self,0)),
  493. nqp::while(
  494. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  495. nqp::if(
  496. nqp::isgt_i(nqp::atpos_i(self,$i),$max),
  497. ($max = nqp::atpos_i(self,$i))
  498. )
  499. ),
  500. $max
  501. ),
  502. -Inf
  503. )
  504. }
  505. multi method minmax(intarray:D:) {
  506. nqp::if(
  507. (my int $elems = self.elems),
  508. nqp::stmts(
  509. (my int $i),
  510. (my int $min =
  511. my int $max = nqp::atpos_i(self,0)),
  512. nqp::while(
  513. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  514. nqp::if(
  515. nqp::islt_i(nqp::atpos_i(self,$i),$min),
  516. ($min = nqp::atpos_i(self,$i)),
  517. nqp::if(
  518. nqp::isgt_i(nqp::atpos_i(self,$i),$max),
  519. ($max = nqp::atpos_i(self,$i))
  520. )
  521. )
  522. ),
  523. Range.new($min,$max)
  524. ),
  525. Range.new(Inf,-Inf)
  526. )
  527. }
  528. method iterator(intarray:D:) {
  529. class :: does Iterator {
  530. has int $!i;
  531. has $!array; # Native array we're iterating
  532. method !SET-SELF(\array) {
  533. $!array := nqp::decont(array);
  534. $!i = -1;
  535. self
  536. }
  537. method new(\array) { nqp::create(self)!SET-SELF(array) }
  538. method pull-one() is raw {
  539. ($!i = $!i + 1) < nqp::elems($!array)
  540. ?? nqp::atposref_i($!array,$!i)
  541. !! IterationEnd
  542. }
  543. method push-all($target --> IterationEnd) {
  544. my int $i = $!i;
  545. my int $elems = nqp::elems($!array);
  546. $target.push(nqp::atposref_i($!array,$i))
  547. while ($i = $i + 1) < $elems;
  548. $!i = $i;
  549. }
  550. }.new(self)
  551. }
  552. method reverse(intarray:D:) is nodal {
  553. nqp::stmts(
  554. (my int $elems = nqp::elems(self)),
  555. (my int $last = nqp::sub_i($elems,1)),
  556. (my int $i = -1),
  557. (my $to := nqp::clone(self)),
  558. nqp::while(
  559. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  560. nqp::bindpos_i($to,nqp::sub_i($last,$i),
  561. nqp::atpos_i(self,$i))
  562. ),
  563. $to
  564. )
  565. }
  566. method rotate(intarray:D: Int(Cool) $rotate = 1) is nodal {
  567. nqp::stmts(
  568. (my int $elems = nqp::elems(self)),
  569. (my $to := nqp::clone(self)),
  570. (my int $i = -1),
  571. (my int $j =
  572. nqp::mod_i(nqp::sub_i(nqp::sub_i($elems,1),$rotate),$elems)),
  573. nqp::if(nqp::islt_i($j,0),($j = nqp::add_i($j,$elems))),
  574. nqp::while(
  575. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  576. nqp::bindpos_i(
  577. $to,
  578. ($j = nqp::mod_i(nqp::add_i($j,1),$elems)),
  579. nqp::atpos_i(self,$i)
  580. ),
  581. ),
  582. $to
  583. )
  584. }
  585. multi method sort(intarray:D:) {
  586. Rakudo::Sorting.MERGESORT-int(nqp::clone(self))
  587. }
  588. #- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE
  589. #- end of generated part of intarray role -------------------------------------
  590. method join(intarray:D: $delim = '') {
  591. my int $elems = nqp::elems(self);
  592. my $list := nqp::setelems(nqp::list_s,$elems);
  593. my int $i = -1;
  594. nqp::bindpos_s($list,$i,
  595. nqp::tostr_I(nqp::p6box_i(nqp::atpos_i(self,$i))))
  596. while nqp::islt_i(++$i,$elems);
  597. nqp::join($delim.Str,$list)
  598. }
  599. multi method STORE(intarray:D: Range:D $range) {
  600. nqp::if(
  601. $range.is-int,
  602. nqp::stmts(
  603. (my int $val = $range.min + $range.excludes-min),
  604. (my int $max = $range.max - $range.excludes-max),
  605. nqp::setelems(self, nqp::add_i(nqp::sub_i($max,$val),1)),
  606. (my int $i = -1),
  607. ($val = nqp::sub_i($val,1)),
  608. nqp::while(
  609. nqp::isle_i(($val = nqp::add_i($val,1)),$max),
  610. nqp::bindpos_i(self,($i = nqp::add_i($i,1)),$val)
  611. ),
  612. self
  613. ),
  614. (die "Can only initialize an int array with an int Range")
  615. )
  616. }
  617. }
  618. my role numarray[::T] does Positional[T] is array_type(T) {
  619. #- start of generated part of numarray role -----------------------------------
  620. #- Generated on 2017-04-09T22:40:33+02:00 by tools/build/makeNATIVE_ARRAY.pl6
  621. #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE
  622. multi method AT-POS(numarray:D: int $idx) is raw {
  623. nqp::atposref_n(self, $idx)
  624. }
  625. multi method AT-POS(numarray:D: Int:D $idx) is raw {
  626. nqp::atposref_n(self, $idx)
  627. }
  628. multi method ASSIGN-POS(numarray:D: int $idx, num $value) {
  629. nqp::bindpos_n(self, $idx, $value)
  630. }
  631. multi method ASSIGN-POS(numarray:D: Int:D $idx, num $value) {
  632. nqp::bindpos_n(self, $idx, $value)
  633. }
  634. multi method ASSIGN-POS(numarray:D: int $idx, Num:D $value) {
  635. nqp::bindpos_n(self, $idx, $value)
  636. }
  637. multi method ASSIGN-POS(numarray:D: Int:D $idx, Num:D $value) {
  638. nqp::bindpos_n(self, $idx, $value)
  639. }
  640. multi method ASSIGN-POS(numarray:D: Any $idx, Mu \value) {
  641. X::TypeCheck.new(
  642. operation => "assignment to num array element #$idx",
  643. got => value,
  644. expected => T,
  645. ).throw;
  646. }
  647. multi method STORE(numarray:D: $value) {
  648. nqp::bindpos_n(self, 0, nqp::unbox_n($value));
  649. self
  650. }
  651. multi method STORE(numarray:D: num @values) {
  652. nqp::splice(self,@values,0,0)
  653. }
  654. multi method STORE(numarray:D: @values) {
  655. my int $elems = @values.elems;
  656. nqp::setelems(self, $elems);
  657. my int $i = -1;
  658. nqp::bindpos_n(self, $i,
  659. nqp::unbox_n(@values.AT-POS($i)))
  660. while nqp::islt_i($i = nqp::add_i($i,1),$elems);
  661. self
  662. }
  663. multi method push(numarray:D: num $value) {
  664. nqp::push_n(self, $value);
  665. self
  666. }
  667. multi method push(numarray:D: Num:D $value) {
  668. nqp::push_n(self, $value);
  669. self
  670. }
  671. multi method push(numarray:D: Mu \value) {
  672. X::TypeCheck.new(
  673. operation => 'push to num array',
  674. got => value,
  675. expected => T,
  676. ).throw;
  677. }
  678. multi method append(numarray:D: num $value) {
  679. nqp::push_n(self, $value);
  680. self
  681. }
  682. multi method append(numarray:D: Num:D $value) {
  683. nqp::push_n(self, $value);
  684. self
  685. }
  686. multi method append(numarray:D: num @values) {
  687. nqp::splice(self,@values,nqp::elems(self),0)
  688. }
  689. multi method append(numarray:D: @values) {
  690. fail X::Cannot::Lazy.new(:action<append>, :what(self.^name))
  691. if @values.is-lazy;
  692. nqp::push_n(self, $_) for flat @values;
  693. self
  694. }
  695. method pop(numarray:D: --> num) {
  696. nqp::elems(self) > 0
  697. ?? nqp::pop_n(self)
  698. !! die X::Cannot::Empty.new(:action<pop>, :what(self.^name));
  699. }
  700. method shift(numarray:D: --> num) {
  701. nqp::elems(self) > 0
  702. ?? nqp::shift_n(self)
  703. !! die X::Cannot::Empty.new(:action<shift>, :what(self.^name));
  704. }
  705. multi method unshift(numarray:D: num $value) {
  706. nqp::unshift_n(self, $value);
  707. self
  708. }
  709. multi method unshift(numarray:D: Num:D $value) {
  710. nqp::unshift_n(self, $value);
  711. self
  712. }
  713. multi method unshift(numarray:D: @values) {
  714. fail X::Cannot::Lazy.new(:action<unshift>, :what(self.^name))
  715. if @values.is-lazy;
  716. nqp::unshift_n(self, @values.pop) while @values;
  717. self
  718. }
  719. multi method unshift(numarray:D: Mu \value) {
  720. X::TypeCheck.new(
  721. operation => 'unshift to num array',
  722. got => value,
  723. expected => T,
  724. ).throw;
  725. }
  726. multi method splice(numarray:D: $offset=0, $size=Whatever, *@values) {
  727. fail X::Cannot::Lazy.new(:action('splice in'))
  728. if @values.is-lazy;
  729. my $elems = self.elems;
  730. my int $o = nqp::istype($offset,Callable)
  731. ?? $offset($elems)
  732. !! nqp::istype($offset,Whatever)
  733. ?? $elems
  734. !! $offset.Int;
  735. X::OutOfRange.new(
  736. :what('Offset argument to splice'),
  737. :got($o),
  738. :range("0..$elems"),
  739. ).fail if $o < 0 || $o > $elems; # one after list allowed for "push"
  740. my int $s = nqp::istype($size,Callable)
  741. ?? $size($elems - $o)
  742. !! !defined($size) || nqp::istype($size,Whatever)
  743. ?? $elems - ($o min $elems)
  744. !! $size.Int;
  745. X::OutOfRange.new(
  746. :what('Size argument to splice'),
  747. :got($s),
  748. :range("0..^{$elems - $o}"),
  749. ).fail if $s < 0;
  750. my @ret := nqp::create(self);
  751. my int $i = $o;
  752. my int $n = ($elems min $o + $s) - 1;
  753. while $i <= $n {
  754. nqp::push_n(@ret, nqp::atpos_n(self, $i));
  755. $i = $i + 1;
  756. }
  757. my @splicees := nqp::create(self);
  758. nqp::push_n(@splicees, @values.shift) while @values;
  759. nqp::splice(self, @splicees, $o, $s);
  760. @ret;
  761. }
  762. multi method min(numarray:D:) {
  763. nqp::if(
  764. (my int $elems = self.elems),
  765. nqp::stmts(
  766. (my int $i),
  767. (my num $min = nqp::atpos_n(self,0)),
  768. nqp::while(
  769. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  770. nqp::if(
  771. nqp::islt_n(nqp::atpos_n(self,$i),$min),
  772. ($min = nqp::atpos_n(self,$i))
  773. )
  774. ),
  775. $min
  776. ),
  777. Inf
  778. )
  779. }
  780. multi method max(numarray:D:) {
  781. nqp::if(
  782. (my int $elems = self.elems),
  783. nqp::stmts(
  784. (my int $i),
  785. (my num $max = nqp::atpos_n(self,0)),
  786. nqp::while(
  787. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  788. nqp::if(
  789. nqp::isgt_n(nqp::atpos_n(self,$i),$max),
  790. ($max = nqp::atpos_n(self,$i))
  791. )
  792. ),
  793. $max
  794. ),
  795. -Inf
  796. )
  797. }
  798. multi method minmax(numarray:D:) {
  799. nqp::if(
  800. (my int $elems = self.elems),
  801. nqp::stmts(
  802. (my int $i),
  803. (my num $min =
  804. my num $max = nqp::atpos_n(self,0)),
  805. nqp::while(
  806. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  807. nqp::if(
  808. nqp::islt_n(nqp::atpos_n(self,$i),$min),
  809. ($min = nqp::atpos_n(self,$i)),
  810. nqp::if(
  811. nqp::isgt_n(nqp::atpos_n(self,$i),$max),
  812. ($max = nqp::atpos_n(self,$i))
  813. )
  814. )
  815. ),
  816. Range.new($min,$max)
  817. ),
  818. Range.new(Inf,-Inf)
  819. )
  820. }
  821. method iterator(numarray:D:) {
  822. class :: does Iterator {
  823. has int $!i;
  824. has $!array; # Native array we're iterating
  825. method !SET-SELF(\array) {
  826. $!array := nqp::decont(array);
  827. $!i = -1;
  828. self
  829. }
  830. method new(\array) { nqp::create(self)!SET-SELF(array) }
  831. method pull-one() is raw {
  832. ($!i = $!i + 1) < nqp::elems($!array)
  833. ?? nqp::atposref_n($!array,$!i)
  834. !! IterationEnd
  835. }
  836. method push-all($target --> IterationEnd) {
  837. my int $i = $!i;
  838. my int $elems = nqp::elems($!array);
  839. $target.push(nqp::atposref_n($!array,$i))
  840. while ($i = $i + 1) < $elems;
  841. $!i = $i;
  842. }
  843. }.new(self)
  844. }
  845. method reverse(numarray:D:) is nodal {
  846. nqp::stmts(
  847. (my int $elems = nqp::elems(self)),
  848. (my int $last = nqp::sub_i($elems,1)),
  849. (my int $i = -1),
  850. (my $to := nqp::clone(self)),
  851. nqp::while(
  852. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  853. nqp::bindpos_n($to,nqp::sub_i($last,$i),
  854. nqp::atpos_n(self,$i))
  855. ),
  856. $to
  857. )
  858. }
  859. method rotate(numarray:D: Int(Cool) $rotate = 1) is nodal {
  860. nqp::stmts(
  861. (my int $elems = nqp::elems(self)),
  862. (my $to := nqp::clone(self)),
  863. (my int $i = -1),
  864. (my int $j =
  865. nqp::mod_i(nqp::sub_i(nqp::sub_i($elems,1),$rotate),$elems)),
  866. nqp::if(nqp::islt_i($j,0),($j = nqp::add_i($j,$elems))),
  867. nqp::while(
  868. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  869. nqp::bindpos_n(
  870. $to,
  871. ($j = nqp::mod_i(nqp::add_i($j,1),$elems)),
  872. nqp::atpos_n(self,$i)
  873. ),
  874. ),
  875. $to
  876. )
  877. }
  878. multi method sort(numarray:D:) {
  879. Rakudo::Sorting.MERGESORT-num(nqp::clone(self))
  880. }
  881. #- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE
  882. #- end of generated part of numarray role -------------------------------------
  883. multi method STORE(numarray:D: Range:D $range) {
  884. my num $val = $range.min;
  885. $val = $val + 1 if $range.excludes-min;
  886. my num $max = $range.max;
  887. $max = $max - 1 if $range.excludes-max;
  888. fail X::Cannot::Lazy.new(:action<initialize>,:what(self.^name))
  889. if $val == -Inf || $max == Inf;
  890. nqp::setelems(self, ($max - $val + 1).Int );
  891. my int $i;
  892. while $val <= $max {
  893. nqp::bindpos_n(self, $i, $val);
  894. $val = $val + 1;
  895. $i = $i + 1;
  896. }
  897. self
  898. }
  899. }
  900. role shapedarray does Rakudo::Internals::ShapedArrayCommon {
  901. method shape() {
  902. nqp::stmts(
  903. (my $idims := nqp::dimensions(self)),
  904. (my int $dims = nqp::elems($idims)),
  905. (my $odims := nqp::setelems(nqp::create(IterationBuffer),$dims)),
  906. (my int $i = -1),
  907. nqp::while(
  908. nqp::islt_i(($i = nqp::add_i($i,1)),$dims),
  909. nqp::bindpos($odims,$i,nqp::atpos_i($idims,$i))
  910. ),
  911. nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',$odims)
  912. )
  913. }
  914. multi method EXISTS-POS(::?CLASS:D: **@indices) {
  915. nqp::p6bool(
  916. nqp::stmts(
  917. (my int $numdims = nqp::numdimensions(self)),
  918. (my int $numind = @indices.elems), # reifies
  919. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  920. nqp::if(
  921. nqp::isle_i($numind,$numdims),
  922. nqp::stmts(
  923. (my $dims := nqp::dimensions(self)),
  924. (my int $i = -1),
  925. nqp::while(
  926. nqp::islt_i(($i = nqp::add_i($i,1)),$numind)
  927. && nqp::isge_i(nqp::atpos($indices,$i),0)
  928. && nqp::islt_i(
  929. nqp::atpos($indices,$i),
  930. nqp::atpos_i($dims,$i)
  931. ),
  932. nqp::null
  933. ),
  934. nqp::iseq_i($i,$numind)
  935. )
  936. )
  937. )
  938. )
  939. }
  940. proto method STORE(|) { * }
  941. multi method STORE(::?CLASS:D: Mu \item) {
  942. X::Assignment::ToShaped.new(shape => self.shape).throw
  943. }
  944. }
  945. #- start of generated part of shapedintarray role -----------------------------
  946. #- Generated on 2017-01-22T22:56:03+01:00 by tools/build/makeNATIVE_SHAPED_ARRAY.pl6
  947. #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE
  948. role shapedintarray does shapedarray {
  949. multi method AT-POS(::?CLASS:D: **@indices) is raw {
  950. nqp::if(
  951. nqp::iseq_i(
  952. (my int $numdims = nqp::numdimensions(self)),
  953. (my int $numind = @indices.elems), # reifies
  954. ),
  955. nqp::stmts(
  956. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  957. (my $idxs := nqp::list_i),
  958. nqp::while( # native index list
  959. nqp::isge_i(($numdims = nqp::sub_i($numdims,1)),0),
  960. nqp::push_i($idxs,nqp::shift($indices))
  961. ),
  962. nqp::multidimref_i(self,$idxs)
  963. ),
  964. nqp::if(
  965. nqp::isgt_i($numind,$numdims),
  966. X::TooManyDimensions.new(
  967. operation => 'access',
  968. got-dimensions => $numind,
  969. needed-dimensions => $numdims
  970. ).throw,
  971. X::NYI.new(
  972. feature => "Partially dimensioned views of shaped arrays"
  973. ).throw
  974. )
  975. )
  976. }
  977. multi method ASSIGN-POS(::?CLASS:D: **@indices) {
  978. nqp::stmts(
  979. (my int $value = @indices.pop),
  980. nqp::if(
  981. nqp::iseq_i(
  982. (my int $numdims = nqp::numdimensions(self)),
  983. (my int $numind = @indices.elems), # reifies
  984. ),
  985. nqp::stmts(
  986. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  987. (my $idxs := nqp::list_i),
  988. nqp::while( # native index list
  989. nqp::isge_i(($numdims = nqp::sub_i($numdims,1)),0),
  990. nqp::push_i($idxs,nqp::shift($indices))
  991. ),
  992. nqp::bindposnd_i(self, $idxs, $value)
  993. ),
  994. nqp::if(
  995. nqp::isgt_i($numind,$numdims),
  996. X::TooManyDimensions,
  997. X::NotEnoughDimensions
  998. ).new(
  999. operation => 'assign to',
  1000. got-dimensions => $numind,
  1001. needed-dimensions => $numdims
  1002. ).throw
  1003. )
  1004. )
  1005. }
  1006. sub NATCPY(Mu \to, Mu \from) is raw {
  1007. class :: does Rakudo::Iterator::ShapeLeaf {
  1008. has Mu $!from;
  1009. method INIT(Mu \to, Mu \from) {
  1010. nqp::stmts(
  1011. ($!from := from),
  1012. self.SET-SELF(to)
  1013. )
  1014. }
  1015. method new(Mu \to, Mu \from) {
  1016. nqp::create(self).INIT(to,from)
  1017. }
  1018. method result(--> Nil) {
  1019. nqp::bindposnd_i($!list,$!indices,
  1020. nqp::multidimref_i($!from,$!indices))
  1021. }
  1022. }.new(to,from).sink-all;
  1023. to
  1024. }
  1025. sub OBJCPY(Mu \to, Mu \from) is raw {
  1026. class :: does Rakudo::Iterator::ShapeLeaf {
  1027. has Mu $!from;
  1028. method INIT(Mu \to, Mu \from) {
  1029. nqp::stmts(
  1030. ($!from := nqp::getattr(from,List,'$!reified')),
  1031. self.SET-SELF(to)
  1032. )
  1033. }
  1034. method new(Mu \to, Mu \from) {
  1035. nqp::create(self).INIT(to,from)
  1036. }
  1037. method result(--> Nil) {
  1038. nqp::bindposnd_i($!list,$!indices,
  1039. nqp::atposnd($!from,$!indices))
  1040. }
  1041. }.new(to,from).sink-all;
  1042. to
  1043. }
  1044. sub ITERCPY(Mu \to, Mu \from) is raw {
  1045. class :: does Rakudo::Iterator::ShapeBranch {
  1046. has $!iterators;
  1047. method INIT(\to,\from) {
  1048. nqp::stmts(
  1049. self.SET-SELF(to),
  1050. ($!iterators := nqp::setelems(
  1051. nqp::list(from.iterator),
  1052. nqp::add_i($!maxdim,1)
  1053. )),
  1054. self
  1055. )
  1056. }
  1057. method new(\to,\from) { nqp::create(self).INIT(to,from) }
  1058. method done(--> Nil) {
  1059. nqp::unless( # verify lowest
  1060. nqp::atpos($!iterators,0).is-lazy # finite iterator
  1061. || nqp::eqaddr( # and something there
  1062. nqp::atpos($!iterators,0).pull-one,IterationEnd),
  1063. nqp::atposnd_i($!list,$!indices) # boom!
  1064. )
  1065. }
  1066. method process(--> Nil) {
  1067. nqp::stmts(
  1068. (my int $i = $!level),
  1069. nqp::while(
  1070. nqp::isle_i(($i = nqp::add_i($i,1)),$!maxdim),
  1071. nqp::if(
  1072. nqp::eqaddr((my $item := # exhausted ?
  1073. nqp::atpos($!iterators,nqp::sub_i($i,1)).pull-one),
  1074. IterationEnd
  1075. ),
  1076. nqp::bindpos($!iterators,$i, # add an empty one
  1077. Rakudo::Iterator.Empty),
  1078. nqp::if( # is it an iterator?
  1079. nqp::istype($item,Iterable) && nqp::isconcrete($item),
  1080. nqp::bindpos($!iterators,$i,$item.iterator),
  1081. X::Assignment::ToShaped.new(shape => $!dims).throw
  1082. )
  1083. )
  1084. ),
  1085. (my $iter := nqp::atpos($!iterators,$!maxdim)),
  1086. nqp::until( # loop over highest dim
  1087. nqp::eqaddr((my $pulled := $iter.pull-one),IterationEnd)
  1088. || nqp::isgt_i(nqp::atpos_i($!indices,$!maxdim),$!maxind),
  1089. nqp::stmts(
  1090. nqp::bindposnd_i($!list,$!indices,$pulled),
  1091. nqp::bindpos_i($!indices,$!maxdim, # increment index
  1092. nqp::add_i(nqp::atpos_i($!indices,$!maxdim),1))
  1093. )
  1094. ),
  1095. nqp::unless(
  1096. nqp::eqaddr($pulled,IterationEnd) # if not exhausted
  1097. || nqp::isle_i( # and index too high
  1098. nqp::atpos_i($!indices,$!maxdim),$!maxind)
  1099. || $iter.is-lazy, # and not lazy
  1100. nqp::atposnd_i($!list,$!indices) # boom!
  1101. )
  1102. )
  1103. }
  1104. }.new(to,from).sink-all;
  1105. to
  1106. }
  1107. multi method STORE(::?CLASS:D: ::?CLASS:D \from) {
  1108. nqp::if(
  1109. EQV_DIMENSIONS(self,from),
  1110. NATCPY(self,from),
  1111. X::Assignment::ArrayShapeMismatch.new(
  1112. source-shape => from.shape,
  1113. target-shape => self.shape
  1114. ).throw
  1115. )
  1116. }
  1117. multi method STORE(::?CLASS:D: array:D \from) {
  1118. nqp::if(
  1119. nqp::istype(from.of,Int),
  1120. nqp::if(
  1121. EQV_DIMENSIONS(self,from),
  1122. NATCPY(self,from),
  1123. X::Assignment::ArrayShapeMismatch.new(
  1124. source-shape => from.shape,
  1125. target-shape => self.shape
  1126. ).throw
  1127. ),
  1128. X::TypeCheck::Assignment.new(
  1129. symbol => self.^name ~ '[' ~ self.shape.join(';') ~ ']',
  1130. expected => Int,
  1131. got => from.of
  1132. ).throw
  1133. )
  1134. }
  1135. multi method STORE(::?CLASS:D: Iterable:D \from) {
  1136. nqp::if(
  1137. nqp::can(from,'shape'),
  1138. nqp::if(
  1139. from.shape eqv self.shape,
  1140. OBJCPY(self,from),
  1141. X::Assignment::ArrayShapeMismatch.new(
  1142. source-shape => from.shape,
  1143. target-shape => self.shape
  1144. ).throw
  1145. ),
  1146. ITERCPY(self,from)
  1147. )
  1148. }
  1149. method iterator(::?CLASS:D:) {
  1150. class :: does Rakudo::Iterator::ShapeLeaf {
  1151. method result() is raw {
  1152. nqp::multidimref_i($!list,nqp::clone($!indices))
  1153. }
  1154. }.new(self)
  1155. }
  1156. multi method kv(::?CLASS:D:) {
  1157. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  1158. has int $!on-key;
  1159. method result() is raw {
  1160. nqp::if(
  1161. ($!on-key = nqp::not_i($!on-key)),
  1162. nqp::stmts(
  1163. (my $result := self.indices),
  1164. (nqp::bindpos_i($!indices,$!maxdim, # back 1 for next
  1165. nqp::sub_i(nqp::atpos_i($!indices,$!maxdim),1))),
  1166. $result
  1167. ),
  1168. nqp::multidimref_i($!list,nqp::clone($!indices))
  1169. )
  1170. }
  1171. # needs its own push-all since it fiddles with $!indices
  1172. method push-all($target --> IterationEnd) {
  1173. nqp::until(
  1174. nqp::eqaddr((my $pulled := self.pull-one),IterationEnd),
  1175. $target.push($pulled)
  1176. )
  1177. }
  1178. }.new(self))
  1179. }
  1180. multi method pairs(::?CLASS:D:) {
  1181. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  1182. method result() {
  1183. Pair.new(
  1184. self.indices,
  1185. nqp::multidimref_i($!list,nqp::clone($!indices))
  1186. )
  1187. }
  1188. }.new(self))
  1189. }
  1190. multi method antipairs(::?CLASS:D:) {
  1191. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  1192. method result() {
  1193. Pair.new(nqp::atposnd_i($!list,$!indices),self.indices)
  1194. }
  1195. }.new(self))
  1196. }
  1197. } # end of shapedintarray role
  1198. role shaped1intarray does shapedintarray {
  1199. multi method AT-POS(::?CLASS:D: int \one) is raw {
  1200. nqp::atposref_i(self,one)
  1201. }
  1202. multi method AT-POS(::?CLASS:D: Int:D \one) is raw {
  1203. nqp::atposref_i(self,one)
  1204. }
  1205. multi method ASSIGN-POS(::?CLASS:D: int \one, int \value) {
  1206. nqp::bindpos_i(self,one,value)
  1207. }
  1208. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, int \value) {
  1209. nqp::bindpos_i(self,one,value)
  1210. }
  1211. multi method ASSIGN-POS(::?CLASS:D: int \one, Int:D \value) {
  1212. nqp::bindpos_i(self,one,value)
  1213. }
  1214. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \value) {
  1215. nqp::bindpos_i(self,one,value)
  1216. }
  1217. multi method EXISTS-POS(::?CLASS:D: int \one) {
  1218. nqp::p6bool(
  1219. nqp::isge_i(one,0) && nqp::islt_i(one,nqp::elems(self))
  1220. )
  1221. }
  1222. multi method EXISTS-POS(::?CLASS:D: Int:D \one) {
  1223. nqp::p6bool(
  1224. nqp::isge_i(one,0) && nqp::islt_i(one,nqp::elems(self))
  1225. )
  1226. }
  1227. multi method STORE(::?CLASS:D: ::?CLASS:D \from) {
  1228. nqp::if(
  1229. nqp::iseq_i((my int $elems = nqp::elems(self)),nqp::elems(from)),
  1230. nqp::stmts(
  1231. (my int $i = -1),
  1232. nqp::while(
  1233. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1234. nqp::bindpos_i(self,$i,nqp::atpos_i(from,$i))
  1235. ),
  1236. self
  1237. ),
  1238. X::Assignment::ArrayShapeMismatch.new(
  1239. source-shape => from.shape,
  1240. target-shape => self.shape
  1241. ).throw
  1242. )
  1243. }
  1244. multi method STORE(::?CLASS:D: Iterable:D \in) {
  1245. nqp::stmts(
  1246. (my \iter := in.iterator),
  1247. (my int $elems = nqp::elems(self)),
  1248. (my int $i = -1),
  1249. nqp::until(
  1250. nqp::eqaddr((my $pulled := iter.pull-one),IterationEnd)
  1251. || nqp::iseq_i(($i = nqp::add_i($i,1)),$elems),
  1252. nqp::bindpos_i(self,$i,$pulled)
  1253. ),
  1254. nqp::unless(
  1255. nqp::islt_i($i,$elems) || iter.is-lazy,
  1256. nqp::atpos_i(list,$i) # too many values on non-lazy it
  1257. ),
  1258. self
  1259. )
  1260. }
  1261. multi method STORE(::?CLASS:D: Int:D \item) {
  1262. nqp::stmts(
  1263. nqp::bindpos_i(self,0,item),
  1264. self
  1265. )
  1266. }
  1267. method iterator(::?CLASS:D:) {
  1268. class :: does Iterator {
  1269. has Mu $!list;
  1270. has int $!pos;
  1271. method !SET-SELF(Mu \list) {
  1272. nqp::stmts(
  1273. ($!list := list),
  1274. ($!pos = -1),
  1275. self
  1276. )
  1277. }
  1278. method new(Mu \list) { nqp::create(self)!SET-SELF(list) }
  1279. method pull-one() is raw {
  1280. nqp::if(
  1281. nqp::islt_i(
  1282. ($!pos = nqp::add_i($!pos,1)),
  1283. nqp::elems($!list)
  1284. ),
  1285. nqp::atposref_i($!list,$!pos),
  1286. IterationEnd
  1287. )
  1288. }
  1289. method push-all($target --> IterationEnd) {
  1290. nqp::stmts(
  1291. (my int $elems = nqp::elems($!list)),
  1292. (my int $i = -1),
  1293. nqp::while(
  1294. nqp::islt_i(($!pos = nqp::add_i($!pos,1)),$elems),
  1295. $target.push(nqp::atpos_i($!list,$!pos))
  1296. )
  1297. )
  1298. }
  1299. method count-only() { nqp::p6box_i(nqp::elems($!list)) }
  1300. method bool-only() { nqp::p6bool(nqp::elems($!list)) }
  1301. method sink-all(--> IterationEnd) {
  1302. $!pos = nqp::elems($!list)
  1303. }
  1304. }.new(self)
  1305. }
  1306. multi method kv(::?CLASS:D:) {
  1307. my int $i = -1;
  1308. my int $elems = nqp::add_i(nqp::elems(self),nqp::elems(self));
  1309. Seq.new(Rakudo::Iterator.Callable({
  1310. nqp::if(
  1311. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1312. nqp::if(
  1313. nqp::bitand_i($i,1),
  1314. nqp::atposref_i(self,nqp::bitshiftr_i($i,1)),
  1315. nqp::bitshiftr_i($i,1)
  1316. ),
  1317. IterationEnd
  1318. )
  1319. }))
  1320. }
  1321. multi method pairs(::?CLASS:D:) {
  1322. my int $i = -1;
  1323. my int $elems = nqp::elems(self);
  1324. Seq.new(Rakudo::Iterator.Callable({
  1325. nqp::if(
  1326. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1327. Pair.new($i,nqp::atposref_i(self,$i)),
  1328. IterationEnd
  1329. )
  1330. }))
  1331. }
  1332. multi method antipairs(::?CLASS:D:) {
  1333. Seq.new(Rakudo::Iterator.AntiPair(self.iterator))
  1334. }
  1335. method reverse(::?CLASS:D:) is nodal {
  1336. nqp::stmts(
  1337. (my int $elems = nqp::elems(self)),
  1338. (my int $last = nqp::sub_i($elems,1)),
  1339. (my int $i = -1),
  1340. (my $to := nqp::clone(self)),
  1341. nqp::while(
  1342. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1343. nqp::bindpos_i($to,nqp::sub_i($last,$i),
  1344. nqp::atpos_i(self,$i))
  1345. ),
  1346. $to
  1347. )
  1348. }
  1349. method rotate(::?CLASS:D: Int(Cool) $rotate = 1) is nodal {
  1350. nqp::stmts(
  1351. (my int $elems = nqp::elems(self)),
  1352. (my $to := nqp::clone(self)),
  1353. (my int $i = -1),
  1354. (my int $j =
  1355. nqp::mod_i(nqp::sub_i(nqp::sub_i($elems,1),$rotate),$elems)),
  1356. nqp::if(nqp::islt_i($j,0),($j = nqp::add_i($j,$elems))),
  1357. nqp::while(
  1358. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1359. nqp::bindpos_i(
  1360. $to,
  1361. ($j = nqp::mod_i(nqp::add_i($j,1),$elems)),
  1362. nqp::atpos_i(self,$i)
  1363. ),
  1364. ),
  1365. $to
  1366. )
  1367. }
  1368. } # end of shaped1intarray role
  1369. role shaped2intarray does shapedintarray {
  1370. multi method AT-POS(::?CLASS:D: int \one, int \two) is raw {
  1371. nqp::atpos2d_i(self,one,two)
  1372. }
  1373. multi method AT-POS(::?CLASS:D: Int:D \one, Int:D \two) is raw {
  1374. nqp::atpos2d_i(self,one,two)
  1375. }
  1376. multi method ASSIGN-POS(::?CLASS:D: int \one, int \two, Int:D \value) {
  1377. nqp::bindpos2d_i(self,one,two,value)
  1378. }
  1379. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \value) {
  1380. nqp::bindpos2d_i(self,one,two,value)
  1381. }
  1382. multi method EXISTS-POS(::?CLASS:D: int \one, int \two) {
  1383. nqp::p6bool(
  1384. nqp::isge_i(one,0)
  1385. && nqp::isge_i(two,0)
  1386. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1387. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1388. )
  1389. }
  1390. multi method EXISTS-POS(::?CLASS:D: Int:D \one, Int:D \two) {
  1391. nqp::p6bool(
  1392. nqp::isge_i(one,0)
  1393. && nqp::isge_i(two,0)
  1394. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1395. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1396. )
  1397. }
  1398. } # end of shaped2intarray role
  1399. role shaped3intarray does shapedintarray {
  1400. multi method AT-POS(::?CLASS:D: int \one, int \two, int \three) is raw {
  1401. nqp::atpos3d_i(self,one,two,three)
  1402. }
  1403. multi method AT-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three) is raw {
  1404. nqp::atpos3d_i(self,one,two,three)
  1405. }
  1406. multi method ASSIGN-POS(::?CLASS:D: int \one, int \two, int \three, Int:D \value) {
  1407. nqp::bindpos3d_i(self,one,two,three,value)
  1408. }
  1409. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three, Int:D \value) {
  1410. nqp::bindpos3d_i(self,one,two,three,value)
  1411. }
  1412. multi method EXISTS-POS(::?CLASS:D: int \one, int \two, int \three) {
  1413. nqp::p6bool(
  1414. nqp::isge_i(one,0)
  1415. && nqp::isge_i(two,0)
  1416. && nqp::isge_i(three,0)
  1417. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1418. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1419. && nqp::islt_i(three,nqp::atpos_i(nqp::dimensions(self),2))
  1420. )
  1421. }
  1422. multi method EXISTS-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three) {
  1423. nqp::p6bool(
  1424. nqp::isge_i(one,0)
  1425. && nqp::isge_i(two,0)
  1426. && nqp::isge_i(three,0)
  1427. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1428. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1429. && nqp::islt_i(three,nqp::atpos_i(nqp::dimensions(self),2))
  1430. )
  1431. }
  1432. } # end of shaped3intarray role
  1433. #- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE
  1434. #- end of generated part of shapedintarray role -------------------------------
  1435. #- start of generated part of shapednumarray role -----------------------------
  1436. #- Generated on 2017-01-22T22:56:03+01:00 by tools/build/makeNATIVE_SHAPED_ARRAY.pl6
  1437. #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE
  1438. role shapednumarray does shapedarray {
  1439. multi method AT-POS(::?CLASS:D: **@indices) is raw {
  1440. nqp::if(
  1441. nqp::iseq_i(
  1442. (my int $numdims = nqp::numdimensions(self)),
  1443. (my int $numind = @indices.elems), # reifies
  1444. ),
  1445. nqp::stmts(
  1446. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  1447. (my $idxs := nqp::list_i),
  1448. nqp::while( # native index list
  1449. nqp::isge_i(($numdims = nqp::sub_i($numdims,1)),0),
  1450. nqp::push_i($idxs,nqp::shift($indices))
  1451. ),
  1452. nqp::multidimref_n(self,$idxs)
  1453. ),
  1454. nqp::if(
  1455. nqp::isgt_i($numind,$numdims),
  1456. X::TooManyDimensions.new(
  1457. operation => 'access',
  1458. got-dimensions => $numind,
  1459. needed-dimensions => $numdims
  1460. ).throw,
  1461. X::NYI.new(
  1462. feature => "Partially dimensioned views of shaped arrays"
  1463. ).throw
  1464. )
  1465. )
  1466. }
  1467. multi method ASSIGN-POS(::?CLASS:D: **@indices) {
  1468. nqp::stmts(
  1469. (my num $value = @indices.pop),
  1470. nqp::if(
  1471. nqp::iseq_i(
  1472. (my int $numdims = nqp::numdimensions(self)),
  1473. (my int $numind = @indices.elems), # reifies
  1474. ),
  1475. nqp::stmts(
  1476. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  1477. (my $idxs := nqp::list_i),
  1478. nqp::while( # native index list
  1479. nqp::isge_i(($numdims = nqp::sub_i($numdims,1)),0),
  1480. nqp::push_i($idxs,nqp::shift($indices))
  1481. ),
  1482. nqp::bindposnd_n(self, $idxs, $value)
  1483. ),
  1484. nqp::if(
  1485. nqp::isgt_i($numind,$numdims),
  1486. X::TooManyDimensions,
  1487. X::NotEnoughDimensions
  1488. ).new(
  1489. operation => 'assign to',
  1490. got-dimensions => $numind,
  1491. needed-dimensions => $numdims
  1492. ).throw
  1493. )
  1494. )
  1495. }
  1496. sub NATCPY(Mu \to, Mu \from) is raw {
  1497. class :: does Rakudo::Iterator::ShapeLeaf {
  1498. has Mu $!from;
  1499. method INIT(Mu \to, Mu \from) {
  1500. nqp::stmts(
  1501. ($!from := from),
  1502. self.SET-SELF(to)
  1503. )
  1504. }
  1505. method new(Mu \to, Mu \from) {
  1506. nqp::create(self).INIT(to,from)
  1507. }
  1508. method result(--> Nil) {
  1509. nqp::bindposnd_n($!list,$!indices,
  1510. nqp::multidimref_n($!from,$!indices))
  1511. }
  1512. }.new(to,from).sink-all;
  1513. to
  1514. }
  1515. sub OBJCPY(Mu \to, Mu \from) is raw {
  1516. class :: does Rakudo::Iterator::ShapeLeaf {
  1517. has Mu $!from;
  1518. method INIT(Mu \to, Mu \from) {
  1519. nqp::stmts(
  1520. ($!from := nqp::getattr(from,List,'$!reified')),
  1521. self.SET-SELF(to)
  1522. )
  1523. }
  1524. method new(Mu \to, Mu \from) {
  1525. nqp::create(self).INIT(to,from)
  1526. }
  1527. method result(--> Nil) {
  1528. nqp::bindposnd_n($!list,$!indices,
  1529. nqp::atposnd($!from,$!indices))
  1530. }
  1531. }.new(to,from).sink-all;
  1532. to
  1533. }
  1534. sub ITERCPY(Mu \to, Mu \from) is raw {
  1535. class :: does Rakudo::Iterator::ShapeBranch {
  1536. has $!iterators;
  1537. method INIT(\to,\from) {
  1538. nqp::stmts(
  1539. self.SET-SELF(to),
  1540. ($!iterators := nqp::setelems(
  1541. nqp::list(from.iterator),
  1542. nqp::add_i($!maxdim,1)
  1543. )),
  1544. self
  1545. )
  1546. }
  1547. method new(\to,\from) { nqp::create(self).INIT(to,from) }
  1548. method done(--> Nil) {
  1549. nqp::unless( # verify lowest
  1550. nqp::atpos($!iterators,0).is-lazy # finite iterator
  1551. || nqp::eqaddr( # and something there
  1552. nqp::atpos($!iterators,0).pull-one,IterationEnd),
  1553. nqp::atposnd_n($!list,$!indices) # boom!
  1554. )
  1555. }
  1556. method process(--> Nil) {
  1557. nqp::stmts(
  1558. (my int $i = $!level),
  1559. nqp::while(
  1560. nqp::isle_i(($i = nqp::add_i($i,1)),$!maxdim),
  1561. nqp::if(
  1562. nqp::eqaddr((my $item := # exhausted ?
  1563. nqp::atpos($!iterators,nqp::sub_i($i,1)).pull-one),
  1564. IterationEnd
  1565. ),
  1566. nqp::bindpos($!iterators,$i, # add an empty one
  1567. Rakudo::Iterator.Empty),
  1568. nqp::if( # is it an iterator?
  1569. nqp::istype($item,Iterable) && nqp::isconcrete($item),
  1570. nqp::bindpos($!iterators,$i,$item.iterator),
  1571. X::Assignment::ToShaped.new(shape => $!dims).throw
  1572. )
  1573. )
  1574. ),
  1575. (my $iter := nqp::atpos($!iterators,$!maxdim)),
  1576. nqp::until( # loop over highest dim
  1577. nqp::eqaddr((my $pulled := $iter.pull-one),IterationEnd)
  1578. || nqp::isgt_i(nqp::atpos_i($!indices,$!maxdim),$!maxind),
  1579. nqp::stmts(
  1580. nqp::bindposnd_n($!list,$!indices,$pulled),
  1581. nqp::bindpos_i($!indices,$!maxdim, # increment index
  1582. nqp::add_i(nqp::atpos_i($!indices,$!maxdim),1))
  1583. )
  1584. ),
  1585. nqp::unless(
  1586. nqp::eqaddr($pulled,IterationEnd) # if not exhausted
  1587. || nqp::isle_i( # and index too high
  1588. nqp::atpos_i($!indices,$!maxdim),$!maxind)
  1589. || $iter.is-lazy, # and not lazy
  1590. nqp::atposnd_n($!list,$!indices) # boom!
  1591. )
  1592. )
  1593. }
  1594. }.new(to,from).sink-all;
  1595. to
  1596. }
  1597. multi method STORE(::?CLASS:D: ::?CLASS:D \from) {
  1598. nqp::if(
  1599. EQV_DIMENSIONS(self,from),
  1600. NATCPY(self,from),
  1601. X::Assignment::ArrayShapeMismatch.new(
  1602. source-shape => from.shape,
  1603. target-shape => self.shape
  1604. ).throw
  1605. )
  1606. }
  1607. multi method STORE(::?CLASS:D: array:D \from) {
  1608. nqp::if(
  1609. nqp::istype(from.of,Num),
  1610. nqp::if(
  1611. EQV_DIMENSIONS(self,from),
  1612. NATCPY(self,from),
  1613. X::Assignment::ArrayShapeMismatch.new(
  1614. source-shape => from.shape,
  1615. target-shape => self.shape
  1616. ).throw
  1617. ),
  1618. X::TypeCheck::Assignment.new(
  1619. symbol => self.^name ~ '[' ~ self.shape.join(';') ~ ']',
  1620. expected => Num,
  1621. got => from.of
  1622. ).throw
  1623. )
  1624. }
  1625. multi method STORE(::?CLASS:D: Iterable:D \from) {
  1626. nqp::if(
  1627. nqp::can(from,'shape'),
  1628. nqp::if(
  1629. from.shape eqv self.shape,
  1630. OBJCPY(self,from),
  1631. X::Assignment::ArrayShapeMismatch.new(
  1632. source-shape => from.shape,
  1633. target-shape => self.shape
  1634. ).throw
  1635. ),
  1636. ITERCPY(self,from)
  1637. )
  1638. }
  1639. method iterator(::?CLASS:D:) {
  1640. class :: does Rakudo::Iterator::ShapeLeaf {
  1641. method result() is raw {
  1642. nqp::multidimref_n($!list,nqp::clone($!indices))
  1643. }
  1644. }.new(self)
  1645. }
  1646. multi method kv(::?CLASS:D:) {
  1647. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  1648. has int $!on-key;
  1649. method result() is raw {
  1650. nqp::if(
  1651. ($!on-key = nqp::not_i($!on-key)),
  1652. nqp::stmts(
  1653. (my $result := self.indices),
  1654. (nqp::bindpos_i($!indices,$!maxdim, # back 1 for next
  1655. nqp::sub_i(nqp::atpos_i($!indices,$!maxdim),1))),
  1656. $result
  1657. ),
  1658. nqp::multidimref_n($!list,nqp::clone($!indices))
  1659. )
  1660. }
  1661. # needs its own push-all since it fiddles with $!indices
  1662. method push-all($target --> IterationEnd) {
  1663. nqp::until(
  1664. nqp::eqaddr((my $pulled := self.pull-one),IterationEnd),
  1665. $target.push($pulled)
  1666. )
  1667. }
  1668. }.new(self))
  1669. }
  1670. multi method pairs(::?CLASS:D:) {
  1671. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  1672. method result() {
  1673. Pair.new(
  1674. self.indices,
  1675. nqp::multidimref_n($!list,nqp::clone($!indices))
  1676. )
  1677. }
  1678. }.new(self))
  1679. }
  1680. multi method antipairs(::?CLASS:D:) {
  1681. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  1682. method result() {
  1683. Pair.new(nqp::atposnd_n($!list,$!indices),self.indices)
  1684. }
  1685. }.new(self))
  1686. }
  1687. } # end of shapednumarray role
  1688. role shaped1numarray does shapednumarray {
  1689. multi method AT-POS(::?CLASS:D: int \one) is raw {
  1690. nqp::atposref_n(self,one)
  1691. }
  1692. multi method AT-POS(::?CLASS:D: Int:D \one) is raw {
  1693. nqp::atposref_n(self,one)
  1694. }
  1695. multi method ASSIGN-POS(::?CLASS:D: int \one, num \value) {
  1696. nqp::bindpos_n(self,one,value)
  1697. }
  1698. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, num \value) {
  1699. nqp::bindpos_n(self,one,value)
  1700. }
  1701. multi method ASSIGN-POS(::?CLASS:D: int \one, Num:D \value) {
  1702. nqp::bindpos_n(self,one,value)
  1703. }
  1704. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Num:D \value) {
  1705. nqp::bindpos_n(self,one,value)
  1706. }
  1707. multi method EXISTS-POS(::?CLASS:D: int \one) {
  1708. nqp::p6bool(
  1709. nqp::isge_i(one,0) && nqp::islt_i(one,nqp::elems(self))
  1710. )
  1711. }
  1712. multi method EXISTS-POS(::?CLASS:D: Int:D \one) {
  1713. nqp::p6bool(
  1714. nqp::isge_i(one,0) && nqp::islt_i(one,nqp::elems(self))
  1715. )
  1716. }
  1717. multi method STORE(::?CLASS:D: ::?CLASS:D \from) {
  1718. nqp::if(
  1719. nqp::iseq_i((my int $elems = nqp::elems(self)),nqp::elems(from)),
  1720. nqp::stmts(
  1721. (my int $i = -1),
  1722. nqp::while(
  1723. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1724. nqp::bindpos_n(self,$i,nqp::atpos_n(from,$i))
  1725. ),
  1726. self
  1727. ),
  1728. X::Assignment::ArrayShapeMismatch.new(
  1729. source-shape => from.shape,
  1730. target-shape => self.shape
  1731. ).throw
  1732. )
  1733. }
  1734. multi method STORE(::?CLASS:D: Iterable:D \in) {
  1735. nqp::stmts(
  1736. (my \iter := in.iterator),
  1737. (my int $elems = nqp::elems(self)),
  1738. (my int $i = -1),
  1739. nqp::until(
  1740. nqp::eqaddr((my $pulled := iter.pull-one),IterationEnd)
  1741. || nqp::iseq_i(($i = nqp::add_i($i,1)),$elems),
  1742. nqp::bindpos_n(self,$i,$pulled)
  1743. ),
  1744. nqp::unless(
  1745. nqp::islt_i($i,$elems) || iter.is-lazy,
  1746. nqp::atpos_n(list,$i) # too many values on non-lazy it
  1747. ),
  1748. self
  1749. )
  1750. }
  1751. multi method STORE(::?CLASS:D: Num:D \item) {
  1752. nqp::stmts(
  1753. nqp::bindpos_n(self,0,item),
  1754. self
  1755. )
  1756. }
  1757. method iterator(::?CLASS:D:) {
  1758. class :: does Iterator {
  1759. has Mu $!list;
  1760. has int $!pos;
  1761. method !SET-SELF(Mu \list) {
  1762. nqp::stmts(
  1763. ($!list := list),
  1764. ($!pos = -1),
  1765. self
  1766. )
  1767. }
  1768. method new(Mu \list) { nqp::create(self)!SET-SELF(list) }
  1769. method pull-one() is raw {
  1770. nqp::if(
  1771. nqp::islt_i(
  1772. ($!pos = nqp::add_i($!pos,1)),
  1773. nqp::elems($!list)
  1774. ),
  1775. nqp::atposref_n($!list,$!pos),
  1776. IterationEnd
  1777. )
  1778. }
  1779. method push-all($target --> IterationEnd) {
  1780. nqp::stmts(
  1781. (my int $elems = nqp::elems($!list)),
  1782. (my int $i = -1),
  1783. nqp::while(
  1784. nqp::islt_i(($!pos = nqp::add_i($!pos,1)),$elems),
  1785. $target.push(nqp::atpos_n($!list,$!pos))
  1786. )
  1787. )
  1788. }
  1789. method count-only() { nqp::p6box_i(nqp::elems($!list)) }
  1790. method bool-only() { nqp::p6bool(nqp::elems($!list)) }
  1791. method sink-all(--> IterationEnd) {
  1792. $!pos = nqp::elems($!list)
  1793. }
  1794. }.new(self)
  1795. }
  1796. multi method kv(::?CLASS:D:) {
  1797. my int $i = -1;
  1798. my int $elems = nqp::add_i(nqp::elems(self),nqp::elems(self));
  1799. Seq.new(Rakudo::Iterator.Callable({
  1800. nqp::if(
  1801. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1802. nqp::if(
  1803. nqp::bitand_i($i,1),
  1804. nqp::atposref_n(self,nqp::bitshiftr_i($i,1)),
  1805. nqp::bitshiftr_i($i,1)
  1806. ),
  1807. IterationEnd
  1808. )
  1809. }))
  1810. }
  1811. multi method pairs(::?CLASS:D:) {
  1812. my int $i = -1;
  1813. my int $elems = nqp::elems(self);
  1814. Seq.new(Rakudo::Iterator.Callable({
  1815. nqp::if(
  1816. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1817. Pair.new($i,nqp::atposref_n(self,$i)),
  1818. IterationEnd
  1819. )
  1820. }))
  1821. }
  1822. multi method antipairs(::?CLASS:D:) {
  1823. Seq.new(Rakudo::Iterator.AntiPair(self.iterator))
  1824. }
  1825. method reverse(::?CLASS:D:) is nodal {
  1826. nqp::stmts(
  1827. (my int $elems = nqp::elems(self)),
  1828. (my int $last = nqp::sub_i($elems,1)),
  1829. (my int $i = -1),
  1830. (my $to := nqp::clone(self)),
  1831. nqp::while(
  1832. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1833. nqp::bindpos_n($to,nqp::sub_i($last,$i),
  1834. nqp::atpos_n(self,$i))
  1835. ),
  1836. $to
  1837. )
  1838. }
  1839. method rotate(::?CLASS:D: Int(Cool) $rotate = 1) is nodal {
  1840. nqp::stmts(
  1841. (my int $elems = nqp::elems(self)),
  1842. (my $to := nqp::clone(self)),
  1843. (my int $i = -1),
  1844. (my int $j =
  1845. nqp::mod_i(nqp::sub_i(nqp::sub_i($elems,1),$rotate),$elems)),
  1846. nqp::if(nqp::islt_i($j,0),($j = nqp::add_i($j,$elems))),
  1847. nqp::while(
  1848. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  1849. nqp::bindpos_n(
  1850. $to,
  1851. ($j = nqp::mod_i(nqp::add_i($j,1),$elems)),
  1852. nqp::atpos_n(self,$i)
  1853. ),
  1854. ),
  1855. $to
  1856. )
  1857. }
  1858. } # end of shaped1numarray role
  1859. role shaped2numarray does shapednumarray {
  1860. multi method AT-POS(::?CLASS:D: int \one, int \two) is raw {
  1861. nqp::atpos2d_n(self,one,two)
  1862. }
  1863. multi method AT-POS(::?CLASS:D: Int:D \one, Int:D \two) is raw {
  1864. nqp::atpos2d_n(self,one,two)
  1865. }
  1866. multi method ASSIGN-POS(::?CLASS:D: int \one, int \two, Num:D \value) {
  1867. nqp::bindpos2d_n(self,one,two,value)
  1868. }
  1869. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \two, Num:D \value) {
  1870. nqp::bindpos2d_n(self,one,two,value)
  1871. }
  1872. multi method EXISTS-POS(::?CLASS:D: int \one, int \two) {
  1873. nqp::p6bool(
  1874. nqp::isge_i(one,0)
  1875. && nqp::isge_i(two,0)
  1876. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1877. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1878. )
  1879. }
  1880. multi method EXISTS-POS(::?CLASS:D: Int:D \one, Int:D \two) {
  1881. nqp::p6bool(
  1882. nqp::isge_i(one,0)
  1883. && nqp::isge_i(two,0)
  1884. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1885. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1886. )
  1887. }
  1888. } # end of shaped2numarray role
  1889. role shaped3numarray does shapednumarray {
  1890. multi method AT-POS(::?CLASS:D: int \one, int \two, int \three) is raw {
  1891. nqp::atpos3d_n(self,one,two,three)
  1892. }
  1893. multi method AT-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three) is raw {
  1894. nqp::atpos3d_n(self,one,two,three)
  1895. }
  1896. multi method ASSIGN-POS(::?CLASS:D: int \one, int \two, int \three, Num:D \value) {
  1897. nqp::bindpos3d_n(self,one,two,three,value)
  1898. }
  1899. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three, Num:D \value) {
  1900. nqp::bindpos3d_n(self,one,two,three,value)
  1901. }
  1902. multi method EXISTS-POS(::?CLASS:D: int \one, int \two, int \three) {
  1903. nqp::p6bool(
  1904. nqp::isge_i(one,0)
  1905. && nqp::isge_i(two,0)
  1906. && nqp::isge_i(three,0)
  1907. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1908. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1909. && nqp::islt_i(three,nqp::atpos_i(nqp::dimensions(self),2))
  1910. )
  1911. }
  1912. multi method EXISTS-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three) {
  1913. nqp::p6bool(
  1914. nqp::isge_i(one,0)
  1915. && nqp::isge_i(two,0)
  1916. && nqp::isge_i(three,0)
  1917. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  1918. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  1919. && nqp::islt_i(three,nqp::atpos_i(nqp::dimensions(self),2))
  1920. )
  1921. }
  1922. } # end of shaped3numarray role
  1923. #- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE
  1924. #- end of generated part of shapednumarray role -------------------------------
  1925. #- start of generated part of shapedstrarray role -----------------------------
  1926. #- Generated on 2017-01-22T22:56:03+01:00 by tools/build/makeNATIVE_SHAPED_ARRAY.pl6
  1927. #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE
  1928. role shapedstrarray does shapedarray {
  1929. multi method AT-POS(::?CLASS:D: **@indices) is raw {
  1930. nqp::if(
  1931. nqp::iseq_i(
  1932. (my int $numdims = nqp::numdimensions(self)),
  1933. (my int $numind = @indices.elems), # reifies
  1934. ),
  1935. nqp::stmts(
  1936. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  1937. (my $idxs := nqp::list_i),
  1938. nqp::while( # native index list
  1939. nqp::isge_i(($numdims = nqp::sub_i($numdims,1)),0),
  1940. nqp::push_i($idxs,nqp::shift($indices))
  1941. ),
  1942. nqp::multidimref_s(self,$idxs)
  1943. ),
  1944. nqp::if(
  1945. nqp::isgt_i($numind,$numdims),
  1946. X::TooManyDimensions.new(
  1947. operation => 'access',
  1948. got-dimensions => $numind,
  1949. needed-dimensions => $numdims
  1950. ).throw,
  1951. X::NYI.new(
  1952. feature => "Partially dimensioned views of shaped arrays"
  1953. ).throw
  1954. )
  1955. )
  1956. }
  1957. multi method ASSIGN-POS(::?CLASS:D: **@indices) {
  1958. nqp::stmts(
  1959. (my str $value = @indices.pop),
  1960. nqp::if(
  1961. nqp::iseq_i(
  1962. (my int $numdims = nqp::numdimensions(self)),
  1963. (my int $numind = @indices.elems), # reifies
  1964. ),
  1965. nqp::stmts(
  1966. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  1967. (my $idxs := nqp::list_i),
  1968. nqp::while( # native index list
  1969. nqp::isge_i(($numdims = nqp::sub_i($numdims,1)),0),
  1970. nqp::push_i($idxs,nqp::shift($indices))
  1971. ),
  1972. nqp::bindposnd_s(self, $idxs, $value)
  1973. ),
  1974. nqp::if(
  1975. nqp::isgt_i($numind,$numdims),
  1976. X::TooManyDimensions,
  1977. X::NotEnoughDimensions
  1978. ).new(
  1979. operation => 'assign to',
  1980. got-dimensions => $numind,
  1981. needed-dimensions => $numdims
  1982. ).throw
  1983. )
  1984. )
  1985. }
  1986. sub NATCPY(Mu \to, Mu \from) is raw {
  1987. class :: does Rakudo::Iterator::ShapeLeaf {
  1988. has Mu $!from;
  1989. method INIT(Mu \to, Mu \from) {
  1990. nqp::stmts(
  1991. ($!from := from),
  1992. self.SET-SELF(to)
  1993. )
  1994. }
  1995. method new(Mu \to, Mu \from) {
  1996. nqp::create(self).INIT(to,from)
  1997. }
  1998. method result(--> Nil) {
  1999. nqp::bindposnd_s($!list,$!indices,
  2000. nqp::multidimref_s($!from,$!indices))
  2001. }
  2002. }.new(to,from).sink-all;
  2003. to
  2004. }
  2005. sub OBJCPY(Mu \to, Mu \from) is raw {
  2006. class :: does Rakudo::Iterator::ShapeLeaf {
  2007. has Mu $!from;
  2008. method INIT(Mu \to, Mu \from) {
  2009. nqp::stmts(
  2010. ($!from := nqp::getattr(from,List,'$!reified')),
  2011. self.SET-SELF(to)
  2012. )
  2013. }
  2014. method new(Mu \to, Mu \from) {
  2015. nqp::create(self).INIT(to,from)
  2016. }
  2017. method result(--> Nil) {
  2018. nqp::bindposnd_s($!list,$!indices,
  2019. nqp::atposnd($!from,$!indices))
  2020. }
  2021. }.new(to,from).sink-all;
  2022. to
  2023. }
  2024. sub ITERCPY(Mu \to, Mu \from) is raw {
  2025. class :: does Rakudo::Iterator::ShapeBranch {
  2026. has $!iterators;
  2027. method INIT(\to,\from) {
  2028. nqp::stmts(
  2029. self.SET-SELF(to),
  2030. ($!iterators := nqp::setelems(
  2031. nqp::list(from.iterator),
  2032. nqp::add_i($!maxdim,1)
  2033. )),
  2034. self
  2035. )
  2036. }
  2037. method new(\to,\from) { nqp::create(self).INIT(to,from) }
  2038. method done(--> Nil) {
  2039. nqp::unless( # verify lowest
  2040. nqp::atpos($!iterators,0).is-lazy # finite iterator
  2041. || nqp::eqaddr( # and something there
  2042. nqp::atpos($!iterators,0).pull-one,IterationEnd),
  2043. nqp::atposnd_s($!list,$!indices) # boom!
  2044. )
  2045. }
  2046. method process(--> Nil) {
  2047. nqp::stmts(
  2048. (my int $i = $!level),
  2049. nqp::while(
  2050. nqp::isle_i(($i = nqp::add_i($i,1)),$!maxdim),
  2051. nqp::if(
  2052. nqp::eqaddr((my $item := # exhausted ?
  2053. nqp::atpos($!iterators,nqp::sub_i($i,1)).pull-one),
  2054. IterationEnd
  2055. ),
  2056. nqp::bindpos($!iterators,$i, # add an empty one
  2057. Rakudo::Iterator.Empty),
  2058. nqp::if( # is it an iterator?
  2059. nqp::istype($item,Iterable) && nqp::isconcrete($item),
  2060. nqp::bindpos($!iterators,$i,$item.iterator),
  2061. X::Assignment::ToShaped.new(shape => $!dims).throw
  2062. )
  2063. )
  2064. ),
  2065. (my $iter := nqp::atpos($!iterators,$!maxdim)),
  2066. nqp::until( # loop over highest dim
  2067. nqp::eqaddr((my $pulled := $iter.pull-one),IterationEnd)
  2068. || nqp::isgt_i(nqp::atpos_i($!indices,$!maxdim),$!maxind),
  2069. nqp::stmts(
  2070. nqp::bindposnd_s($!list,$!indices,$pulled),
  2071. nqp::bindpos_i($!indices,$!maxdim, # increment index
  2072. nqp::add_i(nqp::atpos_i($!indices,$!maxdim),1))
  2073. )
  2074. ),
  2075. nqp::unless(
  2076. nqp::eqaddr($pulled,IterationEnd) # if not exhausted
  2077. || nqp::isle_i( # and index too high
  2078. nqp::atpos_i($!indices,$!maxdim),$!maxind)
  2079. || $iter.is-lazy, # and not lazy
  2080. nqp::atposnd_s($!list,$!indices) # boom!
  2081. )
  2082. )
  2083. }
  2084. }.new(to,from).sink-all;
  2085. to
  2086. }
  2087. multi method STORE(::?CLASS:D: ::?CLASS:D \from) {
  2088. nqp::if(
  2089. EQV_DIMENSIONS(self,from),
  2090. NATCPY(self,from),
  2091. X::Assignment::ArrayShapeMismatch.new(
  2092. source-shape => from.shape,
  2093. target-shape => self.shape
  2094. ).throw
  2095. )
  2096. }
  2097. multi method STORE(::?CLASS:D: array:D \from) {
  2098. nqp::if(
  2099. nqp::istype(from.of,Str),
  2100. nqp::if(
  2101. EQV_DIMENSIONS(self,from),
  2102. NATCPY(self,from),
  2103. X::Assignment::ArrayShapeMismatch.new(
  2104. source-shape => from.shape,
  2105. target-shape => self.shape
  2106. ).throw
  2107. ),
  2108. X::TypeCheck::Assignment.new(
  2109. symbol => self.^name ~ '[' ~ self.shape.join(';') ~ ']',
  2110. expected => Str,
  2111. got => from.of
  2112. ).throw
  2113. )
  2114. }
  2115. multi method STORE(::?CLASS:D: Iterable:D \from) {
  2116. nqp::if(
  2117. nqp::can(from,'shape'),
  2118. nqp::if(
  2119. from.shape eqv self.shape,
  2120. OBJCPY(self,from),
  2121. X::Assignment::ArrayShapeMismatch.new(
  2122. source-shape => from.shape,
  2123. target-shape => self.shape
  2124. ).throw
  2125. ),
  2126. ITERCPY(self,from)
  2127. )
  2128. }
  2129. method iterator(::?CLASS:D:) {
  2130. class :: does Rakudo::Iterator::ShapeLeaf {
  2131. method result() is raw {
  2132. nqp::multidimref_s($!list,nqp::clone($!indices))
  2133. }
  2134. }.new(self)
  2135. }
  2136. multi method kv(::?CLASS:D:) {
  2137. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  2138. has int $!on-key;
  2139. method result() is raw {
  2140. nqp::if(
  2141. ($!on-key = nqp::not_i($!on-key)),
  2142. nqp::stmts(
  2143. (my $result := self.indices),
  2144. (nqp::bindpos_i($!indices,$!maxdim, # back 1 for next
  2145. nqp::sub_i(nqp::atpos_i($!indices,$!maxdim),1))),
  2146. $result
  2147. ),
  2148. nqp::multidimref_s($!list,nqp::clone($!indices))
  2149. )
  2150. }
  2151. # needs its own push-all since it fiddles with $!indices
  2152. method push-all($target --> IterationEnd) {
  2153. nqp::until(
  2154. nqp::eqaddr((my $pulled := self.pull-one),IterationEnd),
  2155. $target.push($pulled)
  2156. )
  2157. }
  2158. }.new(self))
  2159. }
  2160. multi method pairs(::?CLASS:D:) {
  2161. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  2162. method result() {
  2163. Pair.new(
  2164. self.indices,
  2165. nqp::multidimref_s($!list,nqp::clone($!indices))
  2166. )
  2167. }
  2168. }.new(self))
  2169. }
  2170. multi method antipairs(::?CLASS:D:) {
  2171. Seq.new(class :: does Rakudo::Iterator::ShapeLeaf {
  2172. method result() {
  2173. Pair.new(nqp::atposnd_s($!list,$!indices),self.indices)
  2174. }
  2175. }.new(self))
  2176. }
  2177. } # end of shapedstrarray role
  2178. role shaped1strarray does shapedstrarray {
  2179. multi method AT-POS(::?CLASS:D: int \one) is raw {
  2180. nqp::atposref_s(self,one)
  2181. }
  2182. multi method AT-POS(::?CLASS:D: Int:D \one) is raw {
  2183. nqp::atposref_s(self,one)
  2184. }
  2185. multi method ASSIGN-POS(::?CLASS:D: int \one, str \value) {
  2186. nqp::bindpos_s(self,one,value)
  2187. }
  2188. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, str \value) {
  2189. nqp::bindpos_s(self,one,value)
  2190. }
  2191. multi method ASSIGN-POS(::?CLASS:D: int \one, Str:D \value) {
  2192. nqp::bindpos_s(self,one,value)
  2193. }
  2194. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Str:D \value) {
  2195. nqp::bindpos_s(self,one,value)
  2196. }
  2197. multi method EXISTS-POS(::?CLASS:D: int \one) {
  2198. nqp::p6bool(
  2199. nqp::isge_i(one,0) && nqp::islt_i(one,nqp::elems(self))
  2200. )
  2201. }
  2202. multi method EXISTS-POS(::?CLASS:D: Int:D \one) {
  2203. nqp::p6bool(
  2204. nqp::isge_i(one,0) && nqp::islt_i(one,nqp::elems(self))
  2205. )
  2206. }
  2207. multi method STORE(::?CLASS:D: ::?CLASS:D \from) {
  2208. nqp::if(
  2209. nqp::iseq_i((my int $elems = nqp::elems(self)),nqp::elems(from)),
  2210. nqp::stmts(
  2211. (my int $i = -1),
  2212. nqp::while(
  2213. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  2214. nqp::bindpos_s(self,$i,nqp::atpos_s(from,$i))
  2215. ),
  2216. self
  2217. ),
  2218. X::Assignment::ArrayShapeMismatch.new(
  2219. source-shape => from.shape,
  2220. target-shape => self.shape
  2221. ).throw
  2222. )
  2223. }
  2224. multi method STORE(::?CLASS:D: Iterable:D \in) {
  2225. nqp::stmts(
  2226. (my \iter := in.iterator),
  2227. (my int $elems = nqp::elems(self)),
  2228. (my int $i = -1),
  2229. nqp::until(
  2230. nqp::eqaddr((my $pulled := iter.pull-one),IterationEnd)
  2231. || nqp::iseq_i(($i = nqp::add_i($i,1)),$elems),
  2232. nqp::bindpos_s(self,$i,$pulled)
  2233. ),
  2234. nqp::unless(
  2235. nqp::islt_i($i,$elems) || iter.is-lazy,
  2236. nqp::atpos_s(list,$i) # too many values on non-lazy it
  2237. ),
  2238. self
  2239. )
  2240. }
  2241. multi method STORE(::?CLASS:D: Str:D \item) {
  2242. nqp::stmts(
  2243. nqp::bindpos_s(self,0,item),
  2244. self
  2245. )
  2246. }
  2247. method iterator(::?CLASS:D:) {
  2248. class :: does Iterator {
  2249. has Mu $!list;
  2250. has int $!pos;
  2251. method !SET-SELF(Mu \list) {
  2252. nqp::stmts(
  2253. ($!list := list),
  2254. ($!pos = -1),
  2255. self
  2256. )
  2257. }
  2258. method new(Mu \list) { nqp::create(self)!SET-SELF(list) }
  2259. method pull-one() is raw {
  2260. nqp::if(
  2261. nqp::islt_i(
  2262. ($!pos = nqp::add_i($!pos,1)),
  2263. nqp::elems($!list)
  2264. ),
  2265. nqp::atposref_s($!list,$!pos),
  2266. IterationEnd
  2267. )
  2268. }
  2269. method push-all($target --> IterationEnd) {
  2270. nqp::stmts(
  2271. (my int $elems = nqp::elems($!list)),
  2272. (my int $i = -1),
  2273. nqp::while(
  2274. nqp::islt_i(($!pos = nqp::add_i($!pos,1)),$elems),
  2275. $target.push(nqp::atpos_s($!list,$!pos))
  2276. )
  2277. )
  2278. }
  2279. method count-only() { nqp::p6box_i(nqp::elems($!list)) }
  2280. method bool-only() { nqp::p6bool(nqp::elems($!list)) }
  2281. method sink-all(--> IterationEnd) {
  2282. $!pos = nqp::elems($!list)
  2283. }
  2284. }.new(self)
  2285. }
  2286. multi method kv(::?CLASS:D:) {
  2287. my int $i = -1;
  2288. my int $elems = nqp::add_i(nqp::elems(self),nqp::elems(self));
  2289. Seq.new(Rakudo::Iterator.Callable({
  2290. nqp::if(
  2291. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  2292. nqp::if(
  2293. nqp::bitand_i($i,1),
  2294. nqp::atposref_s(self,nqp::bitshiftr_i($i,1)),
  2295. nqp::bitshiftr_i($i,1)
  2296. ),
  2297. IterationEnd
  2298. )
  2299. }))
  2300. }
  2301. multi method pairs(::?CLASS:D:) {
  2302. my int $i = -1;
  2303. my int $elems = nqp::elems(self);
  2304. Seq.new(Rakudo::Iterator.Callable({
  2305. nqp::if(
  2306. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  2307. Pair.new($i,nqp::atposref_s(self,$i)),
  2308. IterationEnd
  2309. )
  2310. }))
  2311. }
  2312. multi method antipairs(::?CLASS:D:) {
  2313. Seq.new(Rakudo::Iterator.AntiPair(self.iterator))
  2314. }
  2315. method reverse(::?CLASS:D:) is nodal {
  2316. nqp::stmts(
  2317. (my int $elems = nqp::elems(self)),
  2318. (my int $last = nqp::sub_i($elems,1)),
  2319. (my int $i = -1),
  2320. (my $to := nqp::clone(self)),
  2321. nqp::while(
  2322. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  2323. nqp::bindpos_s($to,nqp::sub_i($last,$i),
  2324. nqp::atpos_s(self,$i))
  2325. ),
  2326. $to
  2327. )
  2328. }
  2329. method rotate(::?CLASS:D: Int(Cool) $rotate = 1) is nodal {
  2330. nqp::stmts(
  2331. (my int $elems = nqp::elems(self)),
  2332. (my $to := nqp::clone(self)),
  2333. (my int $i = -1),
  2334. (my int $j =
  2335. nqp::mod_i(nqp::sub_i(nqp::sub_i($elems,1),$rotate),$elems)),
  2336. nqp::if(nqp::islt_i($j,0),($j = nqp::add_i($j,$elems))),
  2337. nqp::while(
  2338. nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
  2339. nqp::bindpos_s(
  2340. $to,
  2341. ($j = nqp::mod_i(nqp::add_i($j,1),$elems)),
  2342. nqp::atpos_s(self,$i)
  2343. ),
  2344. ),
  2345. $to
  2346. )
  2347. }
  2348. } # end of shaped1strarray role
  2349. role shaped2strarray does shapedstrarray {
  2350. multi method AT-POS(::?CLASS:D: int \one, int \two) is raw {
  2351. nqp::atpos2d_s(self,one,two)
  2352. }
  2353. multi method AT-POS(::?CLASS:D: Int:D \one, Int:D \two) is raw {
  2354. nqp::atpos2d_s(self,one,two)
  2355. }
  2356. multi method ASSIGN-POS(::?CLASS:D: int \one, int \two, Str:D \value) {
  2357. nqp::bindpos2d_s(self,one,two,value)
  2358. }
  2359. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \two, Str:D \value) {
  2360. nqp::bindpos2d_s(self,one,two,value)
  2361. }
  2362. multi method EXISTS-POS(::?CLASS:D: int \one, int \two) {
  2363. nqp::p6bool(
  2364. nqp::isge_i(one,0)
  2365. && nqp::isge_i(two,0)
  2366. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  2367. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  2368. )
  2369. }
  2370. multi method EXISTS-POS(::?CLASS:D: Int:D \one, Int:D \two) {
  2371. nqp::p6bool(
  2372. nqp::isge_i(one,0)
  2373. && nqp::isge_i(two,0)
  2374. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  2375. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  2376. )
  2377. }
  2378. } # end of shaped2strarray role
  2379. role shaped3strarray does shapedstrarray {
  2380. multi method AT-POS(::?CLASS:D: int \one, int \two, int \three) is raw {
  2381. nqp::atpos3d_s(self,one,two,three)
  2382. }
  2383. multi method AT-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three) is raw {
  2384. nqp::atpos3d_s(self,one,two,three)
  2385. }
  2386. multi method ASSIGN-POS(::?CLASS:D: int \one, int \two, int \three, Str:D \value) {
  2387. nqp::bindpos3d_s(self,one,two,three,value)
  2388. }
  2389. multi method ASSIGN-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three, Str:D \value) {
  2390. nqp::bindpos3d_s(self,one,two,three,value)
  2391. }
  2392. multi method EXISTS-POS(::?CLASS:D: int \one, int \two, int \three) {
  2393. nqp::p6bool(
  2394. nqp::isge_i(one,0)
  2395. && nqp::isge_i(two,0)
  2396. && nqp::isge_i(three,0)
  2397. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  2398. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  2399. && nqp::islt_i(three,nqp::atpos_i(nqp::dimensions(self),2))
  2400. )
  2401. }
  2402. multi method EXISTS-POS(::?CLASS:D: Int:D \one, Int:D \two, Int:D \three) {
  2403. nqp::p6bool(
  2404. nqp::isge_i(one,0)
  2405. && nqp::isge_i(two,0)
  2406. && nqp::isge_i(three,0)
  2407. && nqp::islt_i(one,nqp::atpos_i(nqp::dimensions(self),0))
  2408. && nqp::islt_i(two,nqp::atpos_i(nqp::dimensions(self),1))
  2409. && nqp::islt_i(three,nqp::atpos_i(nqp::dimensions(self),2))
  2410. )
  2411. }
  2412. } # end of shaped3strarray role
  2413. #- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE
  2414. #- end of generated part of shapedstrarray role -------------------------------
  2415. method ^parameterize(Mu:U \arr, Mu:U \t) {
  2416. my $t := nqp::decont(t);
  2417. my int $kind = nqp::objprimspec($t);
  2418. my $what;
  2419. if $kind == 1 {
  2420. $what := arr.^mixin(intarray[$t]);
  2421. }
  2422. elsif $kind == 2 {
  2423. $what := arr.^mixin(numarray[$t]);
  2424. }
  2425. elsif $kind == 3 {
  2426. $what := arr.^mixin(strarray[$t]);
  2427. }
  2428. else {
  2429. die "Can only parameterize array with a native type, not {t.^name}";
  2430. }
  2431. $what.^set_name("{arr.^name}[{t.^name}]");
  2432. $what;
  2433. }
  2434. # poor man's 3x4 matrix
  2435. constant typedim2role := nqp::list(nqp::null,
  2436. nqp::list(shapedintarray,shaped1intarray,shaped2intarray,shaped3intarray),
  2437. nqp::list(shapednumarray,shaped1numarray,shaped2numarray,shaped3numarray),
  2438. nqp::list(shapedstrarray,shaped1strarray,shaped2strarray,shaped3strarray)
  2439. );
  2440. method !shaped(\shape) {
  2441. nqp::if(
  2442. (my int $dims = shape.elems), # reifies
  2443. nqp::stmts(
  2444. # Calculate new meta-object (probably hitting caches in most cases).
  2445. (my \shaped-type = self.WHAT.^mixin(
  2446. nqp::atpos(
  2447. nqp::atpos(typedim2role,nqp::objprimspec(my \T = self.of)),
  2448. nqp::isle_i($dims,3) && $dims
  2449. )
  2450. )),
  2451. nqp::if( # set name if needed
  2452. nqp::isne_s(shaped-type.^name,self.WHAT.^name),
  2453. shaped-type.^set_name(self.WHAT.^name)
  2454. ),
  2455. # Allocate array storage for this shape, based on calculated type.
  2456. Rakudo::Internals.SHAPED-ARRAY-STORAGE(shape,shaped-type.HOW,T)
  2457. ),
  2458. X::NotEnoughDimensions.new(
  2459. operation => 'create',
  2460. got-dimensions => $dims,
  2461. needed-dimensions => '',
  2462. ).throw
  2463. )
  2464. }
  2465. method BIND-POS(|) {
  2466. die "Cannot bind to a natively typed array";
  2467. }
  2468. method DELETE-POS(|) {
  2469. die "Cannot delete from a natively typed array";
  2470. }
  2471. proto method ASSIGN-POS(|) { * } # Hide candidates from Any
  2472. multi method ASSIGN-POS(Any:U \SELF: \pos, Mu \assignee) { # auto-viv
  2473. SELF.AT-POS(pos) = assignee;
  2474. }
  2475. multi method ASSIGN-POS(Any:D: Any:U \pos, Mu \assignee) { # undefined idx
  2476. die "Cannot use '{pos.^name}' as an index";
  2477. }
  2478. multi method EXISTS-POS(array:D: int $idx) {
  2479. $idx >= 0 && $idx < nqp::elems(self)
  2480. }
  2481. multi method EXISTS-POS(array:D: Int $idx) {
  2482. $idx >= 0 && $idx < nqp::elems(self)
  2483. }
  2484. multi method Bool(array:D:) { nqp::p6bool(nqp::elems(self)) }
  2485. multi method Numeric(array:D:) { nqp::elems(self) }
  2486. multi method Str(array:D:) { self.join(' ') }
  2487. multi method elems(array:D:) { nqp::elems(self) }
  2488. method shape() { (*,) }
  2489. proto method Int(|) { * }
  2490. multi method Int(array:D:) { nqp::elems(self) }
  2491. multi method end(array:D:) { nqp::elems(self) - 1 }
  2492. method eager() { self }
  2493. method flat() { Seq.new(self.iterator) }
  2494. method list() { List.from-iterator(self.iterator) }
  2495. method sink(--> Nil) { }
  2496. multi method gist(array:D:) {
  2497. self.map(-> $elem {
  2498. given ++$ {
  2499. when 101 { '...' }
  2500. when 102 { last }
  2501. default { $elem.gist }
  2502. }
  2503. } ).join: ' ';
  2504. }
  2505. multi method perl(array:D:) {
  2506. 'array[' ~ self.of.perl ~ '].new(' ~
  2507. self.map(*.perl).join(', ') ~ ')'
  2508. }
  2509. method FLATTENABLE_LIST() { self }
  2510. method FLATTENABLE_HASH() { nqp::hash() }
  2511. method iterator() {
  2512. nqp::die('iterator must be provided by native array parameterization role')
  2513. }
  2514. }