-
Notifications
You must be signed in to change notification settings - Fork 5
Provide fully templated encoders and decoders #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
96a8e8a
to
fece407
Compare
Hey @brodeuralexis! This is an interesting idea, but I am not sure if it actually has the desired benefits. In practice C++ NIFs are almost always used to integrate a third-party C/C++ library, where a lot of allocations happen internally and is rather not configurable. On a separate note, there is also a usability tradeoff. If we introduce |
To be honest, I hold no particular opinion on whether this should be included or not. I mainly submitted this work because I am writing my libbpf wrapper with fine, and found those features could prove useful.
True, and most do it because it is a pain in the ass, and requires all the code to be in header files. To my knowledge, that is also why
I created those typedefs because I found typing Food for though
|
I would say it's ok to start with 1. and upstream more changes if it comes up again, but looking at the decoders again, I've realised that we need a |
I'll rework the code to go with 1. |
a14bea3
to
30ba27a
Compare
README.md
Outdated
|
||
std::pmr::memory_resource* my_memory_resource = ...; | ||
|
||
std::vector<std::pmr::string, MyAllocator<std::pmr::string>> duplicate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the return also be std::pmr::vector
?
I would also be fine not having this section, because it might be one of the things where people who would think about using allocators would already know about those things. In this PR we just generalise the templates, so it's closer to how they would use the STL anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I wanted a mix of stateless (std::vector
) and stateful allocations (std::pmr::string
) to ensure that both can be encoded correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, the thing is that it's a usage example, and I would expect actual usage to consistently use either allocator type, not both. In other words, I wouldn't show code that the user wouldn't actually ever write. Again, I may be wrong!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[...] I wouldn't show code that the user wouldn't actually ever write.
Also links to #5 (comment).
I will make the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, so should we use the same allocator for both then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With my latest changes, only struct Allocator
is left, and is used for testing both encoding and decoding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! What I mean is that the example still shows a mix of both allocators (std::vector
and std::pmr::string
), which is probably not something they would do in practice?
In other words, I would mention stateless allocators and make the example use std::vector
and std::string
, both with MyAllocator
. Then, below, I would have the note about about polymorphic_allocator
and get_default_resource
.
Does that make sense?
This commits provides a templated allocator for STL containers and a memory resource for `std::pmr::polymorphic_allocator`. This enables the use of `enif_alloc` and `enif_free` from all STL containers while leave the user the choice to use templates or polymorphism to select an allocator.
Now, when decoding `std::pmr::*` STL containers, `fine::memory_resource` will be used instead of the default `std::pmr::get_default_resource()` memory resource.
The `operator[]` on `std::map` will default construct the value if it does not exist, and then move assign it the requested value. By using the C++17 method `insert_or_assign`, we prevent that extra object construction.
fine::Allocator and fine::memory_resource were deemed too complicated for use by users. On the flip side, we keep the templated allocators during encoding and decoding, ensuring that users can implemented their own stateless allocator for decoding and use any possible allocator for encoding.
Information about allocators is remove from the Encoding/Decoding section of the README.md. A column indicating the Elixir type associated with the C++ type has been added.
Co-authored-by: Jonatan Kłosko <[email protected]>
Co-authored-by: Jonatan Kłosko <[email protected]>
f86170d
to
3fd4d26
Compare
@@ -1,5 +1,6 @@ | |||
#include <cstring> | |||
#include <exception> | |||
#include <memory_resource> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include <memory_resource> |
test "allocators" do | ||
assert NIF.allocators("abc", 16) == | ||
["abc"] |> Stream.cycle() |> Stream.take(16) |> Enum.to_list() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw. I would add it to this test:
fine/test/test/finest_test.exs
Lines 145 to 146 in 66bd25f
test "vector" do | |
assert NIF.codec_vector_int64([1, 2, 3]) == [1, 2, 3] |
something like this:
assert NIF.codec_vector_int64_alloc([1, 2, 3]) == [1, 2, 3]
Since we focus on encoding/decoding working as expected :)
This PR provides a templated allocator for STL containers and a memory resource for
std::pmr::polymorphic_allocator
.This enables the use of
enif_alloc
andenif_free
from all STL containers while leaving the user the choice to use templates or polymorphism to select an allocator.EDIT: Following the discussion below, the scope of this PR has been restrained to fully templated encoders and decoders. If a user wants a stateless allocator using
enif_alloc
andenif_free
they can create one themselves.