Здравствуйте, malegkin, Вы писали:
1. Конструкции return std::move обычно вредны, потому как ломают RVO.
2. в функции rotate() цикл видимо должен начинаться так for (size_t j = i + 1 ... иначе не понятно кто с кем меняется. Вообще функция мутная, я что-то не разобрался, что она делает

3. в функции merge неплохо бы сделать out.reserve(SQUARE_DIMENSION). Также это неплохо бы сделать в функции read_square() line.reserve(SQUARE_DIMENSION) потому как функция getline вычитывает из потока посимвольно
в остальном мне код понравился