On Thursday, 28 March 2013 at 17:30:24 UTC, deadalnix wrote:
On Thursday, 28 March 2013 at 09:23:27 UTC, Moritz Maxeiner
wrote:
I don't, I do:
alias uint Foo;
enum : Foo
{
FooA,
FooB,
FooC
}
which is a direct translation of the C enums. It gives the
enum items no named scope, only creates an (alias) type for
them. See
https://github.com/Calrama/llvm-d/blob/master/llvm/c/constants.d
and
https://github.com/Calrama/llvm-d/blob/master/llvm/c/types.d
Ho sorry, I missed that. That is still inferior as it doesn't
introduce its own type now.
No problem, if you mean a strict/strong type, iirc (correct me if
I'm wrong, though) that is the case for C enums as well. I can
change the alias to typedef, though, if it is really that
important.
D enums introduce a scope, when C's don't. So C need to
prefix enums entries manually, when in D it isn't required.
The C to D translation goes as follow : FooA => Foo.A instead
of Foo.FooA .
That is not the D equivalence of the C code. That is how D
improves upon C enums. The equivalence and thus the
translation is to not use a named scope as seen above.
This is why I used the word translation. A good translation
doesn't repeat stupidly, but uses idoms of the target language.
Generally I would agree, but I'm translating the declarations of
an interface here, not porting the implementation. And as such
the content of the D interface imho should match the content of
the C interface, meaning a literal translation, even if that
makes it stupid from the D perspective. The *only* exception to
that is the file structure as C headers are different things than
D modules and there's no 100% match in D for C headers. D
interface files (.di) would probably be technically the closest
thing.
If the goal isn't to follow LLVM's source as closely as
possible, I think this is the way to go.
It does follow the LLVM C API source code as closely as
possible. It just uses a module structure different from
LLVM's C API header structure for the reasons stated above,
which does not change how to use the C API (As you should do
"import llvm.c.all" either way). This is also not a new
approach, Derelict (one of the major providers for D bindings
to C libraries other than deimos) has been doing it for a long
time.
It doesn't follow as closely as possible as the way code is
structured is part of the code.
The way the code (in C) is structured is preserved in the D
modules by grouping and documentation tags. The C header file
structure itself is lost, yes, but not the logical structure it
represent. As such I don't see any vital information being lost
compared to translating the C headers as D modules.
I also don't see the consistency between that choice and the
enum one.
It is only consistent under the directive "Follow the original C
API code as closely as possible while minimizing the amount of
work needed to maintain the result", not in a general sense, but
consider this:
Your enum choice would create a break in the documentation, as
the enum items would not match what is written in the LLVM
doxygen documentation anymore (which means I would have to
provide documentation for that difference); that also holds true
for the file structure, of course, but since you'll get the
entire C API with one import anyway ("import llvm.c.all") there's
no additional documentation needed there (it is covered by the
already existing examples).
If you want proper D enums (with names), though, they'll be
present in the D API - mapping to the C bindings' enum's items.