lu 1.2.2
Library of reusable miscellanea
To use this package, run the following command in your project's root directory:
Manual usage
Put the following dependency into your project's dependences section:
lu
Miscellaneous general-purpose library modules. Nothing extraordinary.
What it is
API documentation can be found here.
In summary:
traits.d
: Various traits and cleverness.
mixin template MyMixin()
{
mixin MixinConstraints!(MixinScope.struct_ | MixinScope.class_);
void foo() {}
int i;
}
struct Bar
{
mixin MyMixin; // ok
}
class Baz
{
mixin MyMixin; // also ok
}
void baz()
{
mixin MyMixin; // static assert 0, wrong mixin scope type
}
meld.d
: Melding two structs/classes of the same type into a union set of their members' values. Also works with arrays and associative arrays. A melding strategy can be supplied as a template parameter for fine-tuning behaviour, but in general non-init values overwrite init ones.
// Aggregate
struct Foo
{
string s;
int i;
}
Foo source;
source.s = "some string";
Foo target;
target.i = 42;
source.meldInto(target);
assert(target.s == "some string");
assert(target.i == 42);
// Array
auto sourceArr = [ 123, 0, 789, 0, 456, 0 ];
auto targetArr = [ 0, 456, 0, 123, 0, 789 ];
sourceArr.meldInto(targetArr);
assert(targetArr == [ 123, 456, 789, 123, 456, 789 ]);
// Associative array
string[string] sourceAA = [ "a":"a", "b":"b" ];
string[string] targetAA = [ "c":"c", "d":"d" ];
sourceAA.meldInto(targetAA);
assert(targetAA == [ "a":"a", "b":"b", "c":"c", "d":"d" ]);
objmanip.d
: Struct/class manipulation, such as setting a member field by its string name.
struct Foo
{
string s;
int i;
bool b;
immutable double pi = 3.14;
}
Foo foo;
bool success;
success = foo.setMemberByName("s", "some string");
assert(success);
assert(foo.s == "some string");
success = foo.setMemberByName("i", "42");
assert(success);
assert(foo.i == 42);
success = foo.setMemberByName("b", "true");
assert(success);
assert(foo.b == true);
success = foo.setMemberByName("pi", "3.15");
assert(!success);
success = foo.setMemberByName("i", 999); // Now works with non-string values
assert(success);
assert(foo.i == 999);
deltastrings.d
: Expressing the differences between two instances of a struct or class of the same type, as either assignment statements or assert statements.
struct Foo
{
string s;
int i;
bool b;
}
Foo altered;
altered.s = "some string";
altered.i = 42;
Appender!(char[]) sink;
// Generate assignment statements by passing `No.asserts`
sink.formatDeltaInto!(No.asserts)(Foo.init, altered);
assert(sink[] ==
`s = "some string";
i = 42;
`);
sink.clear();
// As above but prepend the name "altered" before the members
sink.formatDeltaInto!(No.asserts)(Foo.init, altered, 0, "altered");
assert(sink[] ==
`altered.s = "some string";
altered.i = 42;
`);
sink.clear();
// Generate assert statements by passing `Yes.asserts`
sink.formatDeltaInto!(Yes.asserts)(Foo.init, altered, 0, "altered");
assert(sink[] ==
`assert((altered.s == "some string"), altered.s);
assert((altered.i == 42), altered.i.to!string);
`);
serialisation.d
: Functions and templates for serialising structs into an.ini
file-like format, with entries and values separated into two columns by whitespace.
struct Foo
{
string s;
int i;
bool b;
double pi;
}
Foo foo;
foo.s = "some string";
foo.i = 42;
foo.b = true;
foo.pi = 3.14159;
Appender!(char[]) sink;
sink.serialise(foo);
immutable justified = sink[].justifiedEntryValueText;
assert(justified ==
`[Foo]
s some string
i 42
b true
pi 3.14159
`);
File file = File("config.conf", "w");
file.writeln(justified);
// Later...
Foo newFoo;
newFoo.deserialise(readText("config.conf"));
assert(newFoo.s == "some string");
assert(newFoo.i == 42);
assert(newFoo.b == true);
assert(newFoo.pi == 3.14159);
string.d
: String manipulation functions and templates.
enum line = "Word split by spaces";
string slice = line; // mutable
immutable first = slice.nom(" ");
assert(first == "Word");
immutable second = slice.nom(" ");
assert(second == "split");
immutable third = slice.nom(" ");
assert(third == "by");
assert(slice == "spaces");
immutable fourth = slice.nom!(Yes.inherit)(" ");
assert(fourth == "spaces");
assert(slice.length == 0);
enum quoted = `author "John Doe" title "Foo Bar" tag1 tag2 tag3 tag4`;
string authorHeader;
string author;
string titleHeader;
string title;
string[] overflow;
immutable results = quoted.splitInto(authorHeader, author, titleHeader, title, overflow);
assert(results == SplitResults.overrun);
assert(author == "John Doe");
assert(title == "Foo Bar");
assert(overflow == [ "tag1", "tag2", "tag3", "tag4" ]);
immutable intoArray = quoted.splitWithQuotes();
assert(intoArray.length == 8);
assert(intoArray[1] == "John Doe");
assert(intoArary[3] == "Foo Bar");
assert(intoArray[4..8] == [ "tag1", "tag2", "tag3", "tag4" ]);
conv.d
: Conversion functions and templates.
// Credit for Enum goes to Stephan Koch (https://github.com/UplinkCoder). Used with permission.
// Generates less bloat than `std.conv.to` on larger enums. Restricitons apply.
enum Foo { abc, def, ghi }
immutable someAbc = Foo.abc;
immutable someDef = Foo.def;
immutable someGhi = Foo.ghi;
assert(Enum!Foo.toString(someAbc) == "abc");
assert(Enum!Foo.toString(someDef) == "def");
assert(Enum!Foo.toString(someGhi) == "ghi");
immutable otherAbc = Enum!Foo.fromString("abc");
immutable otherDef = Enum!Foo.fromString("def");
immutable otherGhi = Enum!Foo.fromString("ghi");
json.d
: Convenience wrappers around a PhobosJSONValue
, which can be unwieldy. Not a JSON parser implementation.container.d
: Container things, so far only a primitive FIFOBuffer
(queue) and a LIFOCircularBuffer
.common.d
: Things that don't have a better home yet.numeric.d
: Functions and templates that calculate or manipulate numbers in some way.uda.d
: Some user-defined attributes used here and there.
Roadmap
- nothing right now, ideas needed
Built with
License
This project is licensed under the Boost Software License 1.0 - see the LICENSE10.txt file for details.
- Registered by JR
- 1.2.2 released 2 years ago
- zorael/lu
- www.github.com/zorael/lu
- BSL-1.0
- Copyright © 2016-2022, JR