Rewrote with CRTP