I guess, this is a matter of design choice: do we want a `resize()` beyond `capacity()` to be treated as a programmer bug (something that the library does not offer) or a correct -- even if very occasional -- usage. Both have their justification and both bring value; but making either choice renders a different library, even if similar on the face value. The model with throwing exceptions is the "infinite memory model": programmer can assume that capacity is infinite and accept that at some point an exception will remind her that the assumption could no longer be maintained. The UB model makes the capacity part of the contract, and programmer takes responsibility of maintaining it. If all STL containers take the exception model, and this library aims at being a drop-in replacement for std::string, the it would sound more reasonable to adapt the "infinite capacity" model. On the other hand, if the goal is to provide a container suitable for embedded operations, where you cannot afford throwing exceptions the same way as you cannot afford heap allocation, one would expect the other model. This is what static_vector has chosen. It looks to me that these two design goals cannot be pursued together: * be a drop-in replacement for std::string * be a tool for embedded systems (where resource/constraint awareness changes the way one organize programs) As they necessitate opposite design trade-offs. Authors of fixed_string should make the call which goal they want to pursue and document it. And from this choice the design trade-offs will follow. static_string came from Beast. My guess is that Beast needs the "infinite memory" model. If you are doing networking, you can afford occasional memory allocation required by exceptions. And you want to favor buffer overflow protection over bleeding edge performance. This also justifies using different prefix ("fixed_") than in static_vector, as the latter library chose a different model. Regards, &rzej; pt., 29 lis 2019 o 01:18 Andrey Semashev via Boost <boost@lists.boost.org> napisaĆ(a):
On 2019-11-29 01:44, Zach Laine via Boost wrote:
Ok, I understand your point a bit better now I think. Is it the unboundedly-large nature of a NTBS that has you concerned? That is, do
think that op+=(char) should assert and op+=(char const *) should throw? That position makes sense to me, thought I don't share it -- though I
you think
that's just taste. However, I cannot imagine why I'd ever want op+=(char) or op+=(string_view) to throw.
IIRC, append/insert/push_back will throw with any container or std::string, if the result exceeds max_size(). It is only natural if fixed_string does the same, it is the expected behavior.
You can argue for a separate set of unsafe insert methods that don't perform the check and exhibit undefined behavior if the resulting length exceeds the limit. But it should be very clear that the user must ensure himself that it doesn't happen.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost