module AutoC::Sequential

Method implementations for types which maintain predictable element order (vector, list, queue etc.)

Private Instance Methods

configure() click to toggle source
Calls superclass method
# File lib/autoc/sequential.rb, line 12
def configure
  super
  contains.configure do
    dependencies << find_first
    inline_code %{
      return #{find_first.(*parameters)} != NULL;
    }
  end
  find_first.configure do
    code %{
      #{range} r;
      assert(target);
      for(r = #{range.new.(target)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
        #{element.const_lvalue} e = #{range.view_front.(:r)};
        if(#{element.equal.('*e', value)}) return e;
      }
      return NULL;
    }
  end
  equal.configure do
    code %{
      assert(left);
      assert(right);
      if(#{size.(left)} == #{size.(right)}) {
        #{range} lr, rr;
        for(
          lr = #{range.new.(left)}, rr = #{range.new.(right)};
          !#{range.empty.(:lr)} && !#{range.empty.(:rr)};
          #{range.pop_front.(:lr)}, #{range.pop_front.(:rr)}
        ) {
          #{element.const_lvalue} le = #{range.view_front.(:lr)};
          #{element.const_lvalue} re = #{range.view_front.(:rr)};
          if(!(#{element.equal.('*le', '*re')})) return 0;
        }
        return 1;
      }
      return 0;
    }
  end
  compare.configure do
    code %{
      size_t remaining, ls, rs;
      #{range} lr, rr;
      assert(left);
      assert(right);
      ls = #{size.(left)}; 
      rs = #{size.(right)};
      /* comparing common parts */
      for(
        lr = #{range.new.(left)}, rr = #{range.new.(right)}, remaining = ls < rs ? ls : rs; /* min(ls, rs) */
        remaining > 0;
        #{range.pop_front.(:lr)}, #{range.pop_front.(:rr)}, --remaining
      ) {
        #{element.const_lvalue} le = #{range.view_front.(:lr)};
        #{element.const_lvalue} re = #{range.view_front.(:rr)};
        int c = #{element.compare.('*le', '*re')};
        if(c != 0) {
          return c; /* early exit on first non-equal pair encountered */
        }
      }
      if(ls == rs) {
        return 0; /* both vectors are completely equal */
      } else {
        return ls > rs ? +1 : -1; /* the longer sequence of the two with equal common part is considered "the more" */
      }
    }
  end
  hash_code.configure do
    code %{
      #{range} r;
      size_t result;
      #{hasher.to_s} hash;
      #{hasher.create(:hash)};
      for(r = #{range.new.(target)}; !#{range.empty.(:r)}; #{range.pop_front.(:r)}) {
        #{element.const_lvalue} e = #{range.view_front.(:r)};
        #{hasher.update(:hash, element.hash_code.('*e'))};
      }
      result = #{hasher.result(:hash)};
      #{hasher.destroy(:hash)};
      return result;
    }
  end
end