Skip to content

Commit

Permalink
[330] - Did you know that C++17 added std::pmr::polymorphic_allocator?
Browse files Browse the repository at this point in the history
  • Loading branch information
kris-jusiak committed May 14, 2023
1 parent 83039db commit 7988623
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Tips

* [[330]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/330.md) - Did you know that C++17 added std::pmr::polymorphic_allocator?
* [[329]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/329.md) - Did you know about C++ allows to pass Pointer To Member Function via template parameter?
* [[328]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/328.md) - Did you know that C++23 extended floating-point types?
* [[327]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/327.md) - Did you know that C++17 added `std::forward_as_tuple` and `std::make_from_tuple` and what’s the difference between them?
Expand Down
68 changes: 68 additions & 0 deletions tips/329.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,72 @@ int main() {

> https://godbolt.org/z/q7n71h97z

</p></details><details><summary>Solutions</summary><p>

```cpp
constexpr auto dispatch = []<auto Type, typename... Msgs>(
auto& out, const auto& buffer) {
const auto type = static_cast<const header*>(buffer)->*Type;
(
[&]() {
switch (type) {
case Msgs::id:
const auto& msg = *static_cast<const Msgs*>(buffer);
::dispatch(out, msg);
break;
}
}(),
...);
};
```

> https://godbolt.org/z/7PMv1GE98
```cpp
constexpr auto dispatch = []<auto pm, class... Ts>(std::ostream& out,
const void* buffer) {
const auto type = static_cast<const header*>(buffer)->*pm;

std::variant<std::monostate, Ts...> v;
(
[&]() {
if (type == Ts::id) {
v = *static_cast<const Ts*>(buffer);
}
}(),
...);

return std::visit(overload{[&](auto&& msg) { ::dispatch(out, msg); },
[](std::monostate) {}},
v);
};
```

> https://godbolt.org/z/4Pz33K4Pq
```cpp
constexpr auto dispatch = []<auto Ptr, class... MessageTypes>(
auto& out, auto buffer) -> void {
const auto helper = [&]<class M>(const M* m) {
if (m->*Ptr == M::id) {
::dispatch(out, (M)(*reinterpret_cast<const M*>(buffer)));
}
};
(helper(reinterpret_cast<const MessageTypes*>(buffer)), ...);
};
```
> https://godbolt.org/z/sYGdEjq5q
```cpp
constexpr auto dispatch = [&]<auto Ptr, class... Ts>(std::stringstream& out,
const void* buffer) {
((reinterpret_cast<const header*>(buffer)->*Ptr == Ts::id &&
(::dispatch(out, *reinterpret_cast<const Ts*>(buffer)), true)) ||
...);
};
```

> https://godbolt.org/z/acvzx1re7

</p></details>
61 changes: 61 additions & 0 deletions tips/330.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<details open><summary>Info</summary><p>

* **Did you know that C++17 added std::pmr::polymorphic_allocator?**

* https://eel.is/c++draft/mem.res.syn#header:%3cmemory_resource

</p></details><details open><summary>Example</summary><p>

```cpp
#include <memory_resource>
#include <cassert>

int main() {
// Create a memory resource
std::pmr::monotonic_buffer_resource resource(1024);

// Create a polymorphic allocator using the memory resource
std::pmr::polymorphic_allocator<int> allocator(&resource);

// Allocate memory for an array of 10 integers using the polymorphic allocator
int* ptr = allocator.allocate(10);

// Test that the allocation was successful
assert(ptr);

// Deallocate the memory
allocator.deallocate(ptr, 10);
}
```

> https://godbolt.org/z/1h7voEGo6
</p></details><details open><summary>Puzzle</summary><p>

* **Can you create pmr::vector which will use pmr::monotonic_buffer_resource/pmr::polymorphic_allocator?**

```cpp
#include <memory_resource>
#include <vector>

int main() {
using namespace boost::ut;
std::array<char, 1024> buffer{};

"pmr"_test = [&buffer] {
std::pmr::vector<char> vec{}; // TODO

vec.push_back('a');
vec.push_back('b');
vec.push_back('c');

expect(vec[0] == 'a' and vec[1] == 'b' and vec[2] == 'c');
expect(std::string_view(buffer.data(), buffer.size()).contains("abc"));
};
}
```

> https://godbolt.org/z/o1hx1fdEn
</p></details><details><summary>Solutions</summary><p>
</p></details>

0 comments on commit 7988623

Please sign in to comment.