[libcxx-commits] [libcxx] [llvm] [libc++] Format the code base (PR #74334)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 5 10:22:20 PST 2023


ldionne wrote:

I think `clang-format` is doing something reasonable everywhere. However, there's one pattern we have which might merit discussion. We have a bunch of these write-it-three-times functions. Here's an example with the current manual formatting:

```
template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs&..., _Args...>>>
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & noexcept(
    noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)))
    -> decltype(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) {
  return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...);
}
```

If we just run this through `clang-format`, we get:

```
template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs const&..., _Args...>>>
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& noexcept(
    noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)))
    -> decltype(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) {
  return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...);
}
```

This is not aligned anymore, and it's harder to read. This example isn't very ugly, but we have a few others that do become harder to read when they're not aligned anymore. If we're not happy with this, another option would be to use "clever" comments:

```
template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs&..., _Args...>>>
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & noexcept(
    noexcept(/*   */ _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)))
    -> decltype(/**/ _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) //
{
  return /*       */ _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...);
}
```

The third option would be to use a macro. We previously discussed this but eventually ended up not doing it:

```
#  define _LIBCPP_EXPRESSION_EQUIVALENT(expr)                                                      \
    noexcept(noexcept(expr))->decltype(expr) { return expr; }                                      \
    static_assert(true, "")

template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs const&..., _Args...>>>
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& //
  _LIBCPP_EXPRESSION_EQUIVALENT(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...));
```


https://github.com/llvm/llvm-project/pull/74334


More information about the libcxx-commits mailing list