diff --git a/docs/deps.svg b/docs/deps.svg new file mode 100644 index 0000000..13c7679 --- /dev/null +++ b/docs/deps.svg @@ -0,0 +1,67 @@ + + + + + + +eris + + + +core + +eris.core + + + +array + +eris.array + + + +array->core + + + + + +math + +eris.math + + + +allocator + +eris.allocator + + + +btree + +eris.btree + + + +btree->core + + + + + +btree->array + + + + + +btree->allocator + + + + + diff --git a/docs/eris.allocator.Allocator.alignment.html b/docs/eris.allocator.Allocator.alignment.html new file mode 100644 index 0000000..73fa032 --- /dev/null +++ b/docs/eris.allocator.Allocator.alignment.html @@ -0,0 +1,35 @@ + + + + Allocator.alignment (eris.allocator.Allocator.alignment) + + + + + + + + + + +
+
+

Allocator.alignment

Minimum alignment of all allocated memory blocks.

interface Allocator
nothrow @property const
uint
alignment
()
out (a; a > 0 && a.isPowerOf2)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.Allocator.allocate.html b/docs/eris.allocator.Allocator.allocate.html new file mode 100644 index 0000000..107aefa --- /dev/null +++ b/docs/eris.allocator.Allocator.allocate.html @@ -0,0 +1,36 @@ + + + + Allocator.allocate (eris.allocator.Allocator.allocate) + + + + + + + + + + +
+
+

Allocator.allocate

Attempts to allocate a memory block of size bytes.

If size == 0, the returned slice might have a null .ptr, but either way + it can be safely deallocated.

interface Allocator
nothrow
void[]
allocate
(
size_t size
)
out (mem; mem.ptr == null || mem.length == size)

Return Value

Type: void[]

The allocated memory block, or null on allocation failure.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.Allocator.deallocate.html b/docs/eris.allocator.Allocator.deallocate.html new file mode 100644 index 0000000..be70e64 --- /dev/null +++ b/docs/eris.allocator.Allocator.deallocate.html @@ -0,0 +1,35 @@ + + + + Allocator.deallocate (eris.allocator.Allocator.deallocate) + + + + + + + + + + +
+
+

Allocator.deallocate

Deallocates a previously-allocated memory block.

NOTE: Unlike in std.experimental.allocator, this method does not have to return anything.

interface Allocator
nothrow
void
deallocate
(
void[] memory
)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.Allocator.html b/docs/eris.allocator.Allocator.html new file mode 100644 index 0000000..b6a21bf --- /dev/null +++ b/docs/eris.allocator.Allocator.html @@ -0,0 +1,36 @@ + + + + Allocator (eris.allocator.Allocator) + + + + + + + + + + +
+
+

Allocator

Base allocator interface.

All memory obtained with allocate must be disposed by deallocate on the same allocator instance.

NOTE: Unlike std.experimental.allocator, + we always require a deallocation procedure.

Members

Functions

allocate
void[] allocate(size_t size)

Attempts to allocate a memory block of size bytes.

deallocate
void deallocate(void[] memory)

Deallocates a previously-allocated memory block.

Properties

alignment
uint alignment [@property getter]

Minimum alignment of all allocated memory blocks.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.Mallocator.html b/docs/eris.allocator.Mallocator.html new file mode 100644 index 0000000..1543321 --- /dev/null +++ b/docs/eris.allocator.Mallocator.html @@ -0,0 +1,35 @@ + + + + Mallocator (eris.allocator.Mallocator) + + + + + + + + + + +
+
+

Mallocator

C stdlib allocator using malloc and free.

struct Mallocator {
pragma(inline) nothrow @nogc
enum uint alignment;
}
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.dispose.1.html b/docs/eris.allocator.dispose.1.html new file mode 100644 index 0000000..bb9d579 --- /dev/null +++ b/docs/eris.allocator.dispose.1.html @@ -0,0 +1,35 @@ + + + + dispose (eris.allocator.dispose) + + + + + + + + + + +
+
+

dispose

Destroy and deallocate a given object/array.

  1. void dispose(Allocator alloc, T* p)
    void
    dispose
    (
    Allocator
    T
    )
    (
    ref Allocator alloc
    ,
    T* p
    )
    if (
    isAllocator!Allocator
    )
  2. void dispose(Allocator alloc, T[] array)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.dispose.2.html b/docs/eris.allocator.dispose.2.html new file mode 100644 index 0000000..d8f19ac --- /dev/null +++ b/docs/eris.allocator.dispose.2.html @@ -0,0 +1,35 @@ + + + + dispose (eris.allocator.dispose) + + + + + + + + + + +
+
+

dispose

Destroy and deallocate a given object/array.

  1. void dispose(Allocator alloc, T* p)
  2. void dispose(Allocator alloc, T[] array)
    void
    dispose
    (
    Allocator
    T
    )
    (
    ref Allocator alloc
    ,
    T[] array
    )
    if (
    isAllocator!Allocator
    )
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.dispose.html b/docs/eris.allocator.dispose.html new file mode 100644 index 0000000..72a06bf --- /dev/null +++ b/docs/eris.allocator.dispose.html @@ -0,0 +1 @@ + Continue to overload \ No newline at end of file diff --git a/docs/eris.allocator.html b/docs/eris.allocator.html new file mode 100644 index 0000000..4865387 --- /dev/null +++ b/docs/eris.allocator.html @@ -0,0 +1,36 @@ + + + + eris.allocator (eris.allocator) + + + + + + + + + + +
+
+

eris.allocator

Custom memory allocators and related helpers.

Based on std.experimental.allocator, +without being strictly compatible.

Members

Functions

dispose
void dispose(Allocator alloc, T* p)
void dispose(Allocator alloc, T[] array)

Destroy and deallocate a given object/array.

make
T* make(Allocator alloc, Args args)

Allocate and construct an object of the specified type.

makeArray
T[] makeArray(Allocator alloc, size_t length, T init)

Make an array of the specified type.

Interfaces

Allocator
interface Allocator

Base allocator interface.

Structs

Mallocator
struct Mallocator

C stdlib allocator using malloc and free.

Variables

isAllocator
enum bool isAllocator(T);

Static interface counterpart of Allocator.

platformAlignment
enum uint platformAlignment;

Alignment large enough for any scalar type.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.isAllocator.html b/docs/eris.allocator.isAllocator.html new file mode 100644 index 0000000..6c55254 --- /dev/null +++ b/docs/eris.allocator.isAllocator.html @@ -0,0 +1,37 @@ + + + + isAllocator (eris.allocator.isAllocator) + + + + + + + + + + +
+
+

isAllocator

Static interface counterpart of Allocator.

enum bool isAllocator(T);

Examples

static assert(isAllocator!Allocator); // obviously
+static assert(isAllocator!Mallocator);
+
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.make.html b/docs/eris.allocator.make.html new file mode 100644 index 0000000..2395be0 --- /dev/null +++ b/docs/eris.allocator.make.html @@ -0,0 +1,40 @@ + + + + make (eris.allocator.make) + + + + + + + + + + +
+
+

make

Allocate and construct an object of the specified type.

T*
make
(
T
Allocator
Args...
)
(
ref Allocator alloc
,
auto ref Args args
)
if (
isAllocator!Allocator
)

Examples

struct S { bool ok = false; bool notOk = true; }
+Mallocator alloc;
+S* p = alloc.make!S(true, false);
+scope(exit) alloc.dispose(p);
+assert(p.ok);
+assert(!p.notOk);
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.makeArray.html b/docs/eris.allocator.makeArray.html new file mode 100644 index 0000000..04fa951 --- /dev/null +++ b/docs/eris.allocator.makeArray.html @@ -0,0 +1,37 @@ + + + + makeArray (eris.allocator.makeArray) + + + + + + + + + + +
+
+

makeArray

Make an array of the specified type.

T[]
makeArray
(
T
Allocator
)
(
ref Allocator alloc
,
size_t length
,
T init = T.init
)
if (
isAllocator!Allocator
)

Examples

Mallocator alloc;
+ubyte[] mem = alloc.makeArray!ubyte(64);
+scope(exit) alloc.dispose(mem);
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.allocator.platformAlignment.html b/docs/eris.allocator.platformAlignment.html new file mode 100644 index 0000000..f6183bf --- /dev/null +++ b/docs/eris.allocator.platformAlignment.html @@ -0,0 +1,35 @@ + + + + platformAlignment (eris.allocator.platformAlignment) + + + + + + + + + + +
+
+

platformAlignment

Alignment large enough for any scalar type.

enum uint platformAlignment;
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.array.html b/docs/eris.array.html new file mode 100644 index 0000000..f1e4a76 --- /dev/null +++ b/docs/eris.array.html @@ -0,0 +1,35 @@ + + + + eris.array (eris.array) + + + + + + + + + + +
+
+

eris.array

In-place manipulation of slices.

Members

Functions

shift
void shift(T[] slice, size_t index, T x)

Inserts at a given index in the slice while dropping its last element.

shiftLeft
void shiftLeft(T[] slice, size_t n)

Shift elements in the slice by n > 0 positions to the left.

shiftRight
void shiftRight(T[] slice, size_t n)

Shift all elements in the slice by n > 0 positions to the right.

unshift
T unshift(T[] slice, size_t index)

Pops an elemens from a given index in the slice.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.array.shift.html b/docs/eris.array.shift.html new file mode 100644 index 0000000..1c3f596 --- /dev/null +++ b/docs/eris.array.shift.html @@ -0,0 +1,38 @@ + + + + shift (eris.array.shift) + + + + + + + + + + +
+
+

shift

Inserts at a given index in the slice while dropping its last element.

Basically a macro for

slice[index .. $].shiftRight(1);
+slice[index] = x;
void
shift
(
T
)
(
T[] slice
,
size_t index
,
auto ref T x
)

Examples

static int[] a = [ 1, 2, 4, 5 ];
+a.shift(2, 3);
+assert(a[0] == 1); assert(a[1] == 2); assert(a[2] == 3); assert(a[3] == 4);
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.array.shiftLeft.html b/docs/eris.array.shiftLeft.html new file mode 100644 index 0000000..e3da84b --- /dev/null +++ b/docs/eris.array.shiftLeft.html @@ -0,0 +1,36 @@ + + + + shiftLeft (eris.array.shiftLeft) + + + + + + + + + + +
+
+

shiftLeft

Shift elements in the slice by n > 0 positions to the left.

The first few n elements in the slice will get overwritten.

void
shiftLeft
(
T
)
(
T[] slice
,
size_t n = 1
)

Examples

static int[] empty = [];
+empty.shiftLeft(2); // does nothing

See Also

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.array.shiftRight.html b/docs/eris.array.shiftRight.html new file mode 100644 index 0000000..ebd8e36 --- /dev/null +++ b/docs/eris.array.shiftRight.html @@ -0,0 +1,35 @@ + + + + shiftRight (eris.array.shiftRight) + + + + + + + + + + +
+
+

shiftRight

Shift all elements in the slice by n > 0 positions to the right.

The last few n elements in the slice will get overwritten.

void
shiftRight
(
T
)
(
T[] slice
,
size_t n = 1
)

See Also

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.array.unshift.html b/docs/eris.array.unshift.html new file mode 100644 index 0000000..c1ee597 --- /dev/null +++ b/docs/eris.array.unshift.html @@ -0,0 +1,40 @@ + + + + unshift (eris.array.unshift) + + + + + + + + + + +
+
+

unshift

Pops an elemens from a given index in the slice.

Basically a macro for

T temp = slice[index];
+slice[index .. $].shiftLeft(1);
+return temp;
T
unshift
(
T
)
(
T[] slice
,
size_t index
)

Examples

static int[] a = [ 1, 2, 3, 4 ];
+int extracted = a.unshift(2);
+assert(extracted == 3);
+assert(a[0] == 1); assert(a[1] == 2); assert(a[2] == 4);
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.clear.html b/docs/eris.btree.BTree.clear.html new file mode 100644 index 0000000..847ac16 --- /dev/null +++ b/docs/eris.btree.BTree.clear.html @@ -0,0 +1,35 @@ + + + + BTree.clear (eris.btree.BTree.clear) + + + + + + + + + + +
+
+

BTree.clear

Removes all elements and deallocates all memory for this tree.

If existing elements are structs with a destructor defined, those will be called.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
void
clear
()
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.html b/docs/eris.btree.BTree.html new file mode 100644 index 0000000..79f30fa --- /dev/null +++ b/docs/eris.btree.BTree.html @@ -0,0 +1,132 @@ + + + + BTree (eris.btree.BTree) + + + + + + + + + + +
+
+

BTree

B-tree data structure template.

B-trees are optimized for "cache friendliness" and low overhead per stored element. +The main tradeoff w.r.t other self-balancing trees is that insertions and +deletions from a B-tree will move multiple elements around per operation, +invalidating references and iterators. +When elements are big, consider storing them through indirect references.

In order to ensure all memory is deallocated, remember to call clear. +Alternatively, if stored elements don't need elaborate destruction, and the +provided allocator supports arenas, a full deallocation called externally will +not leave anything leaking (but beware of use-after-free bugs in this case).

While keeping duplicates is not the default, it can be used to implement multisets. +Just note that, if duplicate elements are allowed in the B-tree, they will have an +unspecified order among themselves (i.e. not related to order of insertion).

Members

Functions

clear
void clear()

Removes all elements and deallocates all memory for this tree.

opApply
int opApply(int delegate(ref const(T)) nothrow @(nogc) dg)

Iterates over elements in order. NOTE: should not be used while inserting or deleting elements from the tree.

opApply
int opApply(int delegate(ref T) nothrow @(nogc) dg)

Iterates over elements in order. NOTE: should not be used while inserting or deleting elements from the tree.

opBinaryRight
bool opBinaryRight(T x)

Check if the tree contains an element.

opEquals
bool opEquals(const(BTree!(T, P, A)) other)

Element-wise comparison.

opIndex
inout(T)* opIndex(T x)

Gets the address of the first matching element, or null if it isn't in the tree.

put
T* put(T x)

Adds an element to the tree.

remove
bool remove(T x, void delegate(ref T) nothrow @(nogc) destroy)

Removes (at most) one element from the tree.

toHash
size_t toHash()

Combined element hash.

upsert
T* upsert(T x, T delegate() nothrow @(nogc) create, void delegate(ref T) nothrow @(nogc) update)

Updates an element already in the set or creates a new one therein.

Properties

length
size_t length [@property getter]

Returns the number of elements currently stored in the tree.

Examples

1 // tip: debug w/ visualizer at https://www.cs.usfca.edu/~galles/visualization/BTree.html
+2 enum BTreeParameters params = {
+3 	nodeSlots: 3,
+4 	customCompare: true,
+5 	useBinarySearch: Ternary.yes,
+6 };
+7 auto btree = BTree!(int, params)((ref a, ref b) => a - b);
+8 static const payload = [
+9 	34, 33, 38,
+10 	28, 27, 22,
+11 	30, 21, 24,
+12 	18, 19, 20, 26, 32, 42,
+13 	23,
+14 ];
+15 
+16 assert(btree.length == 0);
+17 foreach (x; payload) {
+18 	// at first, the set does not contain x
+19 	assert(x !in btree);
+20 	assert(!btree.remove(x));
+21 	// insert x and test returned address
+22 	int* p = btree.put(x);
+23 	assert(*p == x);
+24 	// now it does contain x, so test lookup
+25 	assert(x in btree);
+26 	assert(p == btree[x]);
+27 	// redundant insert is redundant
+28 	int* q = btree.put(x);
+29 	assert(q == p);
+30 }
+31 
+32 // sanity check: the b-tree didn't come up with new elements we didn't insert
+33 assert(btree.length == payload.length);
+34 foreach (ref const x; btree) {
+35 	import std.algorithm.searching : canFind;
+36 	assert(payload.canFind(x));
+37 }
+38 
+39 // remove all but the last 3 elements in reverse order
+40 for (int n = 1; n + 2 < payload.length; ++n) {
+41 	auto x = payload[$ - n];
+42 	assert(x in btree);
+43 	btree.remove(x);
+44 	assert(x !in btree);
+45 	assert(btree.length == payload.length - n);
+46 }
+47 assert(btree.length == 3);
+48 
+49 // make sure we test aggregate equality
+50 auto other = BTree!int();
+51 assert(btree != other);
+52 import std.range.primitives : put;
+53 static const remaining = [33, 34, 38];
+54 put(other, remaining);
+55 assert(btree == other);
+56 
+57 // clear gets rid of the rest
+58 btree.clear();
+59 assert(btree.length == 0);
+60 foreach (x; payload) assert(x !in btree);
static struct S {
+	int x;
+	uint discriminator;
+ nothrow @nogc:
+	alias x this;
+	int opCmp(in S other) const => this.x - other.x;
+}
+
+enum BTreeParameters params = { allowDuplicates: true };
+BTree!(S, params) multiset;
+scope(exit) multiset.clear();
+static const payload = [ S(6), S(2), S(4), S(5), S(6, 9), S(4, 20) ];
+
+assert(multiset.length == 0);
+foreach (x; payload) {
+	S* p = multiset.put(x);
+	assert(*p == x);
+	assert(x in multiset);
+}
+assert(multiset.length == payload.length);
+
+assert(multiset.remove(S(4)));
+assert(S(4) in multiset);
+assert(multiset.remove(S(4)));
+assert(S(4) !in multiset);
+assert(multiset.length == payload.length - 2u);
+
+assert(multiset.remove(S(6)));
+assert(multiset.remove(S(6)));
+assert(!multiset.remove(S(6)));
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.length.html b/docs/eris.btree.BTree.length.html new file mode 100644 index 0000000..628bb2e --- /dev/null +++ b/docs/eris.btree.BTree.length.html @@ -0,0 +1,35 @@ + + + + BTree.length (eris.btree.BTree.length) + + + + + + + + + + +
+
+

BTree.length

Returns the number of elements currently stored in the tree.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
@property const
size_t
length
()
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.opApply.1.html b/docs/eris.btree.BTree.opApply.1.html new file mode 100644 index 0000000..da59456 --- /dev/null +++ b/docs/eris.btree.BTree.opApply.1.html @@ -0,0 +1,35 @@ + + + + BTree.opApply (eris.btree.BTree.opApply) + + + + + + + + + + +
+
+

BTree.opApply

Iterates over elements in order. NOTE: should not be used while inserting or deleting elements from the tree.

  1. int opApply(int delegate(ref T) nothrow @(nogc) dg)
    struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
    int
    opApply
    (
    scope int delegate
    (
    ref T
    )
    nothrow @nogc
    dg
    )
  2. int opApply(int delegate(ref const(T)) nothrow @(nogc) dg)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.opApply.2.html b/docs/eris.btree.BTree.opApply.2.html new file mode 100644 index 0000000..23736e0 --- /dev/null +++ b/docs/eris.btree.BTree.opApply.2.html @@ -0,0 +1,35 @@ + + + + BTree.opApply (eris.btree.BTree.opApply) + + + + + + + + + + +
+
+

BTree.opApply

Iterates over elements in order. NOTE: should not be used while inserting or deleting elements from the tree.

  1. int opApply(int delegate(ref T) nothrow @(nogc) dg)
  2. int opApply(int delegate(ref const(T)) nothrow @(nogc) dg)
    struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
    const
    int
    opApply
    (
    scope int delegate
    (
    ref const(T)
    )
    nothrow @nogc
    dg
    )
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.opApply.html b/docs/eris.btree.BTree.opApply.html new file mode 100644 index 0000000..bb396ed --- /dev/null +++ b/docs/eris.btree.BTree.opApply.html @@ -0,0 +1 @@ + Continue to overload \ No newline at end of file diff --git a/docs/eris.btree.BTree.opBinaryRight.html b/docs/eris.btree.BTree.opBinaryRight.html new file mode 100644 index 0000000..2fbaf31 --- /dev/null +++ b/docs/eris.btree.BTree.opBinaryRight.html @@ -0,0 +1,35 @@ + + + + BTree.opBinaryRight (eris.btree.BTree.opBinaryRight) + + + + + + + + + + +
+
+

BTree.opBinaryRight

Check if the tree contains an element.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
const
bool
opBinaryRight
(
string op : "in"
)
(
in T x
)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.opEquals.html b/docs/eris.btree.BTree.opEquals.html new file mode 100644 index 0000000..1a43a6a --- /dev/null +++ b/docs/eris.btree.BTree.opEquals.html @@ -0,0 +1,35 @@ + + + + BTree.opEquals (eris.btree.BTree.opEquals) + + + + + + + + + + +
+
+

BTree.opEquals

Element-wise comparison.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
const
bool
opEquals
(
ref const(BTree!(T, P, A)) other
)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.opIndex.html b/docs/eris.btree.BTree.opIndex.html new file mode 100644 index 0000000..a5e41ac --- /dev/null +++ b/docs/eris.btree.BTree.opIndex.html @@ -0,0 +1,35 @@ + + + + BTree.opIndex (eris.btree.BTree.opIndex) + + + + + + + + + + +
+
+

BTree.opIndex

Gets the address of the first matching element, or null if it isn't in the tree.

NOTE: returned pointer may be invalidated by any insertions or deletions.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
inout
inout(T)*
opIndex
(
in T x
)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.put.html b/docs/eris.btree.BTree.put.html new file mode 100644 index 0000000..35c8bb4 --- /dev/null +++ b/docs/eris.btree.BTree.put.html @@ -0,0 +1,35 @@ + + + + BTree.put (eris.btree.BTree.put) + + + + + + + + + + +
+
+

BTree.put

Adds an element to the tree.

If the tree allows duplicates, this is an insertion; if it doesn't, this is an upsert.

NOTE:

  • Returned pointer may be invalidated by any following insertions or deletions.
  • Allocation failure is irrecoverable in this implementation.
struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
T*
put
(
T x
)

Return Value

Type: T*

A pointer to the stored element, or null in case of insertion failure.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.remove.html b/docs/eris.btree.BTree.remove.html new file mode 100644 index 0000000..7ed35c3 --- /dev/null +++ b/docs/eris.btree.BTree.remove.html @@ -0,0 +1,36 @@ + + + + BTree.remove (eris.btree.BTree.remove) + + + + + + + + + + +
+
+

BTree.remove

Removes (at most) one element from the tree.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
bool
remove
(
in T x
,
scope void delegate
(
ref T
)
nothrow @nogc
destroy = null
)

Parameters

x T

element being looked up in the tree

destroy void delegate
(
ref T
)
nothrow @nogc

callback to cleanup after the element being removed (if found); + defaults to object.destroy.

Return Value

Type: bool

Whether or not at least one x was contained in the tree.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.toHash.html b/docs/eris.btree.BTree.toHash.html new file mode 100644 index 0000000..0583cd8 --- /dev/null +++ b/docs/eris.btree.BTree.toHash.html @@ -0,0 +1,35 @@ + + + + BTree.toHash (eris.btree.BTree.toHash) + + + + + + + + + + +
+
+

BTree.toHash

Combined element hash.

struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
const
size_t
toHash
()
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTree.upsert.html b/docs/eris.btree.BTree.upsert.html new file mode 100644 index 0000000..630be3b --- /dev/null +++ b/docs/eris.btree.BTree.upsert.html @@ -0,0 +1,41 @@ + + + + BTree.upsert (eris.btree.BTree.upsert) + + + + + + + + + + +
+
+

BTree.upsert

Updates an element already in the set or creates a new one therein.

NOTE:

  • Returned pointer may be invalidated by any following insertions or deletions.
  • Allocation failure is irrecoverable in this implementation.
struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)
T*
upsert
(
in T x
,
scope T delegate
()
nothrow @nogc
create
,
scope void delegate
(
ref T
)
nothrow @nogc
update = null
)
out (p) +{ + assert ((p == null) || (*p in this)); +}

Parameters

x T

element being looked up

create T delegate
()
nothrow @nogc

callback to create a new matching element to insert

update void delegate
(
ref T
)
nothrow @nogc

callback to modify an existing element in the tree; only called + if not null; should never be provided if the tree allows duplicates

Return Value

Type: T*

A pointer to the element currently stored in the set, whether it was updated or inserted. + This value is only null if the element would have been inserted but + the operation didn't succeed at some point (i.e. memory allocation failure).

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTreeParameters.allowDuplicates.html b/docs/eris.btree.BTreeParameters.allowDuplicates.html new file mode 100644 index 0000000..88777d0 --- /dev/null +++ b/docs/eris.btree.BTreeParameters.allowDuplicates.html @@ -0,0 +1,35 @@ + + + + BTreeParameters.allowDuplicates (eris.btree.BTreeParameters.allowDuplicates) + + + + + + + + + + +
+
+

BTreeParameters.allowDuplicates

Whether or not to allow duplicates in the B-tree; defaults to false.

struct BTreeParameters
bool allowDuplicates;
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTreeParameters.customCompare.html b/docs/eris.btree.BTreeParameters.customCompare.html new file mode 100644 index 0000000..6526f7e --- /dev/null +++ b/docs/eris.btree.BTreeParameters.customCompare.html @@ -0,0 +1,36 @@ + + + + BTreeParameters.customCompare (eris.btree.BTreeParameters.customCompare) + + + + + + + + + + +
+
+

BTreeParameters.customCompare

Use a custom comparison function as an alternative to static + opCmp.

struct BTreeParameters
bool customCompare;
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTreeParameters.html b/docs/eris.btree.BTreeParameters.html new file mode 100644 index 0000000..00e5c83 --- /dev/null +++ b/docs/eris.btree.BTreeParameters.html @@ -0,0 +1,36 @@ + + + + BTreeParameters (eris.btree.BTreeParameters) + + + + + + + + + + +
+
+

BTreeParameters

Static parameters for BTree template.

Members

Variables

allowDuplicates
bool allowDuplicates;

Whether or not to allow duplicates in the B-tree; defaults to false.

customCompare
bool customCompare;

Use a custom comparison function as an alternative to static + opCmp.

nodeSlots
size_t nodeSlots;

Max elements stored per node, must be at least 2. Use size_t.max for default.

useBinarySearch
Ternary useBinarySearch;

Whether to use a binary intra-node search. Use Ternary.unknown for default.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTreeParameters.nodeSlots.html b/docs/eris.btree.BTreeParameters.nodeSlots.html new file mode 100644 index 0000000..cb38a75 --- /dev/null +++ b/docs/eris.btree.BTreeParameters.nodeSlots.html @@ -0,0 +1,35 @@ + + + + BTreeParameters.nodeSlots (eris.btree.BTreeParameters.nodeSlots) + + + + + + + + + + +
+
+

BTreeParameters.nodeSlots

Max elements stored per node, must be at least 2. Use size_t.max for default.

struct BTreeParameters
size_t nodeSlots;
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.BTreeParameters.useBinarySearch.html b/docs/eris.btree.BTreeParameters.useBinarySearch.html new file mode 100644 index 0000000..b4b2349 --- /dev/null +++ b/docs/eris.btree.BTreeParameters.useBinarySearch.html @@ -0,0 +1,35 @@ + + + + BTreeParameters.useBinarySearch (eris.btree.BTreeParameters.useBinarySearch) + + + + + + + + + + +
+
+

BTreeParameters.useBinarySearch

Whether to use a binary intra-node search. Use Ternary.unknown for default.

struct BTreeParameters
Ternary useBinarySearch;
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.btree.html b/docs/eris.btree.html new file mode 100644 index 0000000..486506c --- /dev/null +++ b/docs/eris.btree.html @@ -0,0 +1,35 @@ + + + + eris.btree (eris.btree) + + + + + + + + + + +
+
+

eris.btree

Generic B-tree data structure.

Members

Structs

BTree
struct BTree(T, BTreeParameters params = BTreeParameters.init, Allocator = Mallocator)

B-tree data structure template.

BTreeParameters
struct BTreeParameters

Static parameters for BTree template.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.core.Unit.html b/docs/eris.core.Unit.html new file mode 100644 index 0000000..760b6eb --- /dev/null +++ b/docs/eris.core.Unit.html @@ -0,0 +1,35 @@ + + + + Unit (eris.core.Unit) + + + + + + + + + + +
+
+

Unit

Zero-sized type carrying no information at all.

NOTE: Make sure not to use this in extern (C) signatures, as the ABI is unspecified.

alias Unit = void[0]
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.core.html b/docs/eris.core.html new file mode 100644 index 0000000..dbdd011 --- /dev/null +++ b/docs/eris.core.html @@ -0,0 +1,36 @@ + + + + eris.core (eris.core) + + + + + + + + + + +
+
+

eris.core

Core type definitions, templates and helper procedures.

Members

Aliases

Unit
alias Unit = void[0]

Zero-sized type carrying no information at all.

Functions

move
T move(T source)

Phobos move, but always by destructive copy when in debug mode.

move
void move(T source, T target)

Phobos move, but always by destructive copy when in debug mode.

opCmp
int opCmp(T a, T b)

Free-function version of opCmp +for generic code.

+ +
+ + + \ No newline at end of file diff --git a/docs/eris.core.move.1.html b/docs/eris.core.move.1.html new file mode 100644 index 0000000..a6f9665 --- /dev/null +++ b/docs/eris.core.move.1.html @@ -0,0 +1,42 @@ + + + + move (eris.core.move) + + + + + + + + + + +
+
+

move

Phobos move, but always by destructive copy when in debug mode.

Performs the same operations as core.lifetime.move, but when in debug mode the +moved source is always set to its .init value, which is easier to check (e.g. +null for pointers) when looking for referential integrity bugs.

  1. void move(T source, T target)
    void
    move
    (
    T
    )
    (
    ref T source
    ,
    ref T target
    )
  2. T move(T source)

Examples

int x = 1;
+int* p = &x;
+int* q = null;
+move(p, q);
+assert(q == &x);
+debug assert(p == null); // only in debug mode!
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.core.move.2.html b/docs/eris.core.move.2.html new file mode 100644 index 0000000..c71cc7c --- /dev/null +++ b/docs/eris.core.move.2.html @@ -0,0 +1,42 @@ + + + + move (eris.core.move) + + + + + + + + + + +
+
+

move

Phobos move, but always by destructive copy when in debug mode.

Performs the same operations as core.lifetime.move, but when in debug mode the +moved source is always set to its .init value, which is easier to check (e.g. +null for pointers) when looking for referential integrity bugs.

  1. void move(T source, T target)
  2. T move(T source)
    T
    move
    (
    T
    )
    (
    ref T source
    )

Examples

int x = 1;
+int* p = &x;
+int* q = null;
+move(p, q);
+assert(q == &x);
+debug assert(p == null); // only in debug mode!
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.core.move.html b/docs/eris.core.move.html new file mode 100644 index 0000000..0c5d1ac --- /dev/null +++ b/docs/eris.core.move.html @@ -0,0 +1 @@ + Continue to overload \ No newline at end of file diff --git a/docs/eris.core.opCmp.html b/docs/eris.core.opCmp.html new file mode 100644 index 0000000..50d7c53 --- /dev/null +++ b/docs/eris.core.opCmp.html @@ -0,0 +1,44 @@ + + + + opCmp (eris.core.opCmp) + + + + + + + + + + +
+
+

opCmp

Free-function version of opCmp +for generic code.

Can be used to efficiently compare both complex types with a custom opCmp, or primitive types.

int
opCmp
(
T
)
(
in T a
,
in T b
)

Examples

import std.meta : AliasSeq;
+static foreach (Scalar; AliasSeq!(char, ubyte, int, size_t, float, double)) {{
+	const Scalar two = 2;
+	const Scalar three = 3;
+	assert( opCmp(two, three)  < 0 );
+	assert( opCmp(three, two)  > 0 );
+	assert( opCmp(two, two)   == 0 );
+	assert( opCmp(two, three) != 0 );
+}}
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.html b/docs/eris.html new file mode 100644 index 0000000..86d4cda --- /dev/null +++ b/docs/eris.html @@ -0,0 +1,51 @@ + + + + eris (eris) + + + + + + + + + + +
+
+

eris

A non-standard library for DasBetterC.

This is the library I wish I had when I started using D as a better alternative and complement to C.

Modules

allocator
module eris.allocator

Custom memory allocators and related helpers.

array
module eris.array

In-place manipulation of slices.

btree
module eris.btree

Generic B-tree data structure.

core
module eris.core

Core type definitions, templates and helper procedures.

math
module eris.math

Miscellaneous numeric math.

Public Imports

eris.core
public +import eris.core;
Undocumented in source.
eris.array
public +import eris.array;
Undocumented in source.
eris.math
public +import eris.math;
Undocumented in source.
eris.allocator
public +import eris.allocator;
Undocumented in source.
eris.btree
public +import eris.btree;
Undocumented in source.

Detailed Description

Goals

The following list ranks the goals of this project, in order of importance:

  1. Maintain compatibility with -betterC mode and/or[1] nothrow @nogc.
  2. Maintain portability across mainstream platforms (x86-64 for desktop, ARM for mobile and WASM for the web).
  3. Provide good documentation for all publicly exposed functionality.
  4. Provide fast single-threaded implementations of certain ADTs and algorithms.

Rationale for the first point is that it allows C developers to use D-generated code in their apps and libraries, +even if that may require some explicit template instantations, manual symbol mangling directives and extern(C). +The other goals constitute reasons for wanting to use this library in C or D codebases in the first place.

+ [1] BetterC mode works best with LDC. + In fact, using -betterC with DMD often leads to impossible-to-debug linker errors. + Therefore, betterC compatibility is only tested against LDC. + Still, @nogc and nothrow should apply for all compilers.

Dependencies

Since I still value my time and sanity, I gave up on trying to partition this library into DUB subpackages. +So, if you want to use any particular module here without the rest of the project, +just make sure you carry its dependency subtree along with it. +Here's a dependency graph (forest) to help with that.

intra-package dependencies

Note

  • D interfaces showing up in the docs are only there to document static interfaces; + this is a betterC library and procedures assume all containers are structs, + so classes probably won't work in most cases.
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.count.html b/docs/eris.math.Accumulator.count.html new file mode 100644 index 0000000..5f40523 --- /dev/null +++ b/docs/eris.math.Accumulator.count.html @@ -0,0 +1,35 @@ + + + + Accumulator.count (eris.math.Accumulator.count) + + + + + + + + + + +
+
+

Accumulator.count

Number of accumulated values.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
size_t
count
()
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.html b/docs/eris.math.Accumulator.html new file mode 100644 index 0000000..120d272 --- /dev/null +++ b/docs/eris.math.Accumulator.html @@ -0,0 +1,55 @@ + + + + Accumulator (eris.math.Accumulator) + + + + + + + + + + +
+
+

Accumulator

Tracks a stream of values and computes some statistics in constant space.

Members

Aliases

put
alias put = opOpAssign!"+"

Accumulate a given (non-NaN) value.

Functions

opOpAssign
void opOpAssign(double x)

Accumulate a given (non-NaN) value.

Properties

count
size_t count [@property getter]

Number of accumulated values.

max
double max [@property getter]

Biggest accumulated value.

mean
double mean [@property getter]

Average accumulated value.

min
double min [@property getter]

Smallest accumulated value.

standardDeviation
double standardDeviation [@property getter]

Population standard deviation.

std
double std [@property getter]

Sample standard deviation.

var
double var [@property getter]

Sample variance.

variance
double variance [@property getter]

Population variance.

Examples

import std.range.primitives : put, isOutputRange;
+import std.math.operations : isClose;
+
+Accumulator small, big;
+static assert(isOutputRange!(Accumulator, double));
+
+static const double[] smallNumbers = [ 4, 7, 13, 16 ];
+put(small, smallNumbers);
+
+static const double[] bigNumbers = [ // same as smallnumbers + 1e9
+	1.000000004e9, 1.000000007e9, 1.000000013e9, 1.000000016e9 ];
+put(big, bigNumbers);
+
+assert(isClose(small.count,             big.count            ));
+assert(isClose(small.min  + 1e9,        big.min              ));
+assert(isClose(small.max  + 1e9,        big.max              ));
+assert(isClose(small.mean + 1e9,        big.mean             ));
+assert(isClose(small.var,               big.var              ));
+assert(isClose(small.variance,          big.variance         ));
+assert(isClose(small.std,               big.std              ));
+assert(isClose(small.standardDeviation, big.standardDeviation));
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.max.html b/docs/eris.math.Accumulator.max.html new file mode 100644 index 0000000..0c27841 --- /dev/null +++ b/docs/eris.math.Accumulator.max.html @@ -0,0 +1,35 @@ + + + + Accumulator.max (eris.math.Accumulator.max) + + + + + + + + + + +
+
+

Accumulator.max

Biggest accumulated value.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
max
()
in (count > 0)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.mean.html b/docs/eris.math.Accumulator.mean.html new file mode 100644 index 0000000..356ad2b --- /dev/null +++ b/docs/eris.math.Accumulator.mean.html @@ -0,0 +1,35 @@ + + + + Accumulator.mean (eris.math.Accumulator.mean) + + + + + + + + + + +
+
+

Accumulator.mean

Average accumulated value.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
mean
()
in (count > 0)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.min.html b/docs/eris.math.Accumulator.min.html new file mode 100644 index 0000000..559e58f --- /dev/null +++ b/docs/eris.math.Accumulator.min.html @@ -0,0 +1,35 @@ + + + + Accumulator.min (eris.math.Accumulator.min) + + + + + + + + + + +
+
+

Accumulator.min

Smallest accumulated value.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
min
()
in (count > 0)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.opOpAssign.html b/docs/eris.math.Accumulator.opOpAssign.html new file mode 100644 index 0000000..bc846c2 --- /dev/null +++ b/docs/eris.math.Accumulator.opOpAssign.html @@ -0,0 +1,35 @@ + + + + Accumulator.opOpAssign (eris.math.Accumulator.opOpAssign) + + + + + + + + + + +
+
+

Accumulator.opOpAssign

Accumulate a given (non-NaN) value.

struct Accumulator
pragma(inline) nothrow @nogc pure
void
opOpAssign
(
string op : "+"
)
(
double x
)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.put.html b/docs/eris.math.Accumulator.put.html new file mode 100644 index 0000000..23c02ea --- /dev/null +++ b/docs/eris.math.Accumulator.put.html @@ -0,0 +1,35 @@ + + + + Accumulator.put (eris.math.Accumulator.put) + + + + + + + + + + +
+
+

Accumulator.put

Accumulate a given (non-NaN) value.

struct Accumulator
pragma(inline) nothrow @nogc pure
alias put = opOpAssign!"+"
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.standardDeviation.html b/docs/eris.math.Accumulator.standardDeviation.html new file mode 100644 index 0000000..4d5e8f5 --- /dev/null +++ b/docs/eris.math.Accumulator.standardDeviation.html @@ -0,0 +1,35 @@ + + + + Accumulator.standardDeviation (eris.math.Accumulator.standardDeviation) + + + + + + + + + + +
+
+

Accumulator.standardDeviation

Population standard deviation.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
standardDeviation
()
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.std.html b/docs/eris.math.Accumulator.std.html new file mode 100644 index 0000000..2191006 --- /dev/null +++ b/docs/eris.math.Accumulator.std.html @@ -0,0 +1,35 @@ + + + + Accumulator.std (eris.math.Accumulator.std) + + + + + + + + + + +
+
+

Accumulator.std

Sample standard deviation.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
std
()
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.var.html b/docs/eris.math.Accumulator.var.html new file mode 100644 index 0000000..55e5e4a --- /dev/null +++ b/docs/eris.math.Accumulator.var.html @@ -0,0 +1,35 @@ + + + + Accumulator.var (eris.math.Accumulator.var) + + + + + + + + + + +
+
+

Accumulator.var

Sample variance.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
var
()
in (count > 1)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.Accumulator.variance.html b/docs/eris.math.Accumulator.variance.html new file mode 100644 index 0000000..5bd6fab --- /dev/null +++ b/docs/eris.math.Accumulator.variance.html @@ -0,0 +1,35 @@ + + + + Accumulator.variance (eris.math.Accumulator.variance) + + + + + + + + + + +
+
+

Accumulator.variance

Population variance.

struct Accumulator
pragma(inline) nothrow @nogc pure @property const
double
variance
()
in (count > 0)
+ +
+ + + \ No newline at end of file diff --git a/docs/eris.math.html b/docs/eris.math.html new file mode 100644 index 0000000..1011a52 --- /dev/null +++ b/docs/eris.math.html @@ -0,0 +1,35 @@ + + + + eris.math (eris.math) + + + + + + + + + + +
+
+

eris.math

Miscellaneous numeric math.

Members

Structs

Accumulator
struct Accumulator

Tracks a stream of values and computes some statistics in constant space.

+ +
+ + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..35aec27 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,35 @@ + + + + index (index) + + + + + + + + + + +
+
+

index

Modules

eris
module eris

A non-standard library for DasBetterC.

+ +
+ + + \ No newline at end of file diff --git a/docs/script.js b/docs/script.js new file mode 100644 index 0000000..b47257e --- /dev/null +++ b/docs/script.js @@ -0,0 +1,180 @@ +window.addEventListener("load", function() { + + var lineWrappers = document.querySelectorAll(".with-line-wrappers"); + for(var i = 0; i < lineWrappers.length; i++) { + var l = lineWrappers[i]; + + var codeblock = document.createElement("div"); + codeblock.className = "codeblock"; + l.parentNode.insertBefore(codeblock, l); + + var header = document.createElement("header"); + codeblock.appendChild(header); + codeblock.appendChild(l); + + var btn = document.createElement("button"); + btn.setAttribute("type", "button"); + var canCopyToClipboard = document.queryCommandSupported("copy"); + btn.addEventListener("click", (function(l) { return function() { + document.body.classList.add("hide-line-numbers"); + window.getSelection().selectAllChildren(l); + if(canCopyToClipboard) + if(!document.execCommand("copy")) { + alert("copy failed, try ctrl+c manually"); + } + };})(l)); + btn.textContent = canCopyToClipboard ? "Copy to Clipboard" : "Select All"; + header.appendChild(btn); + + var btn = document.createElement("button"); + btn.setAttribute("type", "button"); + btn.addEventListener("click", function() { + document.body.classList.toggle("hide-line-numbers"); + }); + btn.textContent = "Toggle Line Numbers"; + header.appendChild(btn); + } + + /* // still sucks in firefox! + document.addEventListener("copy", function(event) { + document.body.classList.add("hide-line-numbers"); + }); + */ + + document.body.addEventListener("mouseover", function(event) { + if(event.target.hasAttribute("data-ident")) { + var all = document.querySelectorAll("[data-ident=\""+event.target.getAttribute("data-ident")+"\"]"); + for(var i = 0; i < all.length; i++) + all[i].className += " active"; + } + }); + document.body.addEventListener("mouseout", function(event) { + if(event.target.hasAttribute("data-ident")) { + var all = document.querySelectorAll("[data-ident=\""+event.target.getAttribute("data-ident")+"\"]"); + for(var i = 0; i < all.length; i++) + all[i].className = all[i].className.replace(" active", ""); + } + }); + /* + document.body.addEventListener("dblclick", function(event) { + if(event.target.hasAttribute("data-ident")) { + location.href = "/" + event.target.getAttribute("data-ident"); + } + }); + */ + + var sn = document.getElementById("source-navigation"); + if(sn) { + sn.addEventListener("click", function(event) { + if(event.target.tagName != "A" || event.target.className == "docs") + return true; + if(event.target.nextSibling) { + var s = event.target.nextSibling; + if(s.style.display == "" || s.style.display == "none" || s.className.indexOf("search-hit") != -1) { + s.style.display = "block"; + var items = s.getElementsByTagName("ul"); + var i; + for(i = 0; i < items.length; i++) + items[i].style.display = ""; + items = s.getElementsByTagName("li"); + for(i = 0; i < items.length; i++) + items[i].style.display = ""; + } else + s.style.display = ""; + } + + //var id = event.target.href.substring(event.target.href.indexOf("#") + 1); + //sn.style.marginTop = (document.getElementById(id).offsetTop - event.target.offsetTop + 16) + "px"; + }); + + var search = document.createElement("input"); + search.setAttribute("type", "search"); + function searchHelper() { + var regex = new RegExp(search.value, "i"); + var items = document.querySelectorAll("#source-navigation a[href^=\"#\"]"); + var stxt = search.value; + for(var i = 0; i < items.length; i++) { + var a = items[i]; + if(stxt.length && regex.test(a.textContent)) { + var p = a.parentNode; + while(p.tagName != "DIV") { + if(p.tagName == "LI") + p.style.display = "list-item"; + else + p.style.display = "block"; + p.className += " search-hit"; + p = p.parentNode; + } + } else { + var p = a.parentNode; + if(stxt.length == 0) { + p.style.display = ""; + while(p.tagName != "DIV") { + p.style.display = ""; + p = p.parentNode; + } + } else + p.style.display = "none"; + p.className = p.className.replace(" search-hit", ""); + } + } + } + search.addEventListener("keyup", searchHelper); + sn.insertBefore(search, sn.firstChild); + } + + /* + function updateDynamicStyle() { + var thing = document.getElementById("page-content"); + var newStyle = document.getElementById("dynamic-style"); + if(!newStyle) { + newStyle = document.createElement("style"); + newStyle.setAttribute("id", "dynamic-style"); + newStyle.type = "text/css"; + document.head.appendChild(newStyle); + } + + var maxContentWidth = window.innerWidth; + // 800 is the threshold for putting nav vertically + if(maxContentWidth < 800) + maxContentWidth = 800; + else + maxContentWidth = + document.body.offsetWidth - + document.getElementById("page-nav").offsetWidth - + document.getElementById("page-nav").offsetLeft - + 64; + + // sanity check lol + if(maxContentWidth < 800) + maxContentWidth = 800; + + newStyle.innerHTML = ".member-list:not(.constructors) dt .simplified-prototype:hover { width: " + (thing.offsetWidth - 32) + "px; } #page-content pre.d_code, #page-content .overload-option, #page-content .member-list dt { max-width: " + (maxContentWidth) + "px; }"; + } + + updateDynamicStyle(); + + window.onresize = updateDynamicStyle; + */ + + // Disable line numbers in IE because the copy/paste with them sucks - it includes all line numbers + // in the middle making it too hard to use. Copy/paste is more important than line displays. + if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) { + var items = document.querySelectorAll(".with-line-wrappers"); + for(var a = 0; a < items.length; a++) + items[a].className = items[a].className.replace("with-line-wrappers", ""); + } + + // Keybind to focus search bar on '?' keydown. + document.addEventListener("keydown", (event) => { + if (event.key == "?") { + var searchBox = document.getElementsByName("searchTerm")[0]; + // Hack so the '?' doesn't auto-populate in the search bar. + this.setTimeout(() => { + searchBox.focus(); + }, 100); + } + }); + + +}); diff --git a/docs/search-docs.html b/docs/search-docs.html new file mode 100644 index 0000000..522aab4 --- /dev/null +++ b/docs/search-docs.html @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/docs/search-docs.js b/docs/search-docs.js new file mode 100644 index 0000000..09687d7 --- /dev/null +++ b/docs/search-docs.js @@ -0,0 +1,393 @@ +/* + This is the source for offline web search; it will be embedded + in a generated search page along with the search index xml. + + You will almost certainly want to gzip this when delivering it! + Also be sure it has the proper cache headers to give a remotely + acceptable performance result. Configure the web server to do + both these. When storing it for offline usage, you might just + leave it unzipped though for convenience of use without a web server. + + Tip to the end user: you might want to open this page and keep it + open in a reused tab. + + The file generated should be the skeleton.html with the search + index in a + + + + + + +
+
+
+ +
+ + + + + diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000..3ac7262 --- /dev/null +++ b/docs/style.css @@ -0,0 +1,1592 @@ +/* a few things you can change to pick a basic color scheme */ + +/* + FIXME: have some automatic magic for choosing light vs dark and picking an accent color. + + Ideally, we'll get to the point where you can just say: + project name + project logo + project links + + light/dark scheme + project color + + and it will adapt the rest to a good-enough state automatically. +*/ + +#page-header, +#suggestion-box { + background-color: rgb(49, 57, 176); + background-color: rgb(49, 110, 47); + background-color: rgb(176, 57, 49); +} + +#page-header, +#suggestion-box, +#page-footer, +#page-nav { + border-color: rgb(41, 48, 148); + border-color: rgb(41, 110, 48); + border-color: rgb(148, 48, 41); + border-color: rgb(204, 204, 204); +} + +#page-nav { + background-color: rgb(245, 245, 255); + background-color: rgb(245, 250, 245); + background-color: rgb(245, 245, 245); + +} + +a:link { + color: #0000ff; + color: #bb0000; +} + +a:visited { + color: #004488; + color: #bb0044; +} + +/* for the dlang.org website font thing */ + +@font-face { + font-family: "Roboto Slab"; + font-weight: normal; + src: url("RobotoSlab-Regular.ttf"); +} +@font-face { + font-family: "Roboto Slab"; + font-weight: bold; + src: url("RobotoSlab-Bold.ttf"); +} + +body { + font-family: "Roboto Slab", sans-serif; + tab-size: 4; +} + +h1, #page-nav a, .quickindex a.xref, .breadcrumb, dt > a { + font-family: Consolas, "Bitstream Vera Sans Mono", "Andale Mono", Monaco, "DejaVu Sans Mono", "Lucida Console", monospace; +} + + +/* done with basic colors */ + +html { + font-size: 100%; +} + +h1 { + font-size: 2.2rem; +} + +h2 { + font-size: 1.6rem; + margin-top: 1.5em; + font-family: "Roboto Slab", sans-serif; + font-weight: normal; +} + +h3 { + font-size: 1.26rem; +} + +body { + /*font-family: sans-serif;*/ + color: #111; + background-color: white; +} + +.big-o { + white-space: nowrap; +} + +.member-list .dt, +.overload-option, +pre { + box-sizing: border-box; + overflow: auto; + max-width: 800px; /* The script sets the real one */ + max-width: calc(80vw - 16em - 4em); +} + + +#page-header { + height: 32px; + line-height: 32px; + margin-bottom: 6px; + border-bottom-width: 1px; + border-bottom-style: solid; + color: white; + margin: -0.5em; + padding: 0em 0.5em; + margin-bottom: 0.0em; + overflow: hidden; +} + +#page-header span { + vertical-align: top; +} + +#page-header #logotype { + float: left; +} + +#page-header #search { + float: right; +} + +#page-header nav { + display: inline-block; + margin-left: 2em; + vertical-align: top; +} + +#page-header nav a { + display: inline-block; + color: white; + font-weight: bold; + margin-right: 2em; +} + +#page-body { + clear: both; + margin: 0px auto; + max-width: 1200px; + min-height: 800px; + min-height: calc(100vh - 3em - 32px); + display: flex; + box-sizing: border-box; +} + +#page-body #page-nav { + flex: 0 0 16em; + width: 16em; + min-width: 16em; + max-width: 16em; + order: 1; + padding-top: 0.25em; + padding-left: 1em; + padding-right: 0px; + min-height: 800px; + min-height: calc(100vh - 3em - 32px); + + border-right-style: solid; + border-right-width: 1px; + border-left-style: solid; + border-left-width: 1px; + box-sizing: border-box; +} + +#page-body #page-content { + flex: 1 1 auto; + order: 2; + padding: 0.25em; + padding-left: 1.75em; + box-sizing: border-box; + max-width: 960px; +} + +@media all and (max-width: 800px) { + #page-body { + display: block; + min-height: 0px; + } + + #page-body #page-nav { + display: block; + width: auto; + max-width: 800px; + border-top-style: solid; + border-top-width: 1px; + border-right: none; + min-height: 0px; + } + + #page-body #page-content { + padding-left: 0.25em; + } + + .member-list .dt, + .overload-option, + pre { + box-sizing: border-box; + overflow: auto; + max-width: 800px; /* The script sets the real one */ + max-width: calc(100vw - 2em); + } + + #page-header { + line-height: 20px; + height: auto; + min-height: 32px; + overflow: visible; + } + #page-header::after { + content: ' '; + display: block; + clear: both; + } +} + +#page-footer { + margin-top: 0em; + padding-top: 2em; + color: #999; + font-size: 0.9rem; + text-align: center; + border-top-style: solid; + border-top-width: 1px; +} + +a:link { + text-decoration: none; +} + +a:link:hover { + text-decoration: underline !important; /* important so it overrides even id level things on non-hover */ +} + +/* +pre.d_code { background-color: #fdf6e3; color: #002b36; padding: 0.25em; border: solid 1px #ccc; } +.d_code .kwrd { color: #b58900; font-weight: bold; } +.d_code .com { color: #666; font-style: italic; } +.d_code .num { color: #dc322f; font-weight: normal; } +.d_code .str { color: #2aa198; font-style: italic; } +.d_code .op { color: #586e75; font-weight: bold; } +.d_code .type { color: #268bd2; font-weight: bold; } +.d_code .cons { color: #859900; font-weight: bold; } + +.highlighted .kwrd { color: #b58900; font-weight: bold; } +.highlighted .com { color: #666; font-style: italic; } /* #93a1a1; * / +.highlighted .num { color: #dc322f; font-weight: normal; } +.highlighted .str { color: #2aa198; font-style: italic; } +.highlighted .op { color: #586e75; font-weight: bold; } +.highlighted .type { color: #268bd2; font-weight: bold; } +.highlighted .cons { color: #859900; font-weight: bold; } +*/ + +/* .member-list p, */ +#table-of-contents, +.enum-members, +.documentation-comment .tip, +.documentation-comment .note, +.documentation-comment .warning, +.documentation-comment .pitfall, +.documentation-comment li, +.documentation-comment p { + /* white-space: pre-line; */ + /* max-width: 74ch; */ + /*font-size: 1.1rem;*/ + font-size: 1.0rem; + line-height: 1.5; +} + +/* +.parameter-item::after { + content: ','; +} + +.parameter-item:last-child::after { + content: ''; +} +*/ + +.aggregate-declaration { + margin: 1em; +} + +.aggregate-member { + padding-left: 2em; +} + +/* +.aggregate-member::after { + content: ";"; +} +*/ + +.aggregate-member > a { + color: inherit; +} + +.template-constraint-expression, +.parameter-item { + padding-left: 2em; +} + + +/* +ol.overloads { + margin-bottom: -1px; + white-space: nowrap; +} + +ol.overloads::before { + content: "Overloads: "; +} + +ol.overloads li { + display: inline-block; + border: solid 1px #ccc; + list-style-position: inside; + text-align: center; + width: 5em; +} + +ol.overloads li.overload-option { + background-color: #eee; +} + +ol.overloads li a { + display: block; +} + +ol.overloads li.active-overload-option { + border-bottom: solid 1px white; +} + +ol.overloads + .aggregate-prototype, +ol.overloads + .function-prototype { + margin-top: 0px; +} +*/ + +.aggregate-prototype #help-link, +.function-prototype #help-link { + border-radius: 100%; + position: absolute; + top: -0.5em; + right: -0.5em; + display: block; + border: solid 1px #ccc; + background-color: white; + width: 1em; + height: 1em; + text-align: center; + font-size: 1.1rem; + padding-bottom: 3px; +} + +.aggregate-prototype #help-link:hover, +.function-prototype #help-link:hover { + text-decoration: none; + background-color: #ccc; +} + +.function-prototype .attributes { + color: #666; +} + +.declaration-prototype, +.aggregate-prototype, +.function-prototype { + border: solid 1px #ccc; + padding: 2em; + margin: 1em; + font-family: monospace; + position: relative; +} + +.declaration-prototype { + padding: 3em 2em; +} + +.parameters-list:empty { + display: none; +} + +/* +.parameters-list .parameters-list { + display: inline; +} +*/ + +.toplevel.parameters-list { + display: table; +} + +.toplevel.parameters-list > .parameter-item { + display: table-row; +} + +.toplevel.parameters-list > .parameter-item > *:first-child { + padding-left: 2em !important; +} + +.toplevel.parameters-list > .parameter-item + .comma { + display: none; +} + +.toplevel.parameters-list > .parameter-item > *:last-child::after { + content: ","; +} +.toplevel.parameters-list > .parameter-item:last-of-type > *:last-child::after { + content: ""; +} + +.parameter-attribute { + padding-left: 1em; +} + +.toplevel.parameters-list > .parameter-item .parameter-type-holder, +.toplevel.parameters-list > .parameter-item .parameter-name, +.toplevel.parameters-list > .parameter-item .parameter-default-value { + display: table-cell; + padding: 0px 0.25em; +} + +.toplevel.parameters-list > .parameter-item:hover { + background-color: #f8f8f8; +} + +.parameter-descriptions .parameter-name { + margin-right: 1.5rem; + font-weight: bold; + padding: 0.25ex 0.75ex; +} + +.parameter-descriptions dd { + margin-left: 1.5em; +} + +.parameter-descriptions dd p:first-child { + margin-top: 0.5em; +} + +.parameter-descriptions dt:not(:first-child) { + margin-top: 1.5em; +} + +.codeblock { + border: solid 1px #ccc; + padding: 0; + margin: 0; +} + +.codeblock header { + background-color: #e8e8e8; + padding: 0; + display: flex; + justify-content: flex-end; +} + +.codeblock header:before { + display: inline-block; + content: "Example"; + justify-content: flex-start; + flex-grow: 1; + padding: 0.25em 1em; + font-weight: bold; +} + +.codeblock header button { +/* TODO: add :before class with icons here (copy, line numbers) */ + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + margin: 0; + padding: 0 1em; + background-color: transparent; + border: none; + border-left: 1px solid #ccc; + cursor: pointer; +} + +.codeblock header button:hover { + background-color: rgba(255, 255, 255, 0.5); +} + +.codeblock header + pre { + border: none; + border-top: solid 1px #ccc; + margin: 0; + padding: 1em 0; + max-width: unset !important;; +} + +.hide-line-numbers .codeblock .with-line-wrappers, +.codeblock pre.d_code:not(.with-line-wrappers) { + padding: 1em; +} + +.codeblock .with-line-wrappers .br { + margin-right: 1em; +} + +.documentation-comment p { + hyphens: auto; +} + +.declaration-prototype, .aggregate-prototype, .function-prototype { + margin-left: 0; + margin-right: 0; +} + + + +tt.D, .inline-code { + color: black; + font-weight: 500; + background-color: #f2f2f2; + padding: 0px 0.5ex; + border-radius: 2px; +} + + +/* +.toplevel.parameters-list > .parameter-item > .parameter-type-holder { + text-align: right; +} + +.toplevel.parameters-list > .parameter-item > .parameter-type-holder > .parameter-type { + text-align: left; + display: inline-block; +} +*/ + +.function-prototype .return-type, .function-prototype .function-name { + display: inline; +} + +.function-name::before { + content: ' '; +} + +.function-name { + /*color: #008888;*/ +} + +.template-parameters[data-count="0"], +.template-parameters[data-count="0"] ~ .runtime-parameters[data-count="0"], +.template-parameters[data-count="0"] ~ .runtime-parameters[data-count="0"] > .parameters-list { + display: inline; +} + +.parameters-list:empty { + display: inline; +} + +.type-constructor, +.builtin-type { + text-decoration: none; + color: #004400 !important; + /*color: green !important; + font-weight: bold;*/ +} + +.kwrd, +.highlighted-keyword, +.lang-feature, +.storage-class { + text-decoration: none; + color: #026 !important; +} + +[data-ident].active { + outline: solid 1px red; +} + +table.enum-members { + border-collapse: collapse; + border: solid 1px #ccc; + min-width: 60%; +} + +.enum-members th, +.enum-members td { + border: solid 1px #ccc; + margin: 0px; + padding: 0.25em 0.5em; +} + +.enum-members th { + text-align: left; + color: #888; +} + +.enum-members td { + vertical-align: top; +} + +.enum-members td p:first-child { + margin-top: 0px; +} + +.enum-members .enum-member-name { + font-weight: bold; + color: inherit; +} + +.enum-members .enum-member-value { + display: block; + color: #666; +} + +.enum-members .enum-disabled { + font-style: italic; +} + +.enum-members .enum-deprecated { + margin-bottom: 1em; +} + +.enum-members .enum-deprecated > span.deprecated-label { + color: red; +} + +.enum-members .enum-attributes { + margin-top: 1em; +} + +.enum-member .enum-attributes:empty { + display: none; +} + +.enum-members tr.enum-member > td:nth-child(2) > div:only-child:empty:before { + display: inline; + content: "undocumented"; + color: rgba(0, 0, 0, 0.4); + font-style: italic; +} + +*:target { + background: #ffffbb; +} + +.breadcrumbs { + margin: 1em; +} + +.breadcrumbs a::before { + content: ' \00bb\a0'; +} + +.parameter-name { + font-weight: bold; +} + +.symbol-reference, +.return-type, +.parameter-type { + font-family: monospace; +} + +.phobos-booktable { + border-collapse: collapse; + margin-bottom: 1.5em; +} + +.phobos-booktable tt.D { + font-weight: bold; + background-color: transparent; +} + +.phobos-booktable caption { + text-align: left; +} + +.phobos-booktable tr { + border-bottom: solid 1px #ccc; +} + +.phobos-booktable tr:hover { + background-color: #fafafa; +} + +.phobos-booktable { + border-top: solid 2px black; + border-bottom: solid 2px black; +} + +.phobos-booktable tr:first-child:has(th) { + border-bottom: solid 1px black; +} + +.phobos-booktable th { + text-align: left; + padding-top: 0.3em; + padding-bottom: 0.3em; +} + +.phobos-booktable td:first-child { + padding-top: 0.3em; + padding-bottom: 0.3em; + padding-right: 1em; +} + +.phobos-booktable td:not(:last-child), +.phobos-booktable th:not(:last-child) { + padding-right: 1em; +} + +.quickindex .phobos-booktable td:last-child a { + padding-right: 1.2em; +} + +.current.breadcrumb { + color: inherit; + text-decoration: none; +} + +.andand-right { + display: inline; +} + +.oror-right { + display: inline; +} + +.parenthetical-expression > .parenthetical-expression-contents > .andand-left, +.parenthetical-expression > .parenthetical-expression-contents > .oror-left { + display: inline; +} + +/* +.parenthetical-expression > .parenthetical-expression-contents > .oror-left:first-child { + display: block; +} +*/ + + +.template-constraint-expression .parenthetical-expression { + display: block; + margin-left: 1em; +} + +.oror-left > .andand-left, +.oror-left > .andand-right { + display: inline; +} + +.aggregate-members:empty::after { + content: "This aggregate has no documented members available."; +} + +h1 .entity-name { + font-family: monospace; +} + +.other-section h3 { + font-size: 1rem; + margin-bottom: 0.25em; +} + +.other-section h3 + p { + margin-top: 0.25em; +} + +.function-prototype .in-contract, +.function-prototype .out-contract { + white-space: pre; +} + +.note { + margin: 1em; + padding: 0.5em; + background-color: #f0f0ff; + border: solid 1px #ccc; + clear: both; +} + +/* +.note::before { + color: #000066; + font-weight: bold; + content: "Note: "; +} +*/ + +.warning { + margin: 1em; + padding: 0.5em; + background-color: #fffff0; + border: solid 1px #ccc; + clear: both; +} + +.pitfall { + margin: 1em; + padding: 0.5em; + background-color: #fff0f0; + border: solid 1px #ccc; + clear: both; +} + +.tip { + margin: 1em; + padding: 0.5em; + background-color: #f0fff0; + border: solid 1px #ccc; + clear: both; +} + +.sidebar { + float: right; + margin: 1em; + margin-top: 2px; + padding: 0.25em; + background: #f3f3f3; + border: solid 1px #ccc; + width: 20%; + min-width: 30ch; + clear: right; +} + +h2 { + clear: both; +} + +.sidebar > *:first-child { + margin-top: 0px; +} + +/* I want to clear floats. This leaves a gap about the size of a blank line + too, but that doesn't bother me (actually, I kinda like a small gap at the + bottom. */ +#page-content::after { + clear: both; + content: '\a0'; + display: block; +} + +tt.D, +.inline-code { + color: black; + font-weight: 500; + background-color: #f2f2f2; + padding: 0px 0.125em; +} + +#page-nav .type-separator { + text-transform: capitalize; + display: block; + border-bottom: solid 1px #ccc; + margin-top: 1em; + margin-bottom: 0.25em; +} + +#page-nav a { + display: block; + box-sizing: border-box; + padding: 1px 0.25em 1px 0.5em; + text-overflow: ellipsis; + overflow: hidden; + font-family: "Roboto Slab", sans-serif; +} + +#page-nav a:hover { + position: relative; + overflow: visible; + z-index: 10; + background-color: rgb(245, 245, 245); + width: max-content; +} + +#page-nav a.parent { + font-weight: bold; + font-size: 1.1rem; + line-height: 0.9; + overflow: visible; +} + +#page-nav a.parent:first-child { + margin-top: 0.75em; +} + +#page-nav a.parent + a.parent::before { + content: "."; +} + +#page-nav a.current { + font-weight: bold; + color: inherit; +} + +pre[data-language=console], +pre.console { + background-color: #222; + color: #eee; + padding: 0.5em; + border: solid 1px #ccc; +} + +#more-link { + display: block; + font-weight: bold; + font-size: 1.1rem; + color: blue; +} + +.member-list dd + dt { + border-top: solid 1px #ccc; + padding-top: 0.5em; + margin-top: 0.5em; +} + +/* +.member-list dd { + max-height: 4em; + overflow: hidden; + text-overflow: ellipsis; +} +*/ + +.member-list dt a { + overflow: hidden; + text-overflow: ellipsis; +} + +.member-list dt .simplified-prototype { + font-family: monospace; + font-size: 90%; + color: #333; + white-space: nowrap; + text-overflow: ellipsis; + text-overflow: '[...]'; /* only Firefox supports this but i like it */ + overflow: hidden; + border: solid 1px white; +} + +.member-list dt .simplified-prototype:hover { + background-color: white; + position: relative; + z-index: 5; + width: 800px; + width: calc(100vw - 16em); + border: solid 1px #eee; + box-shadow: 1px 1px 1px #ccc; +} + +@media screen and (min-width: 640px) { + .member-list dt { + float: left; + clear: left; + width: 20em; + box-sizing: border-box; + padding-right: 1em; + } + + .member-list dd, + .member-list dd + dt { + border-top: solid 1px #ccc; + padding-top: 0.5em; + margin-top: 0em; + } + + .member-list dd p:first-child { + margin-top: 0px; + } + + .member-list dd:first-of-type { + border-top: none; + padding-top: 0px; + } + + .member-list dd { + margin: 0px; + margin-left: 20em; + } + + .member-list dd::after { + content: '\a0'; + height: 0.5em; + clear: both; + display: block; + } +} + +.member-list.articles dt, +.member-list.constructors dt { + float: none; + clear: none; + margin: 0em; + width: auto; + border: none; +} + +.member-list.articles dd, +.member-list.constructors dd { + float: none; + clear: none; + margin: 1em 0em; + width: auto; + border: none; +} + +.member-list.articles dd, +.member-list.constructors dd { + padding-left: 2em; +} + +.member-list dt a { + display: block; +} + +#suggestion-box { + display: inline-block; + color: white; + font-weight: bold; + border: solid 2px black; + border-radius: 8px 8px 0px 0px; + position: fixed; + left: 1em; + bottom: 0em; + padding: 0.25em 0.5em; +} + +.synopsis { + margin: 2em 0px; +} + +/* If it was successfully looked up in an xref, no need to highlight anymore */ +a.xref:link span[data-ident].active { + border: none; +} + +#table-of-contents { + border: solid 1px #ccc; + margin: 1em; + padding: 1em; + padding-left: 0em; /* the list inside can handle this */ +} + +.parent-prototype { + font-size: 0.9rem; + padding-bottom: 1em; +} + +.parent-prototype::after { + content: " {"; +} + +.parent-prototype + div { + padding-left: 1em; +} + +.parent-prototype + div::after { + content: "}"; + display: block; + font-size: 0.9rem; + padding-top: 1em; + margin-left: -1.33em; /* 1/(3/4) */ +} + +.search-result::after { + content: '(Search Score: ' attr(data-score) ')'; + font-size: 0.9rem; +} + +table.std_math { + min-width: 25%; + border: solid 1px black; + border-collapse: collapse; + margin: 2em; +} + +table.std_math td, table.std_math th { + border: solid 1px #ccc; + text-align: left; + padding: 0.25em; +} + +table.std_math.special-values th { + border-bottom: solid 2px #000; +} + +table.std_math.special-values caption { + text-align: left; + font-weight: 700; +} + +.nan { + font-family: monospace; + color: red; +} + +.overload-option, +.overload-signature { + font-family: monospace; +} + +.block-code, +.d_code, +.annotated-prototype { + font-size: 1rem; +} + +.annotated-prototype .overloads { + display: block; + padding: 0px; +} + +.annotated-prototype .overloads li { + display: block; + width: auto; + padding: 0em 0.5em; + text-align: left; + overflow: hidden; + + margin: 0; +} + +.member-list .dt, .overload-option, pre { + max-width: unset; +} + +.annotated-prototype .overloads li.active-overload-option { + border: ridge 2px #ccc; +} + +.annotated-prototype .overloads li.active-overload-option .overload-signature { + white-space: nowrap; + border-bottom: dotted 1px #999; + display: block; +} + +.annotated-prototype .overloads li.overload-option { + border: solid 1px #ccc; + background-color: #eee; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.annotated-prototype .overloads li.ditto-option::before, +.annotated-prototype .overloads li.active-overload-option .overload-signature::before, +.annotated-prototype .overloads li.overload-option::before { + display: inline-block; + width: 6em; + width: 9ch; + font-size: 0.9rem; + vertical-align: baseline; +} + +.annotated-prototype .overloads li.overload-option::before { + content: "Overload: "; +} + +.annotated-prototype .overloads li.active-overload-option .overload-signature::before { + content: "Viewing: "; +} + +.annotated-prototype .overloads li.ditto-option::before { + content: "Related: "; +} + +.annotated-prototype li .declaration-prototype, +.annotated-prototype li .aggregate-prototype, +.annotated-prototype li .function-prototype { + border: none; + padding: 0px; +} + +.annotated-prototype li .declaration-prototype { + padding: 2em 0px; +} + +#page-nav ul { + margin: 0px; + padding: 0px; + list-style: none; +} + +.parameter-name > a[href^="#"], +a.parameter-name[href^="#"] { + color: inherit; +} + + + +/* adrdox special syntax styles */ + +.small-table { + border-collapse: collapse; + min-width: 10em; +} + +.small-table td, +.small-table th { + border: solid 1px #ccc; + padding: 0.25em; +} + +.small-table thead th { + border-bottom: solid 2px #999; +} + +.small-table tbody th, +.small-table.two-axes thead th:first-child { + border-right: solid 2px #999; +} + +.small-table.two-axes td, +.small-table.two-axes th { + text-align: center; + vertical-align: middle; +} + +.adrdox-sample { + display: table; + width: 100%; +} + +.adrdox-sample > div { + display: table-row; +} + +.adrdox-sample > div > * { + display: table-cell; + width: 50%; + vertical-align: top; + border-bottom: dashed 1px #ccc; + padding: 0.25em; + padding-bottom: 0.5em; +} + +.adrdox-sample > div > pre { + border-right: dashed 1px #ccc; +} + +.adrdox-sample > div > pre::before, +.adrdox-sample > div > div::before { + display: block; + font-style: italic; + border-bottom: dashed 1px #ccc; + margin-bottom: 0.5em; + font-family: sans-serif; + font-size: 1rem; + padding: 0px; +} + +.adrdox-sample > div > pre::before { + content: 'Doc source:'; +} +.adrdox-sample > div > div::before { + content: 'Rendered:'; +} + +blockquote { + margin: 1em; + padding: 1em; + border-left: 0.5em solid #ccc; + color: #333; +} + +pre.d_code, +.block-code:not([data-language=""]):not([data-language="pre"]) { + background-color: #fcfcfc; + padding: 0.25em; + border: solid 1px #ccc; + position: relative; +} + +.block-code:not([data-language=""]):not([data-language="pre"])::before { + content: attr(data-language); + display: block; + text-transform: capitalize; + font-size: 0.9rem; + padding: 0px 2px; + border: solid 1px #999; + border-top: none; + border-radius: 0px 0px 0.25em 0.25em; + background-color: #f0f0f0; + float: right; + margin: 0px; + margin-top: -0.25em; + margin-top: calc(-0.25em - 1px); +} +.type, +.highlighted-type { + color: green; + /* font-weight: bold; */ +} +.num, +.highlighted-number { + color: #dc322f; +} +.str, +.highlighted-string { + color: red; +} +.com, +.highlighted-comment { + color: blue; +} +.highlighted-preprocessor-directive { + color: #cd00cd; +} +.highlighted-identifier, +.highlighted-tag { + color: #008888; +} +.highlighted-tag-name { + color: #859900; +} +.highlighted-entity { + color: #cd00cd; + text-decoration: none; + cursor: help; +} +.highlighted-named-constant, +.highlighted-attribute-name { + color: green; +} +.highlighted-attribute-value { + color: red; +} +.highlighted-python-indent { + background: linear-gradient(to right, #eee, transparent 3px) no-repeat; +} +.highlighted-python-indent:hover { + background: linear-gradient(to right, #ccc, transparent 3px) no-repeat; +} + +/* +.with-line-wrappers { + counter-reset: line_numbers; +} + +.with-line-wrappers span.br { + counter-increment: line_numbers; +} + +.with-line-wrappers span.br::before { + content: counter(line_numbers); +*/ +.with-line-wrappers .br { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + width: 3em; + width: 4ch; + display: inline-block; + color: #999; + border-right: solid 2px #ccc; + padding: 0px; + margin: 0px; + margin-right: 3px; + padding-right: 3px; + font-style: normal; + font-weight: normal; + background-color: transparent; + text-align: right; + white-space: pre; +} + +.hide-line-numbers .with-line-wrappers .br { + display: none; +} +.with-line-wrappers .br:target { + background: #ffffbb; +} + +.thousand-lines.with-line-wrappers .br { + width: 4em; + width: 5ch; +} +.ten-thousand-lines.with-line-wrappers .br { + width: 5em; + width: 6ch; +} + +#source-navigation { + position: fixed; + width: 15.5em; +} + +#source-navigation .list-holder { + width: 100%; + overflow: auto; + max-height: 80vh; +} + +#source-navigation .list-holder ul { + padding-left: 1em; +} + +/* hide nested decls as it is too much... */ +#source-navigation .list-holder ul > li > ul { + display: none; +} + +/* ...but show top-level decls under the module cuz no reason not to */ +#source-navigation .list-holder > ul > li > ul { + display: block; +} + +#source-navigation li { + white-space: nowrap; +} + +#source-navigation a { + display: inline; +} + +.postcondition { + color: blue; + font-family: monospace; + font-size: 0.9rem; +} +.postcondition::before { + content: "Post: "; + font-style: italic; + color: black; +} + +.user-table { + border-top: solid 2px black; + border-collapse: collapse; +} + +.user-table tr:nth-of-type(1) th { + border-bottom: solid 1px black; + text-align: left; +} + +.user-table td { + border-bottom: solid 1px #ccc; + vertical-align: top; + padding: 4px; +} +.user-table th { + padding: 4px; +} + +.user-table.two-axes tr + tr th:first-child { + border-bottom: solid 1px #ccc; +} + +.user-table.two-axes th:first-child { + border-right: solid 1px black; + text-align: right; +} + +.allocator-table td:first-child tt { + background-color: transparent; + white-space: nowrap; + font-weight: bold; +} + +.header-anchor { + color: inherit !important; +} + +#members + h3, +.member-list + h3, +h3.member-list-header { + border-bottom: solid 1px #333; + text-transform: capitalize; +} + +#members + h4, +.member-list + h4, +h4.member-list-header { + font-weight: normal; + text-transform: capitalize; + text-decoration: underline; +} + + +tr.leading-row th { + border-bottom: solid 2px black; +} + +.lambda-expression * { + display: inline !important; + padding: 0px !important; + margin: 0px !important; +} + +.footnote-ref a {} +.footnote-ref abbr { + font-variant: none; + text-decoration: none; + cursor: help; +} + +.side-by-side { + table-layout: fixed; + border: none; + width: 100%; +} + +.side-by-side > tbody > tr > td { + vertical-align: top; +} + +/* +tt.D { + font-weight: bold; + background: transparent; + color: inherit; +} +*/ + +tt.D.highlighted *:not(a) { + font-weight: inherit; + color: inherit; +} +tt.D.highlighted a { + color: #500000; +} + +.date-posted { + font-size: 0.9rem; + font-style: italic; +} + +.token-string-literal { + font-style: italic; +} +.token-string-literal:hover { + background-color: rgba(255, 0, 0, 0.05); +} + +.specially-highlighted { + background-color: yellow; + background-color: rgba(255, 255, 0, 0.5); +} + +.console .specially-highlighted { + background-color: rgba(255, 255, 0, 1.0); + color: black; +} + +.quickindex { + background: #f5f5f5; + max-width: 760px; +} + +.quickindex .phobos-booktable { + width: 100%; +} + +.leading-row { + font-style: italic; + background-color: rgb(228, 233, 239); +} + +.leading-row th { + padding-left: 1.5em; +} + +.quickindex td, .quickindex th { + padding-left: 0.3em; +} + +.undocumented-note { + color: #999; +} + +.deprecated-decl { + color: #c00; + font-weight: bold; +} + +.conditional-compilation-attributes { + font-size: 90%; +}