customized ERL_NIF_TERM type support
Daniel Goertzen <[email protected]> Fri, 7 Feb 2014 11:34:14 -0600
| Newsgroups | gmane.comp.lang.erlang.patches |
|---|---|
| Message-ID | <CAJCf5RxSjiO4jRKngbToPWyyWwXQz2Vbu5niqQquDda1Wd-FgA@mail.gmail.com> |
When writing NIFs in C++, it is impossible to employ C++ function
overloading because the underlying type of ERL_NIF_TERM is "unsigned int".
For example:
// won't compile :(
#include <erl_nif.h>
void my_func(ERL_NIF_TERM a) {...}
void my_func(unsigned int a) {...}
This patch allows NIF authors to mutate the type of ERL_NIF_TERM by
defining the macro CUSTOM_NIF_TERM_TYPE(). In the example below, the
underlying unsigned integer type gets wrapped as a C++11 typed
enumeration. The type of ERL_NIF_TERM is now unique and can be used in
overloaded functions.
// compiles! :)
#define CUSTOM_NIF_TERM_TYPE(Type) enum class ERL_NIF_TERM : Type {};
#include <erl_nif.h>
void my_func(ERL_NIF_TERM a) {...}
void my_func(unsigned int a) {...}
The patch has no impact on erl_nif.h if CUSTOM_NIF_TERM_TYPE is not defined
(other than flipping the definition order of ERL_NIF_TERM and ERL_NIF_UINT).
A similar approach has been used on my C++11 NIF wrapper (
https://github.com/goertzenator/nifpp). The wrapper requires manual
installation of a similar patch, and I would love to remove that
requirement.
Regards,
Dan.
_______________________________________________
erlang-patches mailing list
[email protected]
http://erlang.org/mailman/listinfo/erlang-patches
custom_erl_nif_term.patch
(text/x-patch, 889 B)
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index 7613446..e6d7ca6 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -93,17 +93,21 @@ #endif #ifdef HALFWORD_HEAP_EMULATOR # define ERL_NIF_VM_VARIANT "beam.halfword" -typedef unsigned int ERL_NIF_TERM; +typedef unsigned int ERL_NIF_UINT; #else # define ERL_NIF_VM_VARIANT "beam.vanilla" # if SIZEOF_LONG == SIZEOF_VOID_P -typedef unsigned long ERL_NIF_TERM; +typedef unsigned long ERL_NIF_UINT; # elif SIZEOF_LONG_LONG == SIZEOF_VOID_P -typedef unsigned long long ERL_NIF_TERM; +typedef unsigned long long ERL_NIF_UINT; # endif #endif -typedef ERL_NIF_TERM ERL_NIF_UINT; +#ifdef CUSTOM_NIF_TERM_TYPE +CUSTOM_NIF_TERM_TYPE(ERL_NIF_UINT) +#else +typedef ERL_NIF_UINT ERL_NIF_TERM; +#endif struct enif_environment_t; typedef struct enif_environment_t ErlNifEnv;