Done with unions module.

This commit is contained in:
Kapendev 2024-08-06 02:50:23 +03:00
parent a8d1d8bb7c
commit 85c97c634e
6 changed files with 66 additions and 47 deletions

10
TODO.md
View file

@ -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

View file

@ -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"));
}
}

View file

@ -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 {

View file

@ -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);

View file

@ -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...)() {

View file

@ -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);
}