dimanche 23 février 2020

What is `std::string_view::max_size()`?

While creating a version of std::basic_string_view for a private project (choices made for me: C++11; no boost:: allowed; with a pinch of NIH, so no GSL either) I came to implementing std::basic_string_view::max_size() for which the standard (n4820 21.4.2.3 Capacity) simply says:

Returns: The largest possible number of char-like objects that can be referred to by a basic_string_view.

Logically, this would be the maximum number that std::basic_string_view::size_type can represent: std::numeric_limits<std::basic_string_view::size_type>::max() which comes out at 18446744073709551615 on my platform where size_type is std::size_t.

I figured that, since I want to be compatible with the standard libraries, I should ensure that I arrive at the same number as other implementations. This is where I get lost.

Given that I have a auto max_size = string_view{"foo"}.max_size() then I get the following results:

+--------------+--------------------------+
| Library      | Result                   |
+--------------+--------------------------+
| libstdc++    | 4611686018427387899      |
| libc++       | 18446744073709551615     |
| boost 1.72.0 | 3                        |
+--------------+--------------------------+

If my interpretation is correct, then that means that libc++ and I agree on what the value should be. I feel that boost is completely wrong, since the specification for max_size is to return the largest possible number that a, not this, string_view can refer to. Further, looking at the implementations of all three libraries libc++ returns

numeric_limits<size_type>::max();

libstdc++ returns

(npos - sizeof(size_type) - sizeof(void*)) / sizeof(value_type) / 4;

and boost returns:

len_;

Basically, two implementations appear to be wrong, but the question is: which one is correct?

Aucun commentaire:

Enregistrer un commentaire