--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b6abc3db-61ca-4641-ad80-86a5da719a3a%40isocpp.org.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f78f7191-b043-4e95-990d-a0f9baab9aec%40isocpp.org.
@Zach Laine:
Thanks for the feedback. I've filled github issues for all the points you mentioned. I will report back here with the findings about the code-size cost of explicit instantiations of embedded_vector for different Capacities.
> Regarding explicit instantiability, why wouldn't that already be the case for any valid template instantiation?
Non-template member functions, which are instantiated on explicit template instantiations, might not be properly constrained, so their instantiation might fail "loudly". The way I've tried to "fix" this in the proposal is by properly constraining all member functions using concepts, but this is an aspect that I must iterate on with more feedback.
> At the last meeting, LEWG were taking the stance that (most) additions of noexcept and constexpr would be left up to implementers until the implications were better understood by the community as a whole.
Adding constexpr is a breaking change, since functions that were not previously evaluated in unevaluated contexts, and thus could be SFINAEd upon, become always potentially evaluated. This can break a lot of code, and it already happened when libc++ made std::invoke constexpr "as a QoI" feature, a change that needed to be reverted.
Second, embedded_vector can be used inside constexpr functions for trivial types. To conditionally allow this, the API must be made conditionally constexpr.
> That last one is not true -- if I insert a T before the first element, I've invalidated all iterators into the vector, no? Did you meant push_back() never invalidates?
Yes, good catch! I meant inserting elements at the end never invalidates iterators.
@rhalbersma: first thank you a lot for the feedback, the devil is in the details and I had completely missed all the issues you point out!> emplace_back() returns a reference in C++17.
Indeed, I've added an issue to fix this, thanks!> Second, you define the op== and other relational operators as friends, which means they are generated as non-member functions at namespace scope. However, all other Standard containers are defined as non-member function templates. The difference is that the latter does not accept user-defined conversions, and the former does. Also they don't have to be friends either.
Indeed, I hadn't realized this until now. As you already know I've filled some issues to improve these.> The best way to declare the relational operators op== and op< is as non-member non-friend function templates, that delegate to std::equal and std::lexicographical_compare on the embedded_vector's iterator range. Then the others can be defined as usual in terms of the former.AFAIK std::lexicographical_compare is not constexpr in C++17, but whether the op== and friends use it or not is an implementation detail of the proposal's implementation rather than a blocker.
A related proposal to make <algorithm> mostly constexpr http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0202r1.html has not yet been adopted, mainly for concern on intrinsics and C helpers (memset and friends).Currently comparisons andswap
/fill
may be implemented with the help of algorithms from <algorithm> header. Marking comparisons withconstexpr
will break that ability and will potentially lead to performance degradations.
@Rein Halbersma wrote:> Indeed, the reference to <algorithm> was meant to illustrate that it was not necessary to make the comparison operators friends, but that they could be done through the public iterator interface (whether from <algorithm> or hand-implemented to be constexpr).>
>Note that if you would have a std::array as back-end for this embedded_vector, then you might want to check
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0031r0.html which has greatly expanded the constexpr-ness of std::array, but with the exception of the op==/op< and swap/fill operations. The rationale being:
>
>Currently comparisons and swap/fill may be implemented with the help of algorithms from <algorithm> header. Marking comparisons with constexpr will break that ability and will potentially lead to performance degradations.
>
> A related proposal to make <algorithm> mostly constexpr http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0202r1.html has not yet been adopted, mainly for concern on intrinsics and C helpers (memset and friends).
>
> So while I would certainly encourage you to push constexpr-ness as a feature of your proposal, I would not expect this to be adopted without discussion.
Thanks for these remarks. I've added a github issue to expand the design rationale of constexpr with mentions of those two paper. How I see it, is that if those papers are accepted, the implementation of the proposal might be greatly simplified. But if they are not accepted, the proposal can still be implemented as is; doing so just has a higher implementation cost.
@Zach Laine:
Thanks for the feedback. I've filled github issues for all the points you mentioned. I will report back here with the findings about the code-size cost of explicit instantiations of embedded_vector for different Capacities.
> Regarding explicit instantiability, why wouldn't that already be the case for any valid template instantiation?
Non-template member functions, which are instantiated on explicit template instantiations, might not be properly constrained, so their instantiation might fail "loudly". The way I've tried to "fix" this in the proposal is by properly constraining all member functions using concepts, but this is an aspect that I must iterate on with more feedback.
> At the last meeting, LEWG were taking the stance that (most) additions of noexcept and constexpr would be left up to implementers until the implications were better understood by the community as a whole.
Adding constexpr is a breaking change, since functions that were not previously evaluated in unevaluated contexts, and thus could be SFINAEd upon, become always potentially evaluated.
This can break a lot of code, and it already happened when libc++ made std::invoke constexpr "as a QoI" feature, a change that needed to be reverted.
Second, embedded_vector can be used inside constexpr functions for trivial types. To conditionally allow this, the API must be made conditionally constexpr.