1 module nxt.address; 2 3 /** Address as an unsigned integer aligned to a byte alignment `alignment_`. 4 * 5 * Used as key, value or element instead of a pointer in `HybridHashMap` to 6 * prevent triggering of `gc_addRange` and `gc_removeRange`. 7 * 8 * TODO: is `holeValue` suitably chosen? 9 * 10 * See_Also: https://en.wikipedia.org/wiki/Data_structure_alignment 11 */ 12 struct AlignedAddress(uint alignment_) 13 if (alignment_ == 1 || 14 alignment_ == 2 || 15 alignment_ == 4 || 16 alignment_ == 8 || 17 alignment_ == 16 || 18 alignment_ == 32) { 19 enum alignment = alignment_; ///< Alignment in bytes. 20 21 /// Null value. 22 static immutable typeof(this) nullValue = typeof(this).init; 23 24 /// Hole/Deletion value. Prevent hole bitmap from being used. 25 static immutable typeof(this) holeValue = typeof(this)(_addr.max); 26 27 /// Get hash of `this`, with extra fast computation for the small case. 28 @property hash_t toHash() const scope @trusted pure nothrow @nogc 29 { 30 pragma(inline, true); 31 debug checkAlignment(); 32 static if (alignment == 1) 33 const hash = _addr; // as is 34 else static if (alignment == 2) 35 const hash = _addr >> 1; 36 else static if (alignment == 4) 37 const hash = _addr >> 2; 38 else static if (alignment == 8) 39 const hash = _addr >> 3; 40 else static if (alignment == 16) 41 const hash = _addr >> 4; 42 else static if (alignment == 32) 43 const hash = _addr >> 5; 44 else 45 static assert(0, "Unsupported alignment"); 46 /+ TODO: activate import nxt.hash_functions : lemireHash64; +/ 47 import core.internal.hash : hashOf; 48 return hashOf(cast(void*)hash); /+ TODO: is `cast(void*)` preferred here? +/ 49 } 50 51 /// Check alignment. 52 private debug void checkAlignment() const scope pure nothrow @safe @nogc 53 { 54 assert((_addr & (alignment-1)) == 0, 55 "Address is not aligned to " ~ alignment.stringof); 56 } 57 58 size_t _addr; ///< Actual pointer address as unsigned integer. 59 alias _addr this; 60 } 61 62 /// 63 pure nothrow @safe @nogc unittest { // cannot be @nogc when `opIndex` may throw 64 alias A = AlignedAddress!1; 65 import nxt.nullable_traits : hasNullValue, isNullable; 66 static assert(hasNullValue!A); 67 static assert(isNullable!A); 68 }