bug#62386: CC Mode 5.35.2 (C++//l); C++ concept indentation
Michael Welsh Duggan <[email protected]> Fri, 07 Apr 2023 12:00:13 -0400
| Newsgroups | gmane.emacs.cc-mode.general |
|---|---|
| Message-ID | <[email protected]> |
Alan Mackenzie <[email protected]> writes: > Hello, Michael. > > On Tue, Mar 28, 2023 at 10:45:54 -0400, Michael Welsh Duggan wrote: >> Found one strange real code case and one very strange constructed test >> case: > >> class Chunk { >> template <typename T, typename D> >> requires (OctetLike<T> >> || (std::rank_v<T> == 1 && OctetLike<std::remove_extent_t<T>>)) >> Chunk(std::unique_ptr<T, D> && p, length_t size) >> : size_{size} >> { >> auto ptr = p.get(); >> data_ = {std::shared_ptr<T>{std::move(p)}, octet_cast(ptr)}; >> } >> }; > >> The case above comes from some actual code I have been writing. The >> strange bit is that the Chunk constructor is indented once more than >> intended. > >> template <typename T> >> requires >> requires (T t) { >> { ++t; } >> } >> && std::is_integral<T> >> int foo(); > > I think I've now got these corrected. The coding was much more difficult > than I'd anticipated, with me spending several days in total confusion. > The last thing which threw me off was the realisation that the > expressions in the concept clause need not be "primary" expressions, i.e. > something like !foo<T> is valid. This is not the case with requires > clauses, where only "primary" expressions are permitted. > >> This has a few problems with it. The "{ ++t; }" should be indented with >> respect to the "requires (T t)" portion. The "&& std::is_integral<T>" >> should be at the same level as that requires. And "int foo()" is >> indented one level too far. > >> Just in case you didn't know, in this latter case, the first "requires" >> introduces an associated constraint, and the second evaluates a >> requirement as a requires expression. > > Thanks, you've just got to love the C++ Standards Committee. ;-) > >> https://en.cppreference.com/w/cpp/language/constraints >> https://en.cppreference.com/w/cpp/language/requires > > Thanks again, I've had those pages in my web browser cache for quite some > time, now. > > Here's the latest version of the patch. Please do the usual with it, and > let me know how it goes. Thanks! Much, much better! I have only one niggling nit left, and this one doesn't bother me nearly as much as the others. The nit is that opening parentheses don't seem to open up a new indention context anymore. (That's my internal mental terminology, not necessary what it used by cc-mode.) Before: template <typename T> requires (OctetLike<T> || (std::rank_v<T> == 1 && std::extent_v<T> == 0 && OctetLike<std::remove_extent_t<T>>)) Chunk(std::shared_ptr<T> const & p, length_t size) : data_{p, octet_cast(p.get())}, size_{size} {} After: template <typename T> requires (OctetLike<T> || (std::rank_v<T> == 1 && std::extent_v<T> == 0 && OctetLike<std::remove_extent_t<T>>)) Chunk(std::shared_ptr<T> const & p, length_t size) : data_{p, octet_cast(p.get())}, size_{size} {} -- Michael Welsh Duggan ([email protected])