dyaml/dyaml/flags.d
Ferdinand Majerech 934df763ad Most of emitter work done. There are some more changes left until 0.2,
and the turorials and documentation still need some updating.
2011-10-11 15:58:23 +02:00

90 lines
2.6 KiB
D

// Copyright Ferdinand Majerech 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
///Compact storage of multiple boolean values.
module dyaml.flags;
import std.conv;
package:
/**
* Struct holding multiple named boolean values in a single byte.
*
* Can hold at most 8 values.
*
* Example:
* --------------------
* Flags!("empty", "multiline") flags;
* assert(flags.empty == false && flags.multiline == false);
* flags.multiline = true;
* assert(flags.empty == false && flags.multiline == true);
* flags.empty = true;
* assert(flags.empty == true && flags.multiline == true);
* flags.multiline = false;
* assert(flags.empty == true && flags.multiline == false);
* flags.empty = false;
* assert(flags.empty == false && flags.multiline == false);
* --------------------
*/
struct Flags(names ...) if(names.length <= 8)
{
private:
///Byte storing the flags.
ubyte flags_;
///Generate a setter and a getter for each flag.
static string flags(string[] names ...)
in
{
assert(names.length <= 8, "Flags struct can only hold 8 flags");
}
body
{
string result;
foreach(index, name; names)
{
string istr = to!string(index);
result ~= "\n"
"@property bool " ~ name ~ "(bool value)\n"
"{\n"
" flags_ = value ? flags_ | (1 <<" ~ istr ~ ")\n"
" : flags_ & (0xFF ^ (1 << " ~ istr ~"));\n"
" return value;\n"
"}\n"
"\n"
"@property bool " ~ name ~ "() const pure\n"
"{\n"
" return (flags_ >> " ~ istr ~ ") & 1;\n"
"}\n";
}
return result;
}
public:
///Flag accessors.
mixin(flags(names));
}
unittest
{
import std.stdio;
writeln("Flags unittest");
Flags!("empty", "multiline") flags;
assert(flags.empty == false && flags.multiline == false);
flags.multiline = true;
assert(flags.empty == false && flags.multiline == true);
flags.empty = true;
assert(flags.empty == true && flags.multiline == true);
flags.multiline = false;
assert(flags.empty == true && flags.multiline == false);
flags.empty = false;
assert(flags.empty == false && flags.multiline == false);
}