1 /** 2 * Bit manipulation. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 * Simon Arlott 13 */ 14 15 module ae.utils.bitmanip; 16 17 import std.bitmanip; 18 import std.traits; 19 20 /// Stores `T` in big-endian byte order. 21 struct BigEndian(T) 22 { 23 private ubyte[T.sizeof] _endian_bytes; 24 @property T _endian_value() const { return cast(T)bigEndianToNative!(OriginalType!T)(_endian_bytes); } 25 @property void _endian_value(T value) { _endian_bytes = nativeToBigEndian(OriginalType!T(value)); } 26 alias _endian_value this; 27 alias opAssign = _endian_value; /// 28 this(T value) { _endian_value(value); } /// 29 } 30 31 /// Stores `T` in little-endian byte order. 32 struct LittleEndian(T) 33 { 34 private ubyte[T.sizeof] _endian_bytes; 35 @property T _endian_value() const { return cast(T)littleEndianToNative!(OriginalType!T)(_endian_bytes); } 36 @property void _endian_value(T value) { _endian_bytes = nativeToLittleEndian(OriginalType!T(value)); } 37 alias _endian_value this; 38 alias opAssign = _endian_value; /// 39 this(T value) { _endian_value(value); } /// 40 } 41 42 /// 43 unittest 44 { 45 union U 46 { 47 BigEndian!ushort be; 48 LittleEndian!ushort le; 49 ubyte[2] bytes; 50 } 51 U u; 52 53 u.be = 0x1234; 54 assert(u.bytes == [0x12, 0x34]); 55 56 u.le = 0x1234; 57 assert(u.bytes == [0x34, 0x12]); 58 59 u.bytes = [0x56, 0x78]; 60 assert(u.be == 0x5678); 61 assert(u.le == 0x7856); 62 } 63 64 unittest 65 { 66 enum E : uint { e } 67 BigEndian!E be; 68 } 69 70 unittest 71 { 72 const e = BigEndian!int(1); 73 assert(e == 1); 74 }