abstracted template function