25-Sep-2013 00:39, Andrei Alexandrescu пишет:
On 9/24/13 1:02 PM, Dmitry Olshansky wrote:
24-Sep-2013 19:56, Andrei Alexandrescu пишет:
It could, but as I mentioned to Manu - at this level any cost is
significant. Even changing from a compile-time constant to a global
static dynamically-initialized constant has a cost. Making alignment an
instance variable turns stateless allocators into stateful ones.
Hm most could just get away with an enum. Am I missing something?
Right now I do things like:
struct DopeAllocator(Allocator, Dope)
{
static assert(Allocator.alignment >= Dope.alignof,
"DopeAllocator does not work with allocators offering a smaller"
" alignment than the dope alignment.");
static assert(!hasElaborateDestructor!Dope,
"DopeAllocator: ellaborate destructors for Dope not
implemented.");
enum alignment = Dope.alignof;
...
}
But it's a boiler plate regardless.
What if we are to provide the tools to manipulate said alignment
composition (some imaginary templates in action):
alias alignment = requireAlignment!(Allocator,
Dope.alignof).overrideAlignment!(Dope.alignof);
Which in this case would unfold to a proper primitive that tests
alignment of Allocator at RT or CT, and then return fixed value as new
alignment.
Such code would be significantly more involved if Allocator had the
freedom to define alignment as either an enum, a static method, or a
member function.
Well you solved static vs member function issue already (via singleton).
I'm hoping to get away with a static function "static uint alignment()"
that (a) is CTFEable for most allocators/platforms, (b) uses a
dynamically-initialized static constant for a few. Then derived
allocators will inherit CTFEability.
A check for CTFE-ablity might do the trick. The run-time dependent ones
usually would immediately hit a wall that is a sys-call or WinAPI.
It does. It's just some more work. Guess I'd need to put it in.
Would a per-allocator-type alignment suffice?
I see alignment as an inherent property of the way an allocator acquires
memory.
The question remains, is it a property of the allocator _object_ or a
property of the allocator _type_? I.e. do we need to support allocators
that store alignment as a nonstatic member variable?
Sad but true one can't determine the actual alignment of some
important ones at CTFE. Even worse adapters would in turn depend on
these system-specific run-time values such as half a page, 2 cache lines
etc.
auto my2PageAligner = AligningAllocator(page_size*2, rootAllocator)
where page_size is calculated elsewhere.
That can be made to work, it's just that page_size would be a static
variable that the user must set (not a template argument).
Right. So another angle to the problem is that maybe we could just
provide a set of run-time "base" values for alignment. Then one can use
say x-page alignment defining x at compile-time.
The only problem I foresee with this is that: std.allocator is ill
suited to determine all base alignments it may need.
Say a certain kind of disk sector size (some 3rd party code), or DMA
block size (or what it's called) on some system. Maybe it's that 1% that
is not worth it but I dunno.
expand should do the trick. I think that nicely saves on primitives
count. But we may have to add a 'shrink' if you are so bent on never
decreasing size in expand :)
And ... reallocate doesn't cut it as long as there is no big red tape on
it that says - if decreasing the size reallocation it is ALWAYS in-place
(it might not be true for some allocators - e.g. realloc doesn't
guarantee even this IIRC).
OK, I'm willing to add the optional method shrink(void[], size_t
newSize) if expand() and realloc() are insufficient.
Okay let it be shrink. If the @safety of expand is that important and
the fact it may make no sense to shrink on a call to expand. Honestly I
could see a lot of code doing things like
if(newSize < oldSize) shrink(...)
else if(newSize > oldSize) expand(...)
Maybe it's fine.
Indeed realloc()
does not guarantee immovability, and we also shouldn't because
Mallocator must be compatible the C API.
Spawn of Satan :)
--
Dmitry Olshansky