d中自定义object.d

原文

module object;

alias size_t = typeof(int.sizeof);
alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0);

alias sizediff_t = ptrdiff_t; // 后向兼容
only.
/**
 * 底层类型
 * See $(DDSUBLINK spec/type, noreturn).
 */
alias noreturn = typeof(*null);

alias hash_t = size_t; // 后向兼容
alias equals_t = bool; // 后向兼容

alias string  = immutable(char)[];
alias wstring = immutable(wchar)[];
alias dstring = immutable(dchar)[];


bool __equals(T1, T2)(scope const T1[] lhs, scope const T2[] 
rhs)
@nogc nothrow pure @trusted
if (__traits(isScalar, T1) && __traits(isScalar, T2))
{
    if (lhs.length != rhs.length)
        return false;

    static if (T1.sizeof == T2.sizeof
        // 匹配`符号`
        && (T1.sizeof >= 4 || __traits(isUnsigned, T1) ==__traits(isUnsigned, T2))
        && !__traits(isFloating, T1) && !__traits(isFloating,T2))
    {
        if (!__ctfe)
        {
            // 会错误允许整与指针相等
            // ctfe会禁止

            import core.stdc.string : memcmp;
            return lhs.length == 0 ||
                0 == memcmp(cast(const void*) lhs.ptr,cast(const void*) rhs.ptr, lhs.length * T1.sizeof);
        }
    }


    foreach (const i; 0 .. lhs.length)
    {
        static if (__traits(isStaticArray, at(lhs, 0))) // 
"Fix" for -betterC
        {
            if (at(lhs, i)[] != at(rhs, i)[]) // T1[N] != T2[N] 
doesn't compile with -betterC.
                return false;
        }
        else
        {
            if (at(lhs, i) != at(rhs, i))
                return false;
        }
    }
    return true;
}

bool __equals(T1, T2)(scope T1[] lhs, scope T2[] rhs)
if (!__traits(isScalar, T1) || !__traits(isScalar, T2))
{
    if (lhs.length != rhs.length)
    {
        return false;
    }
    if (lhs.length == 0)
        return true;

    static if (useMemcmp!(T1, T2))
    {
        if (!__ctfe)
        {
            static bool trustedMemcmp(scope T1[] lhs, scope 
T2[] rhs) @trusted @nogc nothrow pure
            {
                pragma(inline, true);
                import core.stdc.string : memcmp;
                return memcmp(cast(void*) lhs.ptr, cast(void*) 
rhs.ptr, lhs.length * T1.sizeof) == 0;
            }
            return trustedMemcmp(lhs, rhs);
        }
        else
        {

            foreach (const i; 0 .. lhs.length)
            {
                static if (__traits(isStaticArray, at(lhs, 0))) 
// "Fix" for -betterC
                {
                    if (at(lhs, i)[] != at(rhs, i)[]) // T1[N] 
!= T2[N] doesn't compile with -betterC.
                        return false;
                }
                else
                {
                    if (at(lhs, i) != at(rhs, i))
                        return false;
                }
            }
            return true;
        }
    }
    else
    {

    foreach (const i; 0 .. lhs.length)
    {
        static if (__traits(isStaticArray, at(lhs, 0))) // 
"Fix" for -betterC
        {
            if (at(lhs, i)[] != at(rhs, i)[]) // T1[N] != T2[N] ,用-betterC不编译.
                return false;
        }
        else
        {
            if (at(lhs, i) != at(rhs, i))
                return false;
        }
    }
        return true;
    }
}

pragma(inline, true)
ref at(T)(T[] r, size_t i) @trusted
    // exclude opaque structs due to ,https://issues.dlang.org/show_bug.cgi?id=20959
    if (!(is(T == struct) && !is(typeof(T.sizeof))))
{
    static if (is(immutable T == immutable void))
        return (cast(ubyte*) r.ptr)[i];
    else
        return r.ptr[i];
}

template BaseType(T)
{
    static if (__traits(isStaticArray, T))
        alias BaseType = BaseType!(typeof(T.init[0]));
    else static if (is(immutable T == immutable void))
        alias BaseType = ubyte;
    else static if (is(T == E*, E))
        alias BaseType = size_t;
    else
        alias BaseType = T;
}

template useMemcmp(T1, T2)
{
    static if (T1.sizeof != T2.sizeof)
        enum useMemcmp = false;
    else
    {
        alias B1 = BaseType!T1;
        alias B2 = BaseType!T2;
        enum useMemcmp = __traits(isIntegral, B1) && 
__traits(isIntegral, B2)
           && !( (B1.sizeof < 4 || B2.sizeof < 4) && 
__traits(isUnsigned, B1) != __traits(isUnsigned, B2) );
    }
}



TTo[] __ArrayCast(TFrom, TTo)(return scope TFrom[] from)
{
   const fromSize = from.length * TFrom.sizeof;
   const toLength = fromSize / TTo.sizeof;

   if ((fromSize % TTo.sizeof) != 0)
   {
        //onArrayCastError(TFrom.stringof, fromSize, 
TTo.stringof, toLength * TTo.sizeof);
        assert(0);
   }

   struct Array
   {
       size_t length;
       void* ptr;
   }
   auto a = cast(Array*)&from;
   a.length = toLength; // 新长度
   return *cast(TTo[]*)a;
}



// switch
extern(C) void __switch_error()(string file = __FILE__, size_t 
line = __LINE__)
{
    //__switch_errorT(file, line);
    wasm.abort();
}

extern(C) int __switch(T, caseLabels...)(/*in*/ const scope T[] 
condition) pure nothrow @safe @nogc
{
    // 关闭递归
    static if (caseLabels.length == 0)
    {
        return int.min;
    }
    else static if (caseLabels.length == 1)
    {
        return __cmp(condition, caseLabels[0]) == 0 ? 0 : 
int.min;
    }
    else static if (caseLabels.length < 7)
    {
        int r = void;
        enum mid = cast(int)caseLabels.length / 2;
        if (condition.length == caseLabels[mid].length)
        {
            r = __cmp(condition, caseLabels[mid]);
            if (r == 0) return mid;
        }
        else
        {
            // 等价但更快.condition.length>caseLabels[$ / 2].length ? 1 : -1
            r = ((condition.length > caseLabels[mid].length) << ) - 1;
        }

        if (r < 0)
        {
            // 左搜索
            return __switch!(T, caseLabels[0 .. 
mid])(condition);
        }
        else
        {
            // 右搜索
            return __switch!(T, caseLabels[mid + 1 .. 
$])(condition) + mid + 1;
        }
    }
    else
    {
        // 需要在纯代码中访问不变数组
        // 但当前强制标签为猜条件类型(e.g. const(char)[]).
        pure @trusted nothrow @nogc asImmutable(scope 
const(T[])[] items)
        {
            assert(__ctfe); // 对CTFE@safe
            immutable T[][caseLabels.length] result = 
cast(immutable)(items[]);
            return result;
        }
        static immutable T[][caseLabels.length] cases = 
asImmutable([caseLabels]);

        // 静态数组标签中运行时二分搜索
        return __switchSearch!T(cases[], condition);
    }
}

extern(C) int __cmp(T)(scope const T[] lhs, scope const T[] 
rhs) @trusted
    if (__traits(isScalar, T))
{
    // 对T按实现类型计算U.
    static if (is(T == ubyte) || is(T == void) || is(T == bool))
        alias U = char;
    else static if (is(T == wchar))
        alias U = ushort;
    else static if (is(T == dchar))
        alias U = uint;
    else static if (is(T == ifloat))
        alias U = float;
    else static if (is(T == idouble))
        alias U = double;
    else static if (is(T == ireal))
        alias U = real;
    else
        alias U = T;

    static if (is(U == char))
    {
        import core.internal.string : dstrcmp;
        return dstrcmp(cast(char[]) lhs, cast(char[]) rhs);
    }
    else static if (!is(U == T))
    {
        // 重用另一实现
        return __cmp(cast(U[]) lhs, cast(U[]) rhs);
    }
    else
    {
        version (BigEndian)
        static if (__traits(isUnsigned, T) ? !is(T == __vector) 
: is(T : P*, P))
        {
            if (!__ctfe)
            {
                int c = mem.memcmp(lhs.ptr, rhs.ptr, 
(lhs.length <= rhs.length ? lhs.length : rhs.length) * 
T.sizeof);
                if (c)
                    return c;
                static if (size_t.sizeof <= uint.sizeof && 
T.sizeof >= 2)
                    return cast(int) lhs.length - cast(int) 
rhs.length;
                else
                    return int(lhs.length > rhs.length) - 
int(lhs.length < rhs.length);
            }
        }

        immutable len = lhs.length <= rhs.length ? lhs.length : 
rhs.length;
        foreach (const u; 0 .. len)
        {
            static if (__traits(isFloating, T))
            {
                immutable a = lhs.ptr[u], b = rhs.ptr[u];
                static if (is(T == cfloat) || is(T == cdouble)
                    || is(T == creal))
                {
                    // 用rt.cmath2._Ccmp替换?
                    auto r = (a.re > b.re) - (a.re < b.re);
                    if (!r) r = (a.im > b.im) - (a.im < b.im);
                }
                else
                {
                    const r = (a > b) - (a < b);
                }
                if (r) return r;
            }
            else if (lhs.ptr[u] != rhs.ptr[u])
                return lhs.ptr[u] < rhs.ptr[u] ? -1 : 1;
        }
        return (lhs.length > rhs.length) - (lhs.length < 
rhs.length);
    }
}

// 比较降级为调用此函数
extern(C) int __cmp(T1, T2)(T1[] s1, T2[] s2)
if (!__traits(isScalar, T1) && !__traits(isScalar, T2))
{
    alias U1 = Unqual!T1;
    alias U2 = Unqual!T2;

    static if (is(U1 == void) && is(U2 == void))
        static @trusted ref inout(ubyte) at(inout(void)[] r, 
size_t i) { return (cast(inout(ubyte)*) r.ptr)[i]; }
    else
        static @trusted ref R at(R)(R[] r, size_t i) { return 
r.ptr[i]; }

    // 正字节类型= > dstrcmp
    immutable len = s1.length <= s2.length ? s1.length : 
s2.length;

    foreach (const u; 0 .. len)
    {
        static if (__traits(compiles, __cmp(at(s1, u), at(s2, 
u))))
        {
            auto c = __cmp(at(s1, u), at(s2, u));
            if (c != 0)
                return c;
        }
        else static if (__traits(compiles, at(s1, 
u).opCmp(at(s2, u))))
        {
            auto c = at(s1, u).opCmp(at(s2, u));
            if (c != 0)
                return c;
        }
        else static if (__traits(compiles, at(s1, u) < at(s2, 
u)))
        {
            if (at(s1, u) != at(s2, u))
                return at(s1, u) < at(s2, u) ? -1 : 1;
        }
        else
        {
            // TODO: fix this legacy bad behavior, see
            // https://issues.dlang.org/show_bug.cgi?id=17244
            static assert(is(U1 == U2), "Internal error.");
            auto c = (() @trusted => mem.memcmp(&at(s1, u), 
&at(s2, u), U1.sizeof))();
            if (c != 0)
                return c;
        }
    }
    return (s1.length > s2.length) - (s1.length < s2.length);
}


template Unqual(T : const U, U)
{
    static if (is(U == shared V, V))
        alias Unqual = V;
    else
        alias Unqual = U;
}


// 二分搜索,
private int __switchSearch(T)(/*in*/ const scope T[][] cases, 
/*in*/ const scope T[] condition) pure nothrow @safe @nogc
{
    size_t low = 0;
    size_t high = cases.length;

    do
    {
        auto mid = (low + high) / 2;
        int r = void;
        if (condition.length == cases[mid].length)
        {
            r = __cmp(condition, cases[mid]);
            if (r == 0) return cast(int) mid;
        }
        else
        {
            r = ((condition.length > cases[mid].length) << 1) - 1;
        }//生成更好代码

        if (r > 0) low = mid + 1;
        else high = mid;
    }
    while (low < high);

    // 找不到
    return -1;
}

posted @   zjh6  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示