#C++, 79 bytes

<!-- language-all: lang-c++ -->

    #include<utility>
    [](auto a,auto b){while(a-b)*a%2?++a:(std::swap(*--b,*a),a);}

If you already use `<utility>`, the function itself is 61 bytes.

This function accepts a pair of iterators (which must be random access iterators), and steadily moves them towards each other.  When `a` points to an odd number, it is advanced.  Otherwise, `a` points to an even number; `b` is decremented, and `iter_swap`'ed with `a`.  (We use `std::swap`, as the extra `*` are a net benefit compared to the longer name and include - `<algorithm>` versus `<utility>`).

There are unnecessary swaps when `b` points to an even number, but we're golfing, not squeezing efficiency!

Note that we have to be careful not to move both `a` and `b` in the same iteration, otherwise the iterators could pass each other without ever becoming equal.

##Demo
    #include<utility>
    
    auto f=[](auto a,auto b){while(a!=b)*a%2?++a:(std::swap(*--b,*a),a);};
    
    #include <array>
    #include <iostream>
    int main()
    {
        auto a = std::array{ 3,2,2,5,2,1,2 };
    
        f(a.begin(),a.end());
    
        for (auto i: a)
            std::cout << i << " ";
        std::cout << std::endl;
    }