Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ ARTWORK_DIR=$(DOC_SOURCE_DIR)/artwork
# Packages in mir. Just mention the package name here. The contents of package
# xy/zz is in variable PACKAGE_xy_zz. This allows automation in iterating
# packages and their modules.
MIR_PACKAGES = mir mir/ndslice mir/internal mir/math mir/math/func
MIR_PACKAGES = mir mir/ndslice mir/internal mir/math mir/math/func mir/array

PACKAGE_mir = bitmanip conv functional primitives
PACKAGE_mir_array = primitives
PACKAGE_mir_ndslice = package algorithm allocation dynamic field ndfield iterator package slice sorting concatenation topology
PACKAGE_mir_math = constant common sum
PACKAGE_mir_math_func = expdigamma
Expand Down
174 changes: 174 additions & 0 deletions source/mir/array/primitives.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/++
Range primitives for arrays with multi-dimensional like API support.

Note:
UTF strings behaves like common arrays in Mir.
`std.uni.byCodePoint` can be used to creat a range of chararacters.

See_also: $(MREF mir,_primitives).

License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
Copyright: Copyright © 2017-, Ilya Yaroshenko
Authors: Ilya Yaroshenko
+/
module mir.array.primitives;

import std.traits;
import mir.internal.utility;

pragma(inline, true) @fastmath:

///
bool empty(size_t dim = 0, T)(in T[] ar)
if (!dim)
{
return !ar.length;
}

///
unittest
{
assert((int[]).init.empty);
assert(![1].empty!0); // Slice-like API
}

///
ref front(size_t dim = 0, T)(T[] ar)
if (!dim && !is(Unqual!T[] == void[]))
{
assert(ar.length, "Accessing front of an empty array.");
return ar[0];
}

///
unittest
{
assert(*&[3, 4].front == 3); // access be ref
assert([3, 4].front!0 == 3); // Slice-like API
}


///
ref back(size_t dim = 0, T)(T[] ar)
if (!dim && !is(Unqual!T[] == void[]))
{
assert(ar.length, "Accessing back of an empty array.");
return ar[$ - 1];
}

///
unittest
{
assert(*&[3, 4].back == 4); // access be ref
assert([3, 4].back!0 == 4); // Slice-like API
}

///
void popFront(size_t dim = 0, T)(ref T[] ar)
if (!dim && !is(Unqual!T[] == void[]))
{
assert(ar.length, "Evaluating popFront() on an empty array.");
ar = ar[1 .. $];
}

///
unittest
{
auto ar = [3, 4];
ar.popFront;
assert(ar == [4]);
ar.popFront!0; // Slice-like API
assert(ar == []);
}

///
void popBack(size_t dim = 0, T)(ref T[] ar)
if (!dim && !is(Unqual!T[] == void[]))
{
assert(ar.length, "Evaluating popBack() on an empty array.");
ar = ar[0 .. $ - 1];
}

///
unittest
{
auto ar = [3, 4];
ar.popBack;
assert(ar == [3]);
ar.popBack!0; // Slice-like API
assert(ar == []);
}

///
size_t popFrontN(size_t dim = 0, T)(ref T[] ar, size_t n)
if (!dim && !is(Unqual!T[] == void[]))
{
n = ar.length < n ? ar.length : n;
ar = ar[n .. $];
return n;
}

///
unittest
{
auto ar = [3, 4];
ar.popFrontN(1);
assert(ar == [4]);
ar.popFrontN!0(10); // Slice-like API
assert(ar == []);
}

///
size_t popBackN(size_t dim = 0, T)(ref T[] ar, size_t n)
if (!dim && !is(Unqual!T[] == void[]))
{
n = ar.length < n ? ar.length : n;
ar = ar[0 .. $ - n];
return n;
}

///
unittest
{
auto ar = [3, 4];
ar.popBackN(1);
assert(ar == [3]);
ar.popBackN!0(10); // Slice-like API
assert(ar == []);
}

///
void popFrontExactly(size_t dim = 0, T)(ref T[] ar, size_t n)
if (!dim && !is(Unqual!T[] == void[]))
{
assert(ar.length >= n, "Evaluating *.popFrontExactly(n) on an array with length less then n.");
ar = ar[n .. $];
}

///
unittest
{
auto ar = [3, 4, 5];
ar.popFrontExactly(2);
assert(ar == [5]);
ar.popFrontExactly!0(1); // Slice-like API
assert(ar == []);
}

///
void popBackExactly(size_t dim = 0, T)(ref T[] ar, size_t n)
if (!dim && !is(Unqual!T[] == void[]))
{
assert(ar.length >= n, "Evaluating *.popBackExactly(n) on an array with length less then n.");
ar = ar[0 .. $ - n];
}

///
unittest
{
auto ar = [3, 4, 5];
ar.popBackExactly(2);
assert(ar == [3]);
ar.popBackExactly!0(1); // Slice-like API
assert(ar == []);
}
2 changes: 1 addition & 1 deletion source/mir/ndslice/internal.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module mir.ndslice.internal;

import std.range.primitives;
import std.traits;
import std.meta;
import mir.ndslice.slice;
import mir.internal.utility;
import mir.array.primitives;

@fastmath:

Expand Down
7 changes: 7 additions & 0 deletions source/mir/primitives.d
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
/++
Templates used to check primitives.

Publicly imports $(MREF mir,array,_primitives).

License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
Copyright: Copyright © 2017-, Ilya Yaroshenko
Authors: Ilya Yaroshenko
+/
module mir.primitives;

import mir.internal.utility;
public import mir.array.primitives;

@fastmath:

Expand Down