text: static_assert(sizeof (VecOf<char>) == sizeof (void*) + 8);
  static_assert(sizeof (VecOf<int>)  == sizeof (void*) + 8);
  
  uint32_t vec::hash (uint8_t const* p, uint32_t n) {
      // see http://www.cse.yorku.ca/~oz/hash.html
      uint32_t h = 5381;
      for (uint32_t i = 0; i < n; ++i)
          h = ((h<<5) + h) ^ p[i];
      return h;
  }
  
  void VaryVec::atAdj (uint32_t idx, uint32_t len) {
      //assert(idx < _fill);
      auto olen = atLen(idx);
      if (len == olen)
          return;
      auto ofill = _fill;
      _fill = pos(_fill);
      if (len > olen)
          ByteVec::insert(pos(idx+1), len - olen);
      else
          ByteVec::remove(pos(idx) + len, olen - len);
      _fill = ofill;
  
      for (uint32_t i = idx + 1; i <= _fill; ++i)
          pos(i) += len - olen;
  }
  
  void VaryVec::atSet (uint32_t idx, void const* ptr, uint32_t len) {
      atAdj(idx, len);
      memcpy(begin() + pos(idx), ptr, len);
  }
  
  void VaryVec::insert (uint32_t idx, uint32_t num) {
      //assert(idx <= _fill);
      if (capacity() == 0) {
          ByteVec::insert(0, 2);
          pos(0) = 2;
          _fill = 0;
      }
  
      auto ofill = _fill;
      _fill = pos(_fill);
      ByteVec::insert(2 * idx, 2 * num);
      _fill = ofill + num;
  
      for (uint32_t i = 0; i <= _fill; ++i)
          pos(i) += 2 * num;
      for (uint32_t i = 0; i < num; ++i)
          pos(idx+i) = pos(idx+num);
  }
  
  void VaryVec::remove (uint32_t idx, uint32_t num) {
      //assert(idx + num <= _fill);
      auto diff = pos(idx+num) - pos(idx);
  
      auto ofill = _fill;
      _fill = pos(_fill);
      ByteVec::remove(pos(idx), diff);
      ByteVec::remove(2 * idx, 2 * num);
      _fill = ofill - num;
  
      for (uint32_t i = 0; i <= _fill; ++i)
          pos(i) -= 2 * num;
      for (uint32_t i = idx; i <= _fill; ++i)
          pos(i) -= diff;
  }
  