From 90797a48be55b98d86e4e9ceffeecddd4ab90ac7 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 7 Jun 2022 08:40:18 +0200 Subject: [PATCH] Replace tuples with custom types --- source/tanya/container/entry.d | 9 +- source/tanya/format.d | 39 +++++---- source/tanya/math/random.d | 1 - source/tanya/typecons.d | 154 --------------------------------- tests/tanya/tests/typecons.d | 23 ----- 5 files changed, 28 insertions(+), 198 deletions(-) delete mode 100644 source/tanya/typecons.d delete mode 100644 tests/tanya/tests/typecons.d diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index 02eca4f..7ea5ff6 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -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; diff --git a/source/tanya/format.d b/source/tanya/format.d index 7f09285..8f43cf6 100644 --- a/source/tanya/format.d +++ b/source/tanya/format.d @@ -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) diff --git a/source/tanya/math/random.d b/source/tanya/math/random.d index 68ec317..646dd59 100644 --- a/source/tanya/math/random.d +++ b/source/tanya/math/random.d @@ -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; diff --git a/source/tanya/typecons.d b/source/tanya/typecons.d deleted file mode 100644 index 68c629e..0000000 --- a/source/tanya/typecons.d +++ /dev/null @@ -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); -} diff --git a/tests/tanya/tests/typecons.d b/tests/tanya/tests/typecons.d deleted file mode 100644 index 152370c..0000000 --- a/tests/tanya/tests/typecons.d +++ /dev/null @@ -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"))); -}