PBeFS
Parallel Best-First Search
Loading...
Searching...
No Matches
SlidingTile.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*/
2/*--------------------------- File SlidingTile.h ---------------------------*/
3/*--------------------------------------------------------------------------*/
18/*--------------------------------------------------------------------------*/
19/*------------------------------ DEFINITIONS -------------------------------*/
20/*--------------------------------------------------------------------------*/
21
22#ifndef __PBeFS_SlidingTile
23 #define __PBeFS_SlidingTile
24 /* self-identification: #endif at the end of the file */
25
26/*--------------------------------------------------------------------------*/
27/*-------------------------------- INCLUDES --------------------------------*/
28/*--------------------------------------------------------------------------*/
29
30#include <array>
31
32#include <bit>
33
34#include <cstddef>
35
36#include <cstdint>
37
38#include <cstdlib>
39
40#include <ostream>
41
42#include <sstream>
43
44#include <stdexcept>
45
46#include <string>
47
48#include <type_traits>
49
50#include "PBeFS/astar/Domain.h"
51
52/*--------------------------------------------------------------------------*/
53/*------------------------------- NAMESPACE --------------------------------*/
54/*--------------------------------------------------------------------------*/
55
57namespace PBeFS_di_unipi_it
58{
59
60/*--------------------------------------------------------------------------*/
61/*----------------------------- CLASS Word128 ------------------------------*/
62/*--------------------------------------------------------------------------*/
64
70
71struct Word128 {
72
73 std::uint64_t lo = 0;
74 std::uint64_t hi = 0;
75
76 constexpr Word128( void ) noexcept = default;
77
79
80 constexpr Word128( std::uint64_t l ) noexcept : lo( l ) {}
81
83
84 constexpr Word128( std::uint64_t l , std::uint64_t h ) noexcept
85 : lo( l ) , hi( h ) {}
86
88
89 explicit constexpr operator std::uint64_t( void ) const noexcept {
90 return( lo );
91 }
92
93 friend constexpr bool operator==( const Word128 & a , const Word128 & b )
94 noexcept = default;
95
96 friend constexpr Word128 operator&( Word128 a , Word128 b ) noexcept {
97 return( Word128( a.lo & b.lo , a.hi & b.hi ) );
98 }
99
100 friend constexpr Word128 operator|( Word128 a , Word128 b ) noexcept {
101 return( Word128( a.lo | b.lo , a.hi | b.hi ) );
102 }
103
104 friend constexpr Word128 operator^( Word128 a , Word128 b ) noexcept {
105 return( Word128( a.lo ^ b.lo , a.hi ^ b.hi ) );
106 }
107
108 friend constexpr Word128 operator~( Word128 a ) noexcept {
109 return( Word128( ~a.lo , ~a.hi ) );
110 }
111
113
114 friend constexpr Word128 operator<<( Word128 a , int n ) noexcept {
115 if( n == 0 )
116 return( a );
117 if( n >= 64 )
118 return( Word128( 0 , a.lo << ( n - 64 ) ) );
119 return( Word128( a.lo << n , ( a.hi << n ) | ( a.lo >> ( 64 - n ) ) ) );
120 }
121
123
124 friend constexpr Word128 operator>>( Word128 a , int n ) noexcept {
125 if( n == 0 )
126 return( a );
127 if( n >= 64 )
128 return( Word128( a.hi >> ( n - 64 ) , 0 ) );
129 return( Word128( ( a.lo >> n ) | ( a.hi << ( 64 - n ) ) , a.hi >> n ) );
130 }
131
132 Word128 & operator|=( Word128 b ) noexcept { return( *this = *this | b ); }
133
135
136 [[nodiscard]] friend constexpr int countr_zero( Word128 a ) noexcept {
137 return( a.lo ? std::countr_zero( a.lo ) : 64 + std::countr_zero( a.hi ) );
138 }
139
140 }; // end( struct( Word128 ) )
141
142/*--------------------------------------------------------------------------*/
143/*--------------------------- CLASS SlidingTile ----------------------------*/
144/*--------------------------------------------------------------------------*/
146
168
169template< int W , int H >
171
172/*------------------------ PUBLIC PART OF THE CLASS ------------------------*/
173
174 public:
175
176/*------------------------------ PUBLIC TYPES ------------------------------*/
177
178 static constexpr int width = W;
179 static constexpr int height = H;
180 static constexpr int cells = W * H;
181
182 static_assert( ( W >= 2 ) && ( H >= 2 ) && ( cells <= 25 ) ,
183 "SlidingTile: the packed state holds at most 25 cells" );
184
185 static constexpr int bits = cells <= 16 ? 4 : 5;
186
187 using state_type = std::conditional_t< cells <= 16 , std::uint64_t ,
188 Word128 >;
189 using cost_type = int;
190 using board_type = std::array< std::uint8_t , cells >;
191
192/*------------------------------ CONSTRUCTOR -------------------------------*/
193
195
196 [[nodiscard]] static board_type korf_goal( void ) {
197 board_type b{};
198 for( int i = 0 ; i < cells ; ++i )
199 b[ i ] = static_cast< std::uint8_t >( i );
200 return( b );
201 }
202
203/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
205
208
209 explicit SlidingTile( const board_type & start ,
210 const board_type & goal = korf_goal() )
211 : f_start( pack( check( start ) ) ) , f_goal( pack( check( goal ) ) ) {
212 if( parity( start ) != parity( goal ) )
213 throw( std::invalid_argument( "SlidingTile::SlidingTile: the goal is "
214 "not reachable from the start" ) );
215 for( int c = 0 ; c < cells ; ++c )
216 v_goal_cell[ goal[ c ] ] = c;
217 for( int t = 1 ; t < cells ; ++t )
218 for( int c = 0 ; c < cells ; ++c )
219 v_md[ t ][ c ] = distance( c , v_goal_cell[ t ] );
220 for( int b = 0 ; b < cells ; ++b ) {
221 const int r = b / W , k = b % W;
222 Moves & o = v_moves[ b ];
223 if( r > 0 )
224 o.cell[ o.n++ ] = b - W;
225 if( k > 0 )
226 o.cell[ o.n++ ] = b - 1;
227 if( k < W - 1 )
228 o.cell[ o.n++ ] = b + 1;
229 if( r < H - 1 )
230 o.cell[ o.n++ ] = b + W;
231 }
232 }
233
234/*------------------------- METHODS OF THE DOMAIN --------------------------*/
236
237 [[nodiscard]] state_type initial_state( void ) const noexcept {
238 return( f_start );
239 }
240
241/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
243
244 [[nodiscard]] bool is_goal( state_type s ) const noexcept {
245 return( s == f_goal );
246 }
247
248/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
250
251 [[nodiscard]] std::uint64_t hash( state_type s ) const noexcept {
252 if constexpr( cells <= 16 )
253 return( ADS::splitmix64( s ) );
254 else
255 return( ADS::splitmix64( s.lo ^ ADS::splitmix64( s.hi ) ) );
256 }
257
258/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
260
261 [[nodiscard]] cost_type heuristic( state_type s ) const noexcept {
262 int h = 0;
263 for( int c = 0 ; c < cells ; ++c )
264 h += v_md[ tile( s , c ) ][ c ];
265 return( h );
266 }
267
268/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
270
272
273 template< class F >
274 void for_each_successor( state_type s , cost_type h , F && f ) const {
275 const int b = blank( s );
276 const Moves & o = v_moves[ b ];
277 for( int i = 0 ; i < o.n ; ++i ) {
278 const int c = o.cell[ i ];
279 const int t = tile( s , c );
280 const state_type child = ( s & ~( state_type( c_tile ) << ( bits * c ) ) )
281 | ( state_type( t ) << ( bits * b ) );
282 f( child , 1 , h + v_md[ t ][ b ] - v_md[ t ][ c ] );
283 }
284 }
285
286/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
290
291 template< class F >
292 void for_each_successor( state_type s , cost_type h , std::uint8_t op ,
293 F && f ) const {
294 const int b = blank( s );
295 const Moves & o = v_moves[ b ];
296 for( int i = 0 ; i < o.n ; ++i ) {
297 const int c = o.cell[ i ];
298 if( c == op )
299 continue;
300 const int t = tile( s , c );
301 const state_type child = ( s & ~( state_type( c_tile ) << ( bits * c ) ) )
302 | ( state_type( t ) << ( bits * b ) );
303 f( child , 1 , h + v_md[ t ][ b ] - v_md[ t ][ c ] , std::uint8_t( b ) );
304 }
305 }
306
307/*---------------------- FEATURES FOR ZOBRIST HASHING ----------------------*/
309
310 [[nodiscard]] static constexpr std::size_t num_features( void ) noexcept {
311 return( std::size_t( cells ) * cells );
312 }
313
314/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
316
317 template< class F >
318 void for_each_feature( state_type s , F && f ) const {
319 for( int c = 0 ; c < cells ; ++c )
320 if( const int t = tile( s , c ) )
321 f( std::size_t( t * cells + c ) );
322 }
323
324/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
328
330
331 template< class F >
332 void for_each_feature_change( state_type s , state_type t , F && f ) const {
333 const state_type d = s ^ t;
334 if( d == state_type( 0 ) )
335 return;
336 using std::countr_zero;
337 const int i = countr_zero( d ) / bits;
338 const int k = tile( d , i );
339 const int j =
340 countr_zero( d & ~( state_type( c_tile ) << ( bits * i ) ) ) / bits;
341 f( std::size_t( k * cells + i ) );
342 f( std::size_t( k * cells + j ) );
343 }
344
345/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
347
348 [[nodiscard]] static constexpr std::size_t num_abstract_features( void )
349 noexcept {
350 return( std::size_t( cells ) * 2 );
351 }
352
353/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
355
356 [[nodiscard]] static constexpr std::size_t abstract_feature( std::size_t i )
357 noexcept {
358 const std::size_t t = i / cells , c = i % cells;
359 return( t * 2 + ( c / W >= H / 2 ? 1 : 0 ) );
360 }
361
362/*--------------------------- STATE ABSTRACTIONS ---------------------------*/
364
365 [[nodiscard]] std::uint64_t abstract_state( state_type s ) const noexcept {
366 int p[ 4 ] = { 0 , 0 , 0 , 0 };
367 for( int c = 0 ; c < cells ; ++c )
368 if( const int t = tile( s , c ) ; ( t >= 1 ) && ( t <= 3 ) )
369 p[ t ] = c;
370 return( ( std::uint64_t( p[ 1 ] ) * cells + p[ 2 ] ) * cells + p[ 3 ] );
371 }
372
373/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
375
376 [[nodiscard]] static constexpr std::size_t num_nblocks( void ) noexcept {
377 return( std::size_t( cells ) * cells * cells );
378 }
379
380/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
382
383 [[nodiscard]] std::size_t nblock( state_type s ) const noexcept {
384 int p[ 3 ] = { 0 , 0 , 0 };
385 for( int c = 0 ; c < cells ; ++c )
386 if( const int t = tile( s , c ) ; t <= 2 )
387 p[ t ] = c;
388 return( nblock_id( p[ 0 ] , p[ 1 ] , p[ 2 ] ) );
389 }
390
391/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
393
394 template< class F >
395 void for_each_nblock_successor( std::size_t b , F && f ) const {
396 const int p2 = int( b % cells );
397 const int p1 = int( b / cells % cells );
398 const int p0 = int( b / cells / cells );
399 if( ( p0 == p1 ) || ( p0 == p2 ) || ( p1 == p2 ) )
400 return; // not an abstract state
401 const Moves & o = v_moves[ p0 ];
402 for( int i = 0 ; i < o.n ; ++i ) {
403 const int c = o.cell[ i ];
404 if( c == p1 )
405 f( nblock_id( c , p0 , p2 ) );
406 else
407 if( c == p2 )
408 f( nblock_id( c , p1 , p0 ) );
409 else
410 f( nblock_id( c , p1 , p2 ) );
411 }
412 }
413
414/*---------------------- OTHER HEURISTICS AND HASHES -----------------------*/
416
418 const noexcept {
419 int ps[ cells ] , pt[ cells ];
420 for( int c = 0 ; c < cells ; ++c ) {
421 ps[ tile( s , c ) ] = c;
422 pt[ tile( t , c ) ] = c;
423 }
424 int h = 0;
425 for( int k = 1 ; k < cells ; ++k )
426 h += distance( ps[ k ] , pt[ k ] );
427 return( h );
428 }
429
430/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
432
436
437 [[nodiscard]] std::uint64_t perfect_hash( state_type s ) const noexcept
438 requires( cells <= 20 ) {
439 int pos[ cells ];
440 for( int c = 0 ; c < cells ; ++c )
441 pos[ tile( s , c ) ] = c;
442 std::uint64_t rank = 0;
443 std::uint32_t used = 0;
444 for( int k = 0 ; k < cells ; ++k ) {
445 const std::uint32_t below = used & ( ( 1u << pos[ k ] ) - 1u );
446 rank = rank * std::uint64_t( cells - k ) +
447 std::uint64_t( pos[ k ] - std::popcount( below ) );
448 used |= 1u << pos[ k ];
449 }
450 return( rank );
451 }
452
453/*----------------------------- BOARD HELPERS ------------------------------*/
455
456 [[nodiscard]] static int tile( state_type s , int c ) noexcept {
457 return( int( std::uint64_t( s >> ( bits * c ) ) & c_tile ) );
458 }
459
460/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
462
464
465 [[nodiscard]] static int blank( state_type s ) noexcept {
466 state_type t = s;
467 for( int k = 1 ; k < bits ; ++k )
468 t |= s >> k;
469 t = ~t & c_low_bits;
470 using std::countr_zero;
471 return( countr_zero( t ) / bits );
472 }
473
474/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
476
477 [[nodiscard]] static state_type pack( const board_type & b ) noexcept {
478 state_type s = 0;
479 for( int c = 0 ; c < cells ; ++c )
480 s |= state_type( b[ c ] ) << ( bits * c );
481 return( s );
482 }
483
484/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
486
487 [[nodiscard]] static board_type unpack( state_type s ) noexcept {
488 board_type b{};
489 for( int c = 0 ; c < cells ; ++c )
490 b[ c ] = static_cast< std::uint8_t >( tile( s , c ) );
491 return( b );
492 }
493
494/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
496
497 [[nodiscard]] static board_type parse( const std::string & text ) {
498 std::istringstream in( text );
499 board_type b{};
500 for( int c = 0 ; c < cells ; ++c ) {
501 int t = -1;
502 if( ! ( in >> t ) || ( t < 0 ) || ( t >= cells ) )
503 throw( std::invalid_argument( "SlidingTile::parse: bad board" ) );
504 b[ c ] = static_cast< std::uint8_t >( t );
505 }
506 return( check( b ) );
507 }
508
509/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
511
512 static void print( std::ostream & os , state_type s ) {
513 for( int r = 0 ; r < H ; ++r ) {
514 for( int k = 0 ; k < W ; ++k ) {
515 const int t = tile( s , r * W + k );
516 if( t == 0 )
517 os << " ";
518 else
519 os << ( t < 10 ? " " : " " ) << t;
520 }
521 os << '\n';
522 }
523 }
524
525/*----------------------- PRIVATE PART OF THE CLASS ------------------------*/
526
527 private:
528
530 struct Moves {
531 int n = 0;
532 int cell[ 4 ] = { 0 , 0 , 0 , 0 };
533 };
534
536 static constexpr std::uint64_t c_tile = ( std::uint64_t( 1 ) << bits ) - 1;
537
539 static constexpr state_type c_low_bits = [] {
540 state_type m = 0;
541 for( int c = 0 ; c < cells ; ++c )
542 m = m | ( state_type( 1 ) << ( bits * c ) );
543 return( m );
544 }();
545
546/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
547 // the Manhattan distance between two cells
548
549 static int distance( int a , int b ) noexcept {
550 return( std::abs( a / W - b / W ) + std::abs( a % W - b % W ) );
551 }
552
553/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
554 // the index of the nblock with the blank in p0 and tiles 1 , 2 in p1 , p2
555
556 static std::size_t nblock_id( int p0 , int p1 , int p2 ) noexcept {
557 return( ( std::size_t( p0 ) * cells + p1 ) * cells + p2 );
558 }
559
560/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
561 // throws unless b is a permutation of 0 , ... , cells - 1
562
563 static const board_type & check( const board_type & b ) {
564 std::uint32_t seen = 0;
565 for( std::uint8_t t : b ) {
566 if( ( t >= cells ) || ( ( seen >> t ) & 1u ) )
567 throw( std::invalid_argument( "SlidingTile::check: not a permutation" )
568 );
569 seen |= 1u << t;
570 }
571 return( b );
572 }
573
574/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
575 // the invariant of solvability: the parity of the permutation of the tiles
576 // plus, on boards of even width, the row of the blank
577
578 static int parity( const board_type & b ) noexcept {
579 int inv = 0 , blank_row = 0;
580 for( int i = 0 ; i < cells ; ++i ) {
581 if( b[ i ] == 0 ) {
582 blank_row = i / W;
583 continue;
584 }
585 for( int j = i + 1 ; j < cells ; ++j )
586 if( b[ j ] && ( b[ j ] < b[ i ] ) )
587 ++inv;
588 }
589 return( ( W % 2 == 1 ? inv : inv + blank_row ) % 2 );
590 }
591
592/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
593
594 state_type f_start;
595 state_type f_goal;
596 int v_goal_cell[ cells ] = {};
597 int v_md[ cells ][ cells ] = {};
598 Moves v_moves[ cells ];
599
600 }; // end( class( SlidingTile ) )
601
602/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
603
607
608/*--------------------------------------------------------------------------*/
609
610} // end( namespace PBeFS_di_unipi_it )
611
612/*--------------------------------------------------------------------------*/
613
614#endif /* __PBeFS_SlidingTile */
615
616/*--------------------------------------------------------------------------*/
617/*------------------------- End File SlidingTile.h -------------------------*/
618/*--------------------------------------------------------------------------*/
Header file for the concepts a search problem has to satisfy in order to be searched by the algorithm...
the sliding-tile puzzle on a board of at most 25 cells
Definition SlidingTile.h:170
static constexpr std::size_t num_nblocks(void) noexcept
the number of nblocks: one per triple of cells, not all of them used
Definition SlidingTile.h:376
void for_each_successor(state_type s, cost_type h, F &&f) const
calls f( t , 1 , h( t ) ) for each successor t of s
Definition SlidingTile.h:274
void for_each_feature(state_type s, F &&f) const
calls f( t W H + c ) for each tile t != 0 in each cell c of s
Definition SlidingTile.h:318
static void print(std::ostream &os, state_type s)
prints a board, one row per line
Definition SlidingTile.h:512
std::uint64_t abstract_state(state_type s) const noexcept
the abstract state of AHDA*: the cells of tiles 1, 2 and 3
Definition SlidingTile.h:365
static constexpr int width
Definition SlidingTile.h:178
std::size_t nblock(state_type s) const noexcept
the nblock of PBNF: the cells of the blank and of tiles 1 and 2
Definition SlidingTile.h:383
static board_type parse(const std::string &text)
reads a board: W H numbers, the tiles cell by cell, 0 for the blank
Definition SlidingTile.h:497
state_type initial_state(void) const noexcept
the start board
Definition SlidingTile.h:237
static constexpr std::size_t num_features(void) noexcept
the number of features: one per pair ( tile , cell )
Definition SlidingTile.h:310
std::uint64_t perfect_hash(state_type s) const noexcept
the lexicographic rank of the permutation of the cells of the tiles
Definition SlidingTile.h:437
static constexpr std::size_t num_abstract_features(void) noexcept
the number of abstract features: one per pair ( tile , half board )
Definition SlidingTile.h:348
std::uint64_t hash(state_type s) const noexcept
the hash of a board: its packed integer, mixed
Definition SlidingTile.h:251
std::conditional_t< cells<=16, std::uint64_t, Word128 > state_type
a packed board
Definition SlidingTile.h:187
static constexpr int cells
Definition SlidingTile.h:180
static constexpr std::size_t abstract_feature(std::size_t i) noexcept
the abstract feature of a feature: the tile and the half of its cell
Definition SlidingTile.h:356
static board_type korf_goal(void)
the goal of Korf (1985): the blank in the first cell, then 1 , 2 , ...
Definition SlidingTile.h:196
cost_type heuristic(state_type s) const noexcept
the Manhattan distance of s from the goal
Definition SlidingTile.h:261
bool is_goal(state_type s) const noexcept
true if s is the goal board
Definition SlidingTile.h:244
static int blank(state_type s) noexcept
the cell of the blank in s, i.e., of the zero field of the integer
Definition SlidingTile.h:465
static constexpr int bits
Definition SlidingTile.h:185
std::array< std::uint8_t, cells > board_type
a board
Definition SlidingTile.h:190
void for_each_nblock_successor(std::size_t b, F &&f) const
calls f( b' ) for each abstract successor b' of the nblock b
Definition SlidingTile.h:395
int cost_type
the cost type
Definition SlidingTile.h:189
static board_type unpack(state_type s) noexcept
unpacks a word into a board
Definition SlidingTile.h:487
void for_each_feature_change(state_type s, state_type t, F &&f) const
calls f( k W H + c ) and f( k W H + b ) for the tile k that the move from s to its successor t slides...
Definition SlidingTile.h:332
SlidingTile(const board_type &start, const board_type &goal=korf_goal())
constructor, taking the start and the goal boards
Definition SlidingTile.h:209
cost_type pairwise_heuristic(state_type s, state_type t) const noexcept
the heuristic of PA*SE: the sum of the displacements of the tiles
Definition SlidingTile.h:417
void for_each_successor(state_type s, cost_type h, std::uint8_t op, F &&f) const
as above, but without the successor that op, the cell where the blank was, leads back to; the operato...
Definition SlidingTile.h:292
static state_type pack(const board_type &b) noexcept
Definition SlidingTile.h:477
static int tile(state_type s, int c) noexcept
the tile in the cell c of s
Definition SlidingTile.h:456
static constexpr int height
Definition SlidingTile.h:179
namespace for the Parallel Best-First Search library
Definition AStar.h:83
SlidingTile< 3, 3 > EightPuzzle
the 8-puzzle
Definition SlidingTile.h:604
SlidingTile< 5, 5 > TwentyFourPuzzle
the 24-puzzle
Definition SlidingTile.h:606
SlidingTile< 4, 4 > FifteenPuzzle
the 15-puzzle
Definition SlidingTile.h:605
an unsigned integer of 128 bits, as two words of 64
Definition SlidingTile.h:71
friend constexpr Word128 operator&(Word128 a, Word128 b) noexcept
Definition SlidingTile.h:96
friend constexpr int countr_zero(Word128 a) noexcept
the number of trailing zero bits, 128 if a is 0
Definition SlidingTile.h:136
friend constexpr Word128 operator^(Word128 a, Word128 b) noexcept
Definition SlidingTile.h:104
constexpr Word128(void) noexcept=default
friend constexpr bool operator==(const Word128 &a, const Word128 &b) noexcept=default
friend constexpr Word128 operator>>(Word128 a, int n) noexcept
the shift to the right by n bits,
Definition SlidingTile.h:124
constexpr Word128(std::uint64_t l) noexcept
the integer of value l
Definition SlidingTile.h:80
std::uint64_t hi
the bits 64 to 127
Definition SlidingTile.h:74
constexpr Word128(std::uint64_t l, std::uint64_t h) noexcept
the integer of the words l and h
Definition SlidingTile.h:84
friend constexpr Word128 operator|(Word128 a, Word128 b) noexcept
Definition SlidingTile.h:100
friend constexpr Word128 operator~(Word128 a) noexcept
Definition SlidingTile.h:108
friend constexpr Word128 operator<<(Word128 a, int n) noexcept
the shift to the left by n bits,
Definition SlidingTile.h:114
std::uint64_t lo
the bits 0 to 63
Definition SlidingTile.h:73
Word128 & operator|=(Word128 b) noexcept
Definition SlidingTile.h:132