summaryrefslogtreecommitdiff
path: root/gcc/d/dmd/common/bitfields.d
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d/dmd/common/bitfields.d')
-rw-r--r--gcc/d/dmd/common/bitfields.d70
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);
+}