Thread overview
contracts in interfaces
Dec 13, 2012
Yann
Dec 13, 2012
bearophile
Dec 14, 2012
Yann
Dec 14, 2012
Ali Çehreli
Dec 15, 2012
Yann
December 13, 2012
Hi,

could someone tell me what the problem(s) with the following are? Also, how do I make "$" work with the slice operator?

Thanks a lot.

interface Graph
{
  bool opIndex(uint u, uint v)
  in { assert(u < n && v < n); }

  Graph opSlice(uint start, uint end)
  in { assert(start < n && end <= n); }
  //why does this not compile:
  out(g) { assert(g.n == end - start); }

  @property uint n();
}

interface MutableGraph : Graph
{
  bool addEdge(uint u, uint v)
  in { assert(u < n && v < n); }
  //why does this produce a segmentation fault when executed:
  out(ret) { assert(this[u,v]); }
}
December 13, 2012
Yann:

> could someone tell me what the problem(s) with the following are?

>   //why does this not compile:
>   out(g) { assert(g.n == end - start); }
>
>   @property uint n();

n() needs to be const:
    @property uint n() const;



> why does this produce a segmentation fault when executed:

I don't know, you should show us a more complete minimal code that shows the segfault.


> Also, how do I make "$" work with the slice operator?

There is opDollar. But so much time has passed since dmd 2.060, that I don't remember if that works in dmd 2.060 or only in 2.061.

Bye,
bearophile
December 14, 2012
Thanks for your reply!

>>  @property uint n();
> n() needs to be const:
>     @property uint n() const;

Ok. Why is that?

>> why does this produce a segmentation fault when executed:
> I don't know, you should show us a more complete minimal code that shows the segfault.

Here you go (I stripped it down a bit too much the first time). Also, why does "new AdjacencyList(5)" not compile, even though Tdirected has a default value?

(I am very thankful for feedback of any kind about the following)

import std.algorithm;
import std.range;
import std.stdio;
import std.conv;
import std.string;

struct Edge
{
  this(bool exists = true)
  { _exists = exists; }
  bool _exists;
  alias _exists this;
}

interface Graph
{
  Edge opIndex(uint u, uint v)
  in { assert(u < n && v < n); }

  bool addEdge(uint u, uint v)
  in { assert(u < n && v < n); }
  //why does this line crash with Segfault 11 ?
  out(ret) { assert(this[u,v]); }

  @property uint n() const;
}

class AdjacencyListGraph(bool Tdirected = false) : Graph
{
  this(uint n = 0)
  { _adjList = new uint[][](n, 0); }

  Edge opIndex(uint u, uint v)
  {
    if(v < u && !Tdirected)
      swap(u, v);
    return Edge(countUntil(_adjList[u], v) >= 0);
  }

  @property uint n()
  { return cast(uint) _adjList.length; }

  bool addEdge(uint u, uint v)
  {
    if(v < u && !Tdirected)
      swap(u, v);
    if(this[u,v])
      return false;
    _adjList[u] ~= v;
    return true;
  }

  private uint[][] _adjList;
}

void main()
{
  //why do I have to add "!(false)", even though it's the default value?
  Graph g = new AdjacencyListGraph!(false)(5);
  g.addEdge(1,2);
}
December 14, 2012
On 12/14/2012 12:11 AM, Yann wrote:

>>> why does this produce a segmentation fault when executed:

There are quite a few bugs about interface contracts and inherited contracts:

  http://d.puremagic.com/issues/buglist.cgi?quicksearch=interface+contract

Although, I haven't seen one about segmentation faults though.

> //why do I have to add "!(false)", even though it's the default value?
> Graph g = new AdjacencyListGraph!(false)(5);

With struct and class templates, what you currently need to add is the template parameter list, even if empty:

    Graph g = new AdjacencyListGraph!()(5);

That may change in the future.

Ali

December 15, 2012
Thanks for your reply!

I'll investigate further and report a bug if necessary.