template cannot split easily, so I combine them into a head file