Replace tuples with custom types

This commit is contained in:
Eugen Wissner 2022-06-07 08:40:18 +02:00
parent 5453c646f6
commit 90797a48be
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
5 changed files with 28 additions and 198 deletions

View File

@ -5,7 +5,7 @@
/*
* Internal package used by containers that rely on entries/nodes.
*
* Copyright: Eugene Wissner 2016-2020.
* Copyright: Eugene Wissner 2016-2022.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@ -19,7 +19,6 @@ import tanya.memory.allocator;
import tanya.memory.lifetime;
import tanya.meta.trait;
import tanya.meta.transform;
import tanya.typecons;
package struct SEntry(T)
{
@ -54,7 +53,11 @@ package struct Bucket(K, V = void)
}
else
{
alias KV = Tuple!(K, "key", V, "value");
package struct KV
{
package K key;
package V value;
}
KV kv;
}
BucketStatus status = BucketStatus.empty;

View File

@ -38,7 +38,7 @@
*
* More advanced formatting is currently not implemented.
*
* Copyright: Eugene Wissner 2017-2020.
* Copyright: Eugene Wissner 2017-2022.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@ -56,7 +56,6 @@ import tanya.meta.metafunction;
import tanya.meta.trait;
import tanya.meta.transform;
import tanya.range;
import tanya.typecons : Tuple;
// Returns the last part of buffer with converted number.
package(tanya) char[] integral2String(T)(T number, return ref char[21] buffer)
@ -940,6 +939,12 @@ private struct uint128
{
ulong[2] data;
private struct DivMod
{
uint128 quotient;
uint128 remainder;
}
this(ulong upper, ulong lower) @nogc nothrow pure @safe
{
this.data[0] = upper;
@ -1174,7 +1179,7 @@ private struct uint128
return this.data[1];
}
Tuple!(uint128, uint128) divMod(ulong rhs) const @nogc nothrow pure @safe
DivMod divMod(ulong rhs) const @nogc nothrow pure @safe
in
{
assert(rhs != uint128(), "Division by 0");
@ -1197,22 +1202,22 @@ private struct uint128
typeof(return) result;
for (ubyte x = this.bits; x > 0; --x)
{
result[0] = result[0] << 1;
result[1] = result[1] << 1;
result.quotient = result.quotient << 1;
result.remainder = result.remainder << 1;
if ((this >> (x - 1U)) & 1)
{
++result[1];
++result.remainder;
}
if (result[1] >= rhs)
if (result.remainder >= rhs)
{
if (result[1].data[1] < rhs)
if (result.remainder.data[1] < rhs)
{
--result[1].data[0];
--result.remainder.data[0];
}
result[1].data[1] -= rhs;
++result[0];
result.remainder.data[1] -= rhs;
++result.quotient;
}
}
return result;
@ -1220,12 +1225,12 @@ private struct uint128
uint128 opBinary(string op : "/")(ulong rhs)
{
return divMod(rhs)[0];
return divMod(rhs).quotient;
}
uint128 opBinary(string op : "%")(ulong rhs) const
{
return divMod(rhs)[1];
return divMod(rhs).remainder;
}
}
@ -1302,12 +1307,12 @@ do
enum ulong power19 = cast(ulong) 1e19;
auto qr = leftBoundary.divMod(power19);
auto low = cast(ulong) qr[1];
const lowFactor = cast(ulong) (qr[0] % power19);
auto low = cast(ulong) qr.remainder;
const lowFactor = cast(ulong) (qr.quotient % power19);
qr = rightBoundary.divMod(power19);
auto high = cast(ulong) qr[1];
const highFactor = cast(ulong) (qr[0] % power19);
auto high = cast(ulong) qr.remainder;
const highFactor = cast(ulong) (qr.quotient % power19);
size_t digitIndex;
if (lowFactor != highFactor)

View File

@ -16,7 +16,6 @@ module tanya.math.random;
import std.typecons;
import tanya.memory.allocator;
import tanya.typecons;
/// Maximum amount gathered from the entropy sources.
enum maxGather = 128;

View File

@ -1,154 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Type constructors.
*
* This module contains templates that allow to build new types from the
* available ones.
*
* Copyright: Eugene Wissner 2017-2020.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/typecons.d,
* tanya/typecons.d)
*/
module tanya.typecons;
import tanya.format;
import tanya.memory.lifetime;
import tanya.meta.metafunction;
import tanya.meta.trait;
/**
* $(D_PSYMBOL Tuple) can store two or more heterogeneous objects.
*
* The objects can by accessed by index as `obj[0]` and `obj[1]` or by optional
* names (e.g. `obj.first`).
*
* $(D_PARAM Specs) contains a list of object types and names. First
* comes the object type, then an optional string containing the name.
* If you want the object be accessible only by its index (`0` or `1`),
* just skip the name.
*
* Params:
* Specs = Field types and names.
*
* See_Also: $(D_PSYMBOL tuple).
*/
template Tuple(Specs...)
{
template parseSpecs(size_t fieldCount, Specs...)
{
static if (Specs.length == 0)
{
alias parseSpecs = AliasSeq!();
}
else static if (is(Specs[0]) && fieldCount < 2)
{
static if (is(typeof(Specs[1]) == string))
{
alias parseSpecs
= AliasSeq!(Pack!(Specs[0], Specs[1]),
parseSpecs!(fieldCount + 1, Specs[2 .. $]));
}
else
{
alias parseSpecs
= AliasSeq!(Pack!(Specs[0]),
parseSpecs!(fieldCount + 1, Specs[1 .. $]));
}
}
else
{
static assert(false, "Invalid argument: " ~ Specs[0].stringof);
}
}
alias ChooseType(alias T) = T.Seq[0];
alias ParsedSpecs = parseSpecs!(0, Specs);
static assert(ParsedSpecs.length > 1, "Invalid argument count");
private string formatAliases(size_t n, Specs...)()
{
static if (Specs.length == 0)
{
return "";
}
else
{
string fieldAlias;
static if (Specs[0].length == 2)
{
char[21] buffer;
fieldAlias = "alias " ~ Specs[0][1] ~ " = expand["
~ integral2String(n, buffer).idup ~ "];";
}
return fieldAlias ~ formatAliases!(n + 1, Specs[1 .. $])();
}
}
struct Tuple
{
/// Field types.
alias Types = Map!(ChooseType, ParsedSpecs);
// Create field aliases.
mixin(formatAliases!(0, ParsedSpecs[0 .. $])());
/// Represents the values of the $(D_PSYMBOL Tuple) as a list of values.
Types expand;
alias expand this;
}
}
///
@nogc nothrow pure @safe unittest
{
auto pair = Tuple!(int, "first", string, "second")(1, "second");
assert(pair.first == 1);
assert(pair[0] == 1);
assert(pair.second == "second");
assert(pair[1] == "second");
}
/**
* Creates a new $(D_PSYMBOL Tuple).
*
* Params:
* Names = Field names.
*
* See_Also: $(D_PSYMBOL Tuple).
*/
template tuple(Names...)
{
/**
* Creates a new $(D_PSYMBOL Tuple).
*
* Params:
* Args = Field types.
* args = Field values.
*
* Returns: Newly created $(D_PSYMBOL Tuple).
*/
auto tuple(Args...)(auto ref Args args)
if (Args.length >= Names.length && isTypeTuple!Args)
{
alias Zipped = ZipWith!(AliasSeq, Pack!Args, Pack!Names);
alias Nameless = Args[Names.length .. $];
return Tuple!(Zipped, Nameless)(forward!args);
}
}
///
@nogc nothrow pure @safe unittest
{
auto t = tuple!("one", "two")(20, 5);
assert(t.one == 20);
assert(t.two == 5);
}

View File

@ -1,23 +0,0 @@
module tanya.tests.typecons;
import tanya.test.stub;
import tanya.typecons;
@nogc nothrow pure @safe unittest
{
static assert(is(Tuple!(int, int)));
static assert(!is(Tuple!(int, 5)));
static assert(is(Tuple!(int, "first", int)));
static assert(is(Tuple!(int, "first", int, "second")));
static assert(is(Tuple!(int, "first", int)));
static assert(is(Tuple!(int, int, "second")));
static assert(!is(Tuple!("first", int, "second", int)));
static assert(!is(Tuple!(int, int, int)));
static assert(!is(Tuple!(int, "first")));
static assert(!is(Tuple!(int, double, char)));
static assert(!is(Tuple!(int, "first", double, "second", char, "third")));
}