# Laboratorio de la semana 4: un `Vector` propio

Los comandos se corren desde `code/week-04`. La teoría está en los apuntes de la semana.
Esta semana hay una sola sesión, de 2 horas, porque la otra es la Práctica 1.

| Archivo | Qué es | ¿Lo cambian? |
|---|---|---|
| `vector.h` | La clase, con los invariantes y `check_invariants`; cada función con `TODO` es suya | **Sí** |
| `vector_tests.cpp` | Las pruebas | No |
| `growth_bench.cpp` | El programa que mide y cuenta | No |
| `report.md` | Su explicación de la medición | **Sí** |
| `../tracked.h` | El tipo que cuenta copias y movimientos | No |
| `../bench.h` | El medidor de la semana 3 | No |

```sh
make lab                               # compila en build/lab/
build/lab/vector_tests                 # lista las pruebas
build/lab/vector_tests push_and_read   # corre una
make test-lab                          # comprueba todo; falla hasta que terminen
```

Las pruebas corren con ASan: una fuga o un acceso inválido hacen fallar la prueba.

## Parte 1: lo básico (35 minutos)

Lean los invariantes de `vector.h`. Escriban el destructor, `size`, `capacity`, las dos versiones
de `operator[]`, `reserve`, las dos versiones de `push_back` y `pop_back`. Para `reserve`, usen
el molde de `copy_block.cpp`.

Deben pasar: `starts_empty`, `push_and_read`, `capacity_doubles`, `pop_keeps_capacity`,
`reserve_is_exact`, `reserve_on_empty_then_push`, `step_growth_counts`, `every_slot_is_alive`,
`growth_builds_every_slot`.

## Parte 2: la regla de cinco (25 minutos)

Ya la escribieron para `Stack<T>` en la semana 2, y aquí es la misma idea. Escriban el constructor
de copia, la asignación de copia, el constructor de movimiento y la asignación de movimiento.

Deben pasar: `copy_is_deep`, `copy_of_empty_has_no_block`, `copy_assign_replaces`,
`copy_assign_to_itself`, `move_builds_nothing`, `moved_from_can_be_reused`,
`move_assign_frees_old_block`, `move_assign_to_itself`.

## Parte 3: las pruebas que cuentan (25 minutos)

Lean `tracked.h` y corran las pruebas que quedan. Si fallan, la pista está en los apuntes.

- `growth_moves_when_noexcept`, `growth_copies_without_noexcept`, `lvalue_push_copies_once`,
  `rvalue_push_does_not_copy`, `move_only_elements`: cuándo se copia y cuándo se mueve.
- `push_own_element_when_full`: `v.push_back(v[0])` con el vector lleno.
- `failed_growth_changes_nothing`: una copia falla a mitad del crecimiento.
- `random_against_std_vector`: 20000 operaciones al azar, con semilla fija.

## Parte 4: medir y explicar (25 minutos)

```sh
make lab
build/lab/growth_bench
```

`growth_bench` se compila con `-O2` y sin sanitizers, y cada tiempo es la mediana de 5
repeticiones. Los tiempos dependen de la máquina: lo que se compara es por cuánto se multiplican
cuando n se duplica. Córranlo tres veces y respondan `report.md` con sus números.

Quedan unos 10 minutos para preguntas. Lo que no terminen en la sesión lo terminan antes de la
siguiente, en la que ya empieza el deque.
