From 85c97c634e9373022f2a2d82ca6166d497ac521c Mon Sep 17 00:00:00 2001 From: Kapendev Date: Tue, 6 Aug 2024 02:50:23 +0300 Subject: [PATCH] Done with unions module. --- TODO.md | 10 ++++----- source/popka/core/ascii.d | 4 ++-- source/popka/core/math.d | 5 ++--- source/popka/core/stdc.d | 35 +++++++++++-------------------- source/popka/core/traits.d | 16 +++++++------- source/popka/core/unions.d | 43 ++++++++++++++++++++++++++++++++------ 6 files changed, 66 insertions(+), 47 deletions(-) diff --git a/TODO.md b/TODO.md index 0e57b27..d644ac5 100644 --- a/TODO.md +++ b/TODO.md @@ -11,14 +11,14 @@ Cleaning things in core. * [x] io * [ ] math * [x] package -* [ ] stdc +* [x] stdc * [x] traits * [x] types -* [ ] unions +* [x] unions -Now I have to do math, stdc and unions. -Was doing unions. -Was doing the compile time stuff. +Done with unions. +Now will do math. +Then do also a file with the abbreviations used. For docs and stuff. ## IDEAS diff --git a/source/popka/core/ascii.d b/source/popka/core/ascii.d index b5a9821..7665c80 100644 --- a/source/popka/core/ascii.d +++ b/source/popka/core/ascii.d @@ -440,7 +440,7 @@ IStr toStr(T)(T value, ToStrOptions options = ToStrOptions()) { return unsignedToStr(value); } else static if (isSignedType!T) { return signedToStr(value); - } else static if (isDoubleType!T) { + } else static if (isFloatingType!T) { return doubleToStr(value, options.doublePrecision); } else static if (isStrType!T) { return value; @@ -451,7 +451,7 @@ IStr toStr(T)(T value, ToStrOptions options = ToStrOptions()) { } else static if (__traits(hasMember, T, "toStr")) { return value.toStr(); } else { - static assert(0, "Type `" ~ T.stringof ~ "` does not implement the `toStr` function."); + static assert(0, funcImplementationErrorMessage!(T, "toStr")); } } diff --git a/source/popka/core/math.d b/source/popka/core/math.d index a86cc06..861fb8f 100644 --- a/source/popka/core/math.d +++ b/source/popka/core/math.d @@ -1,8 +1,7 @@ // Copyright 2024 Alexandros F. G. Kapretsos // SPDX-License-Identifier: MIT -/// The math module covers -/// essential mathematical operations, vectors, and shapes. +/// The `math` module provides mathematical functions and types. module popka.core.math; @@ -12,7 +11,7 @@ import popka.core.types; @safe @nogc nothrow: -enum pi = 3.141592f; +enum pi = 3.1415f; enum epsilon = 0.0001f; enum Hook : ubyte { diff --git a/source/popka/core/stdc.d b/source/popka/core/stdc.d index 4427d9a..b147ad7 100644 --- a/source/popka/core/stdc.d +++ b/source/popka/core/stdc.d @@ -1,19 +1,19 @@ // Copyright 2024 Alexandros F. G. Kapretsos // SPDX-License-Identifier: MIT -/// The stdc module provides access to C standard library functions and types. - +/// The `stdc` module provides access to the C standard library. module popka.core.stdc; @nogc nothrow extern(C): -// types +// types.l -// NOTE: Might be a bad idea. We care about Windows, MacOS, Linux and Web for now. version (WebAssembly) { - alias c_long = int; + alias CLong = int; + alias CULong = uint; } else { - alias c_long = long; + alias CLong = long; + alias CULong = ulong; } // math.h @@ -30,6 +30,8 @@ void free(void* ptr); // stdio.h +alias FILE = void; + enum SEEK_SET = 0; enum SEEK_CUR = 1; enum SEEK_END = 2; @@ -38,9 +40,7 @@ enum STDIN_FILENO = 0; enum STDOUT_FILENO = 1; enum STDERR_FILENO = 2; -alias FILE = void; - -// NOTE: Code from D std. +// NOTE: Code from the D standard library. version (CRuntime_Microsoft) { FILE* __acrt_iob_func(int hnd); // VS2015+, reimplemented in msvc.d for VS2013- FILE* stdin()() { return __acrt_iob_func(0); } @@ -54,7 +54,6 @@ version (CRuntime_Microsoft) { extern __gshared FILE* __stdinp; extern __gshared FILE* __stdoutp; extern __gshared FILE* __stderrp; - alias __stdinp stdin; alias __stdoutp stdout; alias __stderrp stderr; @@ -62,27 +61,22 @@ version (CRuntime_Microsoft) { extern __gshared FILE* __stdinp; extern __gshared FILE* __stdoutp; extern __gshared FILE* __stderrp; - alias __stdinp stdin; alias __stdoutp stdout; alias __stderrp stderr; } else version (NetBSD) { extern __gshared FILE[3] __sF; - auto __stdin()() { return &__sF[0]; } auto __stdout()() { return &__sF[1]; } auto __stderr()() { return &__sF[2]; } - alias __stdin stdin; alias __stdout stdout; alias __stderr stderr; } else version (OpenBSD) { extern __gshared FILE[3] __sF; - auto __stdin()() { return &__sF[0]; } auto __stdout()() { return &__sF[1]; } auto __stderr()() { return &__sF[2]; } - alias __stdin stdin; alias __stdout stdout; alias __stderr stderr; @@ -90,19 +84,16 @@ version (CRuntime_Microsoft) { extern __gshared FILE* __stdinp; extern __gshared FILE* __stdoutp; extern __gshared FILE* __stderrp; - alias __stdinp stdin; alias __stdoutp stdout; alias __stderrp stderr; } else version (Solaris) { extern __gshared FILE[_NFILE] __iob; - auto stdin()() { return &__iob[0]; } auto stdout()() { return &__iob[1]; } auto stderr()() { return &__iob[2]; } } else version (CRuntime_Bionic) { extern __gshared FILE[3] __sF; - auto stdin()() { return &__sF[0]; } auto stdout()() { return &__sF[1]; } auto stderr()() { return &__sF[2]; } @@ -117,9 +108,7 @@ version (CRuntime_Microsoft) { __sFILE* _stdout; __sFILE* _stderr; } - _reent* __getreent(); - pragma(inline, true) { auto stdin()() { return __getreent()._stdin; } auto stdout()() { return __getreent()._stdout; } @@ -140,9 +129,9 @@ version (CRuntime_Microsoft) { } FILE* fopen(const(char)* filename, const(char)* mode); -c_long ftell(FILE* stream); -int fseek(FILE* stream, c_long offset, int origin); +CLong ftell(FILE* stream); +int fseek(FILE* stream, CLong offset, int origin); size_t fread(void* ptr, size_t size, size_t count, FILE* stream); int fclose(FILE* stream); int fputs(const(char)* str, FILE* stream); -size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream); +size_t fwrite(const(void)* buffer, size_t size, size_t count, FILE* stream); diff --git a/source/popka/core/traits.d b/source/popka/core/traits.d index f4d7501..467504f 100644 --- a/source/popka/core/traits.d +++ b/source/popka/core/traits.d @@ -50,17 +50,17 @@ bool isIntegerType(T)() { return isUnsignedType!T || isSignedType!T; } -bool isDoubleType(T)() { +bool isFloatingType(T)() { return is(T == float) || - is(T == const(float)) || - is(T == immutable(float)) || - is(T == double) || - is(T == const(double)) || - is(T == immutable(double)); + is(T == const(float)) || + is(T == immutable(float)) || + is(T == double) || + is(T == const(double)) || + is(T == immutable(double)); } bool isNumberType(T)() { - return isIntegerType!T || isDoubleType!T; + return isIntegerType!T || isFloatingType!T; } bool isCharType(T)() { @@ -106,7 +106,7 @@ bool isCStrType(T)() { } bool hasMember(T, IStr name)() { - return __traits(hasMember, T, func); + return __traits(hasMember, T, name); } int findInAliasArgs(T, A...)() { diff --git a/source/popka/core/unions.d b/source/popka/core/unions.d index 46435d7..795a9d4 100644 --- a/source/popka/core/unions.d +++ b/source/popka/core/unions.d @@ -1,7 +1,7 @@ // Copyright 2024 Alexandros F. G. Kapretsos // SPDX-License-Identifier: MIT -/// The `unions` module provides functions and value structures for working with unions. +/// The `unions` module provides functions and data structures for working with unions. module popka.core.unions; import popka.core.types; @@ -11,6 +11,8 @@ import popka.core.traits; alias VariantKind = int; +struct None {} + union VariantValue(A...) { static assert(A.length != 0, "Arguments must contain at least one element."); @@ -22,7 +24,7 @@ union VariantValue(A...) { } } - alias Base = A[0]; + enum length = A.length; alias Types = A; } @@ -63,6 +65,11 @@ struct Variant(A...) { return kind == findInAliasArgs!(T, A); } + @trusted + ref A[0] base() { + return member0; + } + @trusted ref T get(T)() { if (isKind!T) { @@ -106,7 +113,7 @@ T toVariant(T)(VariantKind kind) { static foreach (i, Type; T.Types) { if (i == kind) { static if (isNumberType!Type) { - result = 0; + result = cast(Type) 0; } else { result = Type.init; } @@ -124,7 +131,7 @@ T toVariant(T)(IStr kindName) { static foreach (i, Type; T.Types) { if (Type.stringof == kindName) { static if (isNumberType!Type) { - result = 0; + result = cast(Type) 0; } else { result = Type.init; } @@ -144,6 +151,7 @@ mixin template addBase(T) { alias base this; } +// Variant test. unittest { alias Number = Variant!(float, double); @@ -159,7 +167,30 @@ unittest { assert(Number(0.0).isKind!double == true); assert(Number(0.0).kindName == "double"); assert(Number(0.0).get!double() == 0); + assert(Number.kindOf!float == 0); + assert(Number.kindOf!double == 1); + assert(Number.kindNameOf!float == "float"); + assert(Number.kindNameOf!double == "double"); + + auto number = Number(); + number = 0.0; + assert(number.get!double() == 0); + number = 0.0f; + assert(number.get!float() == 0); + number.get!float() += 69.0f; + assert(number.get!float() == 69); - // TODO: Was doing the compile time stuff. - // assert(toVariant!Number(Variant.kindOf!(float)).isKind!float == true); + auto numberPtr = &number.get!float(); + *numberPtr *= 10; + assert(number.get!float() == 690); +} + +// Function test. +unittest { + alias Number = Variant!(float, double); + + assert(toVariant!Number(Number.kindOf!float).get!float() == 0); + assert(toVariant!Number(Number.kindOf!double).get!double() == 0); + assert(toVariant!Number(Number.kindNameOf!float).get!float() == 0); + assert(toVariant!Number(Number.kindNameOf!double).get!double() == 0); }