std lib iterators unnecessarily require value copies
### Description

When iterating over the pairs of a `Table` or (or indeed any other std lib type with a custom iterator), there's no fundamental reason why a copy of the keys/values should be needed and indeed, it is significantly expensive to require one for anything but non-trivial table entries. 

Apart from being broadly inefficient, it also makes it hard to use move-only types in general because they can no longer be used with std containers.

```nim
import std/tables
type NoCopies = object

proc `=copy`(a: var NoCopies, b: NoCopies) {.error.}

var t: Table[int, NoCopies]
t[3] = NoCopies() # only moves
for k,v in t.pairs(): # lent values, no need to copy!
  echo "found entry"
```


### Nim Version

2.2

### Current Output

```text
Error: '=copy' is not available for type <NoCopies>; requires a copy because it's not the last read of 't.data[h].val'; routine: main
```

### Expected Output

```text

```

### Known Workarounds

_No response_

### Additional Information

_No response_