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 }