There's a place in std::is_permutation where we eliminate a common prefix at the start. We could use std::mismatch instead of a hand-written loop, since mismatch is vectorized.
Inside __is_permutation_impl, we can use std::find for "Have we already counted the number of *__i in [f1, l1)?"
In the main loop of __is_permutation_impl, we can basically use std::count to count the number of times a value appears, I think.