D模板:最酷的黑客

时间:2008-10-29 02:11:21

标签: templates metaprogramming d

你在D编程语言中做过或看过的最酷的有点实用的元编程黑客是什么?有点实际意味着排除例如编译时光线跟踪器。

12 个答案:

答案 0 :(得分:9)

An arbitrary precision type它在编译时(编译器之前)生成ASM代码

答案 1 :(得分:8)

Scrapple工具中的DParse是一个模板化的解析器生成器。但是,ldc是唯一一个具有正常运行的编译时间GC的D编译器(但即便如此,它也有几个奇怪的随机崩溃)。我玩了一点,你可以做一些有趣的事情,如配置文件解析和东西,但直到编译时GC完全运行,你不能做大事。

答案 2 :(得分:8)

就彻头彻尾的最酷而言,我不得不说Kirk McDonald的PyD(和其他类似的绑定),因为它们在检测和处理许多不同类型方面做了大量的工作,作为复杂的代码生成。

也就是说,PyD只会赢,因为BLADE在技术上使用CTFE,而不是模板。

从更个人的角度来看,D模板已经在我的研究项目中得到了广泛的应用。它是一个模拟框架,模块可以在其中定义自己的私有数据类型。向框架公开新的用户类型需要一行代码,它为类型创建XML解析器以及关联的网络序列化/反序列化代码。

答案 3 :(得分:7)

D/Objective-C Bridge使用模板让你在D中操作Cocoa对象。

答案 4 :(得分:6)

我最喜欢的是来自tools.base的ElemType和KeyType:

template ElemType(T) {
  alias typeof((function() {
    foreach (elem; Init!(T)) return elem; assert(false);
  })()) ElemType;
}

template KeyType(T) {
  alias typeof((function() {
    foreach (key, elem; Init!(T)) return key; assert(false);
  })()) KeyType;
}

答案 5 :(得分:6)

Compile time string hashing。您可以使用它来混淆代码中的嵌入字符串。只需搜索“哈希”。该页面上还有其他一些有趣的样本。

答案 6 :(得分:6)

A united type template struct(它不会让你犯单位错误。)

答案 7 :(得分:6)

一个例子是D标准库中的bitfields工具,它从用户指定的布局开始生成位字段操作的代码。

Tuple facility是另一个例子。它根据用户提供的类型和可选名称生成元组。除了注入指定的字段外,没有很多生成的umph,但我认为这是一个说明性的例子。

在不知道Lambert的漏洞利用的情况下,我刚刚将memoize添加到标准库中 - 请参阅here获取文档,here获取代码,here获取相关新闻组讨论。

我工作的另一个工具是高阶函数,它将整数或实值函数制成表格(例如,提供快速指数)。那尚未准备好发布。

一旦在编译期间允许创建对象,将很容易创建,例如正则表达式引擎,在编译期间执行所有自动生成。

答案 8 :(得分:5)

我会回答我自己的问题,因为当我问这个时,这个问题不存在。我给垃圾收集器写了一个补丁,它使用模板和编译时内省来生成任意复杂的用户定义类型的指针偏移信息,以便进行精确的堆扫描,而不是在编译器中完成。

答案 9 :(得分:4)

我写了一个memoize()函数,其标题是这个(这里的代码有点长):

自动记忆(TFunc)(TFunc func);

它的作用是,你给它一个函数的地址,它返回一个强类型的委托(与原始函数相同的签名和返回类型)缓存原始函数的返回值,以便用它调用它两次相同的参数只调用底层函数一次。例如,这里是斐波纳契序列的一个记忆的“递归”定义,它以线性而非指数的时间执行:

uint fib(uint n) {return n> 0? n> 1? memoize(& fib)(n - 1)+ memoize(& fib)(n - 2):1:0; }

您可以正常调用它,如:fib(1000);


编辑:我发布的链接之前的代码相当可怕; this version is much more elegant

答案 10 :(得分:2)

Mixins用于从Stream对象读取和写入简单结构:

template TStructReader() {
        private alias typeof(*this) T;
        static T opCall(Stream stream) {
                assert(stream.readable);
                T ret; stream.readExact(&ret, T.sizeof);
                return ret;
        }
}

template TStructWriter() {
        private alias typeof(*this) T;
        void write(Stream stream) {
                assert(stream.writeable);
                stream.writeExact(this, T.sizeof);
        }
}

像这样使用:

align (1) struct MyStruct {
        ... definitions here ...
        mixin TStructReader;
        mixin TStructWriter;
}

auto ms = MyStruct(stream);
ms.write(stream);

答案 11 :(得分:2)

LuaD还广泛使用元编程与Lua无缝交互。 您可以使用单个命令注册整个类。