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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ P2MODULES=$(foreach P,$1,$(addprefix $P/,$(PACKAGE_$(subst /,_,$P))))
# packages and their modules.
STD_PACKAGES = std $(addprefix std/,\
algorithm container digest experimental/allocator \
experimental/allocator/building_blocks experimental/logger net \
experimental/allocator/building_blocks experimental/logger \
experimental/ndslice \
net \
range regex)

# Modules broken down per package
Expand All @@ -176,6 +178,7 @@ PACKAGE_std_experimental_allocator_building_blocks = \
fallback_allocator free_list free_tree bitmapped_block \
kernighan_ritchie null_allocator package quantizer \
region scoped_allocator segregator stats_collector
PACKAGE_std_experimental_ndslice = package iteration selection slice
PACKAGE_std_net = curl isemail
PACKAGE_std_range = interfaces package primitives
PACKAGE_std_regex = package $(addprefix internal/,generator ir parser \
Expand Down Expand Up @@ -209,6 +212,7 @@ EXTRA_MODULES_INTERNAL := $(addprefix \
cstring processinit unicode_tables scopebuffer\
unicode_comp unicode_decomp unicode_grapheme unicode_norm) \
$(addprefix std/internal/test/, dummyrange) \
$(addprefix std/experimental/ndslice/, internal) \
$(addprefix std/algorithm/, internal)

EXTRA_MODULES += $(EXTRA_DOCUMENTABLES) $(EXTRA_MODULES_INTERNAL)
Expand Down
194 changes: 194 additions & 0 deletions std/experimental/ndslice/internal.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
module std.experimental.ndslice.internal;

import std.traits;
import std.meta; //: AliasSeq, anySatisfy, Filter, Reverse;

package:

enum string tailErrorMessage(
string fun = __FUNCTION__,
string pfun = __PRETTY_FUNCTION__) =
"
- - -
Error in function
" ~ fun ~ "
- - -
Function prototype
" ~ pfun ~ "
_____";

mixin template _DefineRet()
{
alias Ret = typeof(return);
static if (hasElaborateAssign!(Ret.PureRange))
Ret ret;
else
Ret ret = void;
}

mixin template DimensionsCountCTError()
{
static assert(Dimensions.length <= N,
"Dimensions list length = " ~ Dimensions.length.stringof
~ " should be less than or equal to N = " ~ N.stringof
~ tailErrorMessage!());
}

enum DimensionsCountRTError = q{
assert(dimensions.length <= N,
"Dimensions list length should be less than or equal to N = " ~ N.stringof
~ tailErrorMessage!());
};

mixin template DimensionCTError()
{
static assert(dimension >= 0,
"dimension = " ~ dimension.stringof ~ " at position "
~ i.stringof ~ " should be greater than or equal to 0"
~ tailErrorMessage!());
static assert(dimension < N,
"dimension = " ~ dimension.stringof ~ " at position "
~ i.stringof ~ " should be less than N = " ~ N.stringof
~ tailErrorMessage!());
}

enum DimensionRTError = q{
static if (isSigned!(typeof(dimension)))
assert(dimension >= 0, "dimension should be greater than or equal to 0"
~ tailErrorMessage!());
assert(dimension < N, "dimension should be less than N = " ~ N.stringof
~ tailErrorMessage!());
};

private alias IncFront(Seq...) = AliasSeq!(Seq[0] + 1, Seq[1 .. $]);

private alias DecFront(Seq...) = AliasSeq!(Seq[0] - 1, Seq[1 .. $]);

private enum bool isNotZero(alias t) = t != 0;

alias NSeqEvert(Seq...) = Filter!(isNotZero, DecFront!(Reverse!(IncFront!Seq)));

alias Parts(Seq...) = DecAll!(IncFront!Seq);

alias Snowball(Seq...) = AliasSeq!(size_t.init, SnowballImpl!(size_t.init, Seq));

private template SnowballImpl(size_t val, Seq...)
{
static if (Seq.length == 0)
alias SnowballImpl = AliasSeq!();
else
alias SnowballImpl = AliasSeq!(Seq[0] + val, SnowballImpl!(Seq[0] + val, Seq[1 .. $]));
}

private template DecAll(Seq...)
{
static if (Seq.length == 0)
alias DecAll = AliasSeq!();
else
alias DecAll = AliasSeq!(Seq[0] - 1, DecAll!(Seq[1 .. $]));
}

template SliceFromSeq(Range, Seq...)
{
static if (Seq.length == 0)
alias SliceFromSeq = Range;
else
{
import std.experimental.ndslice.slice: Slice;
alias SliceFromSeq = SliceFromSeq!(Slice!(Seq[$ - 1], Range), Seq[0 .. $ - 1]);
}
}

template DynamicArrayDimensionsCount(T)
{
static if(isDynamicArray!T)
enum size_t DynamicArrayDimensionsCount = 1 + DynamicArrayDimensionsCount!(typeof(T.init[0]));
else
enum size_t DynamicArrayDimensionsCount = 0;
}

bool isPermutation(size_t N)(auto ref in size_t[N] perm)
{
int[N] mask;
if (isValidPartialPermutationImpl(perm, mask) == false)
return false;
foreach (e; mask)
if (e == false)
return false;
return true;
}

bool isValidPartialPermutation(size_t N)(in size_t[] perm)
{
int[N] mask;
return isValidPartialPermutationImpl(perm, mask);
}

private bool isValidPartialPermutationImpl(size_t N)(in size_t[] perm, ref int[N] mask)
{
if (perm.length == 0)
return false;
foreach (j; perm)
{
if (j >= N)
return false;
if (mask[j]) //duplicate
return false;
mask[j] = true;
}
return true;
}

enum isIndex(I) = is(I : size_t);

private enum isReference(P) =
hasIndirections!P
|| isFunctionPointer!P
|| is(P == interface);

enum hasReference(T) = anySatisfy!(isReference, RepresentationTypeTuple!T);

alias ImplicitlyUnqual(T) = Select!(isImplicitlyConvertible!(T, Unqual!T), Unqual!T, T);

//TODO: replace with `static foreach`
template Iota(size_t i, size_t j)
{
static assert(i <= j, "Iota: i should be less than or equal to j");
static if (i == j)
alias Iota = AliasSeq!();
else
alias Iota = AliasSeq!(i, Iota!(i + 1, j));
}

template Repeat(T, size_t N)
{
static if (N)
alias Repeat = AliasSeq!(Repeat!(T, N - 1), T);
else
alias Repeat = AliasSeq!();
}

size_t lengthsProduct(size_t N)(auto ref in size_t[N] lengths)
{
size_t length = lengths[0];
foreach (i; Iota!(1, N))
length *= lengths[i];
return length;
}

pure nothrow unittest
{
const size_t[3] lengths = [3, 4, 5];
assert(lengthsProduct(lengths) == 60);
assert(lengthsProduct([3, 4, 5]) == 60);
}

enum canSave(T) = isPointer!T || isDynamicArray!T ||
__traits(compiles,
{
T r1 = T.init;
auto s1 = r1.save;
static assert (is(typeof(s1) == T));
});

struct _Slice { size_t i, j; }
Loading