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

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Thu Dec 7 00:18:04 PST 2023


H-G-Hristov 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:
> 
> ```c++
> 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:
> 
> ```c++
> // option #1
> 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:
> 
> ```c++
> // option #2
> 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:
> 
> ```c++
> // option 3
> #  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)...));
> ```

@ldionne Would this new clang-format 18 option help: https://clang.llvm.org/docs/ClangFormatStyleOptions.html#allowbreakbeforenoexceptspecifier

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


More information about the libcxx-commits mailing list