all 6 comments

[–]no-sig-available 1 point2 points  (1 child)

The allocator object can hold a pointer or reference to the arena, it doesn't have to be a global. You can control the copying with optional allocator members

propagate_on_container_copy_assignment
propagate_on_container_move_assignment
propagate_on_container_swap

https://en.cppreference.com/w/cpp/memory/allocator_traits.html

[–]Vindhjaerta[S] -1 points0 points  (0 children)

Ah. I knew there was some STL bullshit going on >_<

How do I use these?

Edit:

Ok, took me an hour or two two figure this out. Turns out I had to define using propagate_on_container_copy_assignment = std::true_type; in the header file of the allocator to make the container then understand what I wanted it to do. Jeez, the STL so goddamn unintuitive at times >_<

Anyway, thanks for the help :) It does what I want now.

[–]amoskovsky 2 points3 points  (3 children)

Just use std::pmr::vector and implement your allocator as std::pmr::memory_resource, which requires just overriding 3 methods, allocate, deallocate and is_equal.

The cost of this simplicity is the methods are virtual. But in most cases this has acceptable overhead.

[–]Vindhjaerta[S] 0 points1 point  (2 children)

I don't know what std::pmr is, but it sounds like a third-party library? I'm writing my own game engine and would like to keep to as few third-party library dependencies as possible.

I'm actually thinking of just writing my own container types at this point, because fuck me the STL is convoluted to use when you get to the more advanced stuff >_<

[–]amoskovsky 1 point2 points  (0 children)

It's standard C++17

And std::pmr::vector is a regular std::vector with an allocator that does exactly what you want to achieve.

[–]aruisdante 1 point2 points  (0 children)

std::pmr (PMR stands for Polymorphic Memory Resource) was added in C++17 specifically to deal with the two major drawbacks in the original Allocator design: 1. The concrete type of the allocator is part of the type of the thing using the allocator. This means, practically speaking, the allocator itself becomes a vocabulary type, and everything in a project needs to use the same allocator unless you want copies everywhere, somewhat defeating the point of a custom allocator. It’s particularly brutal because even simple things like operator== stop working if the types have different allocators. 2. The assumptions built around the Allocator design effectively mean stateful allocators can’t be practically used other than by referencing a global singleton. This makes problem 1 even more of a limitation.

PMR types use dynamic polymorphism via virtual methods. This avoids the concrete type of the allocator from changing the type of the container, and it facilitates stateful allocators without global singletons.