May 02, 2017
On Monday, 1 May 2017 at 16:31:10 UTC, Nick Sabalausky (Abscissa) wrote:

> If we had a type similar to TaggedAlgebraic...
>
> Destroy?

It's too strict: you have to specify concrete types beforehand. This spills over into user code and makes it far less versatile that can be achieved.
Currently with allocators we have two extremes: IAllocator (and now, ISharedAllocator) that carries *no* static type information about concrete implementation, *and* loses all the inference regarding @nogc and shared memory. On the other end it's CAllocatorImpl that carries *both*.
But for user code, what is desirable is to have a middle man: a type that erases concrete allocator type but still keeps the @nogc and/or shared. This would enable user types to exchange their allocators while keeping static checks afforded by the language.
This can be done e.g. like this:

enum AllocatorTraits
{
    none            = 0x00,
    noGC            = 0x01,
    sharedMemory    = 0x02,
    sharedInstance  = 0x04,
}

mixin template AllocatorInterface()
{
    Ternary owns(Block block) @nogc;
    Ternary resolveInternalPointer(void* p, ref Block result) @nogc;
    Ternary empty() const @nogc;

    Block allocate(size_t, TypeInfo ti = null);
    Block alignedAllocate(size_t, uint);
    Block allocateAll();
    bool expand(ref Block, size_t);
    bool reallocate(ref Block, size_t);
    bool alignedReallocate(ref Block, size_t, uint);
    bool deallocate(Block block);
    bool deallocateAll();
}

template IAllocatorImpl(AllocatorTraits traits)
{
    static if (traits & AllocatorTraits.sharedInstance)
        alias Base = ISharedAllocator;
    else
        alias Base = IAllocator;

    interface IAllocatorImpl : Base
    {
        static if (traits & AllocatorTraits.sharedMemory)
            alias Block = shared(void)[];
        else
            alias Block = void[];

        static if (traits & (AllocatorTraits.sharedInstance | AllocatorTraits.noGC))
            @nogc shared { mixin AllocatorInterface!(); }
        else static if (traits & AllocatorTraits.sharedInstance)
            shared { mixin AllocatorInterface!(); }
        else
            @nogc { mixin AllocatorInterface!(); }

        mixin AllocatorInterface!();
    }
}

...and make the allocatorObject() function return IAllocatorImpl!traits instead of CAllocatorImpl!Allocator. With such IAllocatorImpl, user code can specify concrete expectations about the allocator without needing to know the exact allocator type.
May 02, 2017
On Tuesday, 2 May 2017 at 02:51:02 UTC, Stanislav Blinov wrote:

Lost one else. Should be

         static if (traits & (AllocatorTraits.sharedInstance |
 AllocatorTraits.noGC))
             @nogc shared { mixin AllocatorInterface!(); }
         else static if (traits & AllocatorTraits.sharedInstance)
             shared { mixin AllocatorInterface!(); }
         else static if (traits & AllocatorTraits.noGC)
             @nogc { mixin AllocatorInterface!(); }
         else
             mixin AllocatorInterface!();

May 02, 2017
On 05/01/2017 10:51 PM, Stanislav Blinov wrote:
> On Monday, 1 May 2017 at 16:31:10 UTC, Nick Sabalausky (Abscissa) wrote:
>
>> If we had a type similar to TaggedAlgebraic...
>>
>> Destroy?
>
> It's too strict: you have to specify concrete types beforehand.

No, that's why my suggestion was:

"If we had a type similar to TaggedAlgebraic, but was an open variant rather than a closed algebraic (Ie, a type like Phobos's Variant, but forwarded member access without first requiring explicit conversion to the exact underlying type),"



May 02, 2017
On Monday, 1 May 2017 at 07:42:19 UTC, Sebastiaan Koppe wrote:
> On Friday, 28 April 2017 at 22:18:54 UTC, Atila Neves wrote:
>> Done. I also added to the README that it has its own versions of the range constraints from Phobos that can be used with `@models`.
>>
>> Atila
>
> Example of an error message in the README would be great too.

Good point, done.

Atila
May 07, 2017
On Monday, 1 May 2017 at 13:00:27 UTC, Andrei Alexandrescu wrote:
> On 05/01/2017 08:12 AM, Guillaume Piolat wrote:
>> On Sunday, 30 April 2017 at 21:43:26 UTC, Andrei Alexandrescu wrote:
>>>
>>> A pass through the root allocators (Mallocator, GCAllocator etc)
>>> figuring out what attributes could be meaningfully attached would be
>>> welcome. The rest would rely on inference.
>>>
>>>
>>> Thanks,
>>>
>>> Andrei
>>
>> IAllocator being fully @nogc would be a comforting guarantee, as runtime
>> dispatch makes for lighter types.
>
> As I said (and am encouraging you to do this), this is achieved through simple variance:
>
> interface INoGCAllocator : IAllocator {
>    ... override all methods here as @nogc ...
> }
>
> This is possible because a @nogc method may override one that is not @nogc. @nogc being more restrictive it is contravariant with no-@nogc.
>
> Also IAllocator should have a few @nogc methods to start with; there's no reason e.g. for empty() to create garbage.
>
> Could you please initiate a PR?
>
>
> Andrei

To follow this discussion up, and in light of yesterday's Collections presentation at DConf, I though I'd go ahead and make a basic implementation of traits-based IAllocator.

You can find it here:

https://github.com/radcapricorn/alloctraits

It pretty much evades the shortcomings of IAllocator, alleviates the need for any additional interfaces (ISharedAllocator et al.), at the cost of making user code slightly more verbose. But that is a small price to pay if we want to benefit from the type system.
The current implementation lacks a few features of std.experimental.allocator (i.e. passing implementation by pointer), which are easy to add, I was just focused mainly on roughing out the design as the first step.

Anyone interested, feel free to comment, improve, bash, destroy...
May 07, 2017
On 5/7/17 1:30 PM, Stanislav Blinov wrote:
>>
> 
> To follow this discussion up, and in light of yesterday's Collections presentation at DConf, I though I'd go ahead and make a basic implementation of traits-based IAllocator.
> 
> You can find it here:
> 
> https://github.com/radcapricorn/alloctraits

Cool, thanks. Before we saw that, Eduard and I are working on a similar solution along the lines of IAllocator!(Flag!"nogc", Flag!"safe"). -- Andrei
May 07, 2017
On Sunday, 7 May 2017 at 11:46:33 UTC, Andrei Alexandrescu wrote:
> On 5/7/17 1:30 PM, Stanislav Blinov wrote:
>>>
>> 
>> To follow this discussion up, and in light of yesterday's Collections presentation at DConf, I though I'd go ahead and make a basic implementation of traits-based IAllocator.
>> 
>> You can find it here:
>> 
>> https://github.com/radcapricorn/alloctraits
>
> Cool, thanks. Before we saw that, Eduard and I are working on a similar solution along the lines of IAllocator!(Flag!"nogc", Flag!"safe"). -- Andrei

I guess the exact representation of "traits" is something to decide on. I have to say, even though I used the BitFlags-based solution, I'm not a big fan of that, the syntax is a bit unwieldy. Then again, Flag-based would be too.
Perhaps a struct with enum members could be used...
1 2 3
Next ›   Last »