[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