https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89417

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Federico Kircheis from comment #6)
> For what is worth, I imagined the implementation for parameters of different
> type and more or less than two to be similar to
> 
> ----
> template <class...Args>
> auto sorted_indexes(Args&... args) {
>     const void* addresses[] = {&args...};
>     std::array<int,std::size(addresses)> indexes{};
>     std::iota(std::begin(indexes), std::end(indexes), 0);
>     std::sort(std::begin(indexes), std::end(indexes), [&](int i1, int i2){
>         return std::less<void>()(addresses[i1], addresses[i2]);
>     });
>     return indexes;
> }
> 
> 
> template <class...Args>
> auto create_lock(Args&... args){
>     auto indexes = sorted_indexes(args...);
>     return std::scoped_lock(args[indexes]...); // ???
> }
> ----
> 
> But it's probably a dead end, as args is not an array and I see no way to
> use the computed index.

args is not an array and indexes is not a pack.

You could make sorted_indexes a constexpr function that returns a
std::index_sequence holding the sorted indices, then:

template<class T, size_t... I>
auto create_lock_impl(std::index_sequence<I...>, T arg_tuple, ) {
  return std::scoped_lock(std::get<I>(args)...);
}

template<class... Args>
auto create_lock(Args&... args) {
  return create_lock_impl(sorted_indexes(args...), std::tie(args...));
}

But I am still unconvinced it's worth changing anything here.

Reply via email to