diff options
Diffstat (limited to 'gcc/d/dmd/common/bitfields.d')
-rw-r--r-- | gcc/d/dmd/common/bitfields.d | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/gcc/d/dmd/common/bitfields.d b/gcc/d/dmd/common/bitfields.d new file mode 100644 index 00000000000..d17983d66b4 --- /dev/null +++ b/gcc/d/dmd/common/bitfields.d @@ -0,0 +1,70 @@ +/** + * A library bitfields utility + * + * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Authors: Dennis Korpel + * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/bitfields.d, common/bitfields.d) + * Documentation: https://dlang.org/phobos/dmd_common_bitfields.html + * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/common/bitfields.d + */ +module dmd.common.bitfields; + +/** + * Generate code for bit fields inside a struct/class body + * Params: + * S = type of a struct with only boolean fields, which should become bit fields + * T = type of bit fields variable, must have enough bits to store all booleans + * Returns: D code with a bit fields variable and getter / setter functions + */ +extern (D) string generateBitFields(S, T)() +if (__traits(isUnsigned, T)) +{ + string result = "extern (C++) pure nothrow @nogc @safe final {"; + enum structName = __traits(identifier, S); + + foreach (size_t i, mem; __traits(allMembers, S)) + { + static assert(is(typeof(__traits(getMember, S, mem)) == bool)); + static assert(i < T.sizeof * 8, "too many fields for bit field storage of type `"~T.stringof~"`"); + enum mask = "(1 << "~i.stringof~")"; + result ~= " + /// set or get the corresponding "~structName~" member + bool "~mem~"() const { return !!(bitFields & "~mask~"); } + /// ditto + bool "~mem~"(bool v) + { + v ? (bitFields |= "~mask~") : (bitFields &= ~"~mask~"); + return v; + }"; + } + return result ~ "}\n private "~T.stringof~" bitFields;\n"; +} + +/// +unittest +{ + static struct B + { + bool x; + bool y; + bool z; + } + + static struct S + { + mixin(generateBitFields!(B, ubyte)); + } + + S s; + assert(!s.x); + s.x = true; + assert(s.x); + s.x = false; + assert(!s.x); + + s.y = true; + assert(s.y); + assert(!s.x); + assert(!s.z); +} |