#include <functional>
#include <iostream>
#define uint unsigned int
template<typename T>
void merge(
    uint const size_a, T const *a,
    uint const size_b, T const *b,
    uint const size_m, T *m,
    bool(*const is_ordered)(T const &, T const &)
    // std::function<bool(T const &, T const &)> const is_ordered
) {
    uint len = size_a + size_b;
    if(len > size_m)
        len = size_m;
    T const *a_end = a + size_a;
    T const *b_end = b + size_b;
    T *const m_end = m + len;
    while(m < m_end && a < a_end && b < b_end)
        *m++ = is_ordered(*a, *b) ? *a++ : *b++;
    while(m < m_end && a < a_end) *m++ = *a++;
    while(m < m_end && b < b_end) *m++ = *b++;
}
int main(int const argc, char const *const argv[]) {
    uint const size_a = 4;
    uint const size_b = 5;
    uint const size_m = size_a + size_b;
    float *a = new float[size_a] {   1,    3,       6, 7       },
          *b = new float[size_b] {      2,    4, 5,       8, 9 },
          *m = new float[size_m]; // 1, 2, 3, 4, 5, 6, 7, 8, 9 <- expected
    merge<float>(
        size_a, a,
        size_b, b,
        size_m, m,
        [](float const &a, float const &b) -> bool { return a <= b; }
    );
    for(float *p = m; p < m + size_m; ++p)
        std::cout << " " << *p;
    for(float *p : { a, b, m }) delete[] p;
    return 0;
}
#undef uint