diff --git a/std/concurrency.d b/std/concurrency.d index 4bff9020c..2aff38375 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -19,38 +19,6 @@ * schedulers are available that multiplex fibers across the main thread or * use some combination of the two approaches. * - * Synopsis: - * --- - * import std.stdio; - * import std.concurrency; - * - * void spawnedFunc(Tid ownerTid) - * { - * // Receive a message from the owner thread. - * receive( - * (int i) { writeln("Received the number ", i);} - * ); - * - * // Send a message back to the owner thread - * // indicating success. - * send(ownerTid, true); - * } - * - * void main() - * { - * // Start spawnedFunc in a new thread. - * auto childTid = spawn(&spawnedFunc, thisTid); - * - * // Send the number 42 to this new thread. - * send(childTid, 42); - * - * // Receive the result code. - * auto wasSuccessful = receiveOnly!(bool); - * assert(wasSuccessful); - * writeln("Successfully printed number."); - * } - * --- - * * Copyright: Copyright Sean Kelly 2009 - 2014. * License: Boost License 1.0. * Authors: Sean Kelly, Alex Rønne Petersen, Martin Nowak @@ -73,6 +41,39 @@ import std.range.primitives; import std.range.interfaces : InputRange; import std.traits; +// Avoids writeln output during a normal test-suite run +// Using writeln is very helpful for runnable unittest examples +version(unittest) +{ + void writeln(T...)(T t){} +} + +/// +@system unittest +{ + static void spawnedFunc(Tid ownerTid) + { + // Receive a message from the owner thread. + receive( + (int i) { writeln("Received the number ", i);} + ); + + // Send a message back to the owner thread + // indicating success. + send(ownerTid, true); + } + + // Start spawnedFunc in a new thread. + auto childTid = spawn(&spawnedFunc, thisTid); + + // Send the number 42 to this new thread. + send(childTid, 42); + + // Receive the result code. + auto wasSuccessful = receiveOnly!(bool); + assert(wasSuccessful); +} + private { template hasLocalAliasing(T...) diff --git a/std/random.d b/std/random.d index 7fcda1953..d7f8a563c 100644 --- a/std/random.d +++ b/std/random.d @@ -23,21 +23,6 @@ useful. The standard library provides an alias $(D_PARAM Random) for whichever generator it considers the most fit for the target environment. -Example: - ----- -// Generate a uniformly-distributed integer in the range [0, 14] -auto i = uniform(0, 15); - -// Generate a uniformly-distributed real in the range [0, 100) -// using a specific random generator -Random gen; -auto r = uniform(0.0L, 100.0L, gen); - -// Generate a 32-bit random number -auto l = uniform!uint(); ----- - In addition to random number generators, this module features distributions, which skew a generator's output statistical distribution in various ways. So far the uniform distribution for @@ -70,6 +55,26 @@ module std.random; import std.range.primitives; import std.traits; +/// +@safe unittest +{ + // seed a random generator with a constant + auto rnd = Random(42); + + // Generate a uniformly-distributed integer in the range [0, 14] + // If no random generator is passed, the global `rndGen` would be used + auto i = uniform(0, 15, rnd); + assert(i == 12); + + // Generate a uniformly-distributed real in the range [0, 100) + auto r = uniform(0.0L, 100.0L, rnd); + assert(r == 79.65429843861011285); + + // Generate a 32-bit random number + auto u = uniform!uint(rnd); + assert(u == 4083286876); +} + version(unittest) { static import std.meta; diff --git a/std/typecons.d b/std/typecons.d index d1ad5edcf..2b163b130 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -6,30 +6,6 @@ that allow construction of new, useful general-purpose types. Source: $(PHOBOSSRC std/_typecons.d) -Synopsis: - ----- -// value tuples -alias Coord = Tuple!(float, "x", float, "y", float, "z"); -Coord c; -c[1] = 1; // access by index -c.z = 1; // access by given name -alias DicEntry = Tuple!(string, string); // names can be omitted - -// Rebindable references to const and immutable objects -void bar() -{ - const w1 = new Widget, w2 = new Widget; - w1.foo(); - // w1 = w2 would not work; can't rebind const object - auto r = Rebindable!(const Widget)(w1); - // invoke method as if r were a Widget object - r.foo(); - // rebind r to refer to another object - r = w2; -} ----- - Copyright: Copyright the respective authors, 2008- License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP erdani.org, Andrei Alexandrescu), @@ -44,6 +20,38 @@ import core.stdc.stdint : uintptr_t; import std.meta; // : AliasSeq, allSatisfy; import std.traits; +/// +@safe unittest +{ + // value tuples + alias Coord = Tuple!(int, "x", int, "y", int, "z"); + Coord c; + c[1] = 1; // access by index + c.z = 1; // access by given name + assert(c == Coord(0, 1, 1)); + + // names can be omitted + alias DicEntry = Tuple!(string, string); + + // tuples can also be constructed on instantiation + assert(tuple(2, 3, 4)[1] == 3); + // construction on instantiation works with names too + assert(tuple!("x", "y", "z")(2, 3, 4).y == 3); + + // Rebindable references to const and immutable objects + { + class Widget { void foo() const @safe {} } + const w1 = new Widget, w2 = new Widget; + w1.foo(); + // w1 = w2 would not work; can't rebind const object + auto r = Rebindable!(const Widget)(w1); + // invoke method as if r were a Widget object + r.foo(); + // rebind r to refer to another object + r = w2; + } +} + debug(Unique) import std.stdio; /** diff --git a/std/variant.d b/std/variant.d index 8ca537325..574e2c5a3 100644 --- a/std/variant.d +++ b/std/variant.d @@ -10,38 +10,6 @@ Such types are useful for type-uniform binary interfaces, interfacing with scripting languages, and comfortable exploratory programming. -Synopsis: ----- -Variant a; // Must assign before use, otherwise exception ensues -// Initialize with an integer; make the type int -Variant b = 42; -assert(b.type == typeid(int)); -// Peek at the value -assert(b.peek!(int) !is null && *b.peek!(int) == 42); -// Automatically convert per language rules -auto x = b.get!(real); -// Assign any other type, including other variants -a = b; -a = 3.14; -assert(a.type == typeid(double)); -// Implicit conversions work just as with built-in types -assert(a < b); -// Check for convertibility -assert(!a.convertsTo!(int)); // double not convertible to int -// Strings and all other arrays are supported -a = "now I'm a string"; -assert(a == "now I'm a string"); -a = new int[42]; // can also assign arrays -assert(a.length == 42); -a[5] = 7; -assert(a[5] == 7); -// Can also assign class values -class Foo {} -auto foo = new Foo; -a = foo; -assert(*a.peek!(Foo) == foo); // and full type information is preserved ----- - A $(LREF Variant) object can hold a value of any type, with very few restrictions (such as `shared` types and noncopyable types). Setting the value is as immediate as assigning to the `Variant` object. To read back the value of @@ -67,6 +35,43 @@ module std.variant; import std.meta, std.traits, std.typecons; +/// +@system unittest +{ + Variant a; // Must assign before use, otherwise exception ensues + // Initialize with an integer; make the type int + Variant b = 42; + assert(b.type == typeid(int)); + // Peek at the value + assert(b.peek!(int) !is null && *b.peek!(int) == 42); + // Automatically convert per language rules + auto x = b.get!(real); + + // Assign any other type, including other variants + a = b; + a = 3.14; + assert(a.type == typeid(double)); + // Implicit conversions work just as with built-in types + assert(a < b); + // Check for convertibility + assert(!a.convertsTo!(int)); // double not convertible to int + // Strings and all other arrays are supported + a = "now I'm a string"; + assert(a == "now I'm a string"); + + // can also assign arrays + a = new int[42]; + assert(a.length == 42); + a[5] = 7; + assert(a[5] == 7); + + // Can also assign class values + class Foo {} + auto foo = new Foo; + a = foo; + assert(*a.peek!(Foo) == foo); // and full type information is preserved +} + /++ Gives the $(D sizeof) the largest type given. +/