use functor and function adaptors