On Tuesday, 11 November 2014 at 19:23:39 UTC, Adam Taylor wrote:
* i apologize in advance, this is my first post -- the code formatting probably wont turn out so great...

I have a bunch of duck typed interfaces for "containers" similar to what you would find in std.range.

i.e.
template isContainer(C)
{
    enum bool isContainer = is(typeof(
    (inout int = 0)
    {
        C c = C.init;
        ...                                     
    }));
}

template canRemoveFromContainer(C)
{
enum bool canRemoveFromContainer = isContainer!C && is(typeof(
    (inout int = 0)
    {
        C c = C.init;
        c.remove();
    }));
}

Now what i want to do is pass some such "container" object to an interface function:

interface MyInterface
{
void filterCollisions(S)(S collisionCandidates)
    if(canRemoveFromContainer!S)
}

but of coarse templates and interfaces don't get along so well.
 so...so far as I know i would need to do something like this:


interface MyInterface
{
final void filterCollisions(S)(S collisionCandidates)
    if(canRemoveFromContainer!S)
{
filterCollisionsImpl(...);
}

void filterCollisionsImpl(...)

}


and pass something to filterCollisionsImpl that is a "proper" class or interface type.

So here's the problem: many of the "duck-typed" interfaces cannot be converted to proper interfaces without losing something. So is there ANY way to pass in a very basic class or interface Container type and call the remove function on it? Here's what i've tried:

interface Container(C)
{
...
}

template ContainerObject(C) if (isContainer!(Unqual!C)) {
    static if (is(C : Container!(ElementType!C))) {
        alias ContainerObject = C;
    } else static if (!is(Unqual!C == C)) {
        alias ContainerObject = ContainerObject!(Unqual!C);
    } else {

        static if (__traits(compiles, { enum e = C.ValueType; })) {
          alias ValueType = C.ValueType;
        } else {
          alias ValueType = ElementType!C;
        }
                
        class ContainerObject : Container!ValueType {
            C _container;

            this(C container) {
                this._container = container;
            }

            static if(canRemoveFromContainer!C) {
              size_t remove()
              {
                return _container.remove();
              }
            }
        }
    }
}

ContainerObject!C containerObject(C)(C container) if (isContainer!C) {
    static if (is(C : Container!(ElementType!C))) {
        return container;
    } else {
        return new ContainerObject!C(container);
    }
}


interface MyInterface
{
final void filterCollisions(S)(S collisionCandidates)
    if(canRemoveFromContainer!S)
{
  auto container = containerObject(collisionCandidates);
container.remove(); // works just fine -- have the complete type info at instantiation site
  filterCollisionsImpl();
}

void filterCollisionsImpl(Container!string collisionCandidates)
collisionCandidates.remove(); // error -- some type info is lost here, only have a Container!string which doesn't have a remove function.
}
Not entirly sure of what you asking for,but have you tried
inhertance?
----
interface Base(C){
     /+...+/
}

interface Derived(C):Base!C{
     /+...+/
}
----

Reply via email to