Ok, I'm convinced. I am still not convinced that the containers that maintain these invariants should be lazy. That still seems weird to
me. If they own the data, and are regular types, they should probably
be eager. The larger issue to me is that they have a subset of the expected STL API.
Yes. If I understand the discussion correctly, the container that maintains the invariant is not lazy but the documentation could probably be better at explaining some other things. It's the urls::url that maintains the invariants and owns the data in url u( "ldap:local:userdb/8675309" ); u.remove_scheme(); (u == "local%3a/8675309"); The urls::segment and urls::params views are just references to part of this urls::url. The invariants belong to the url. They are helpers to operate on the urls::url segments and parameters at an individual level, while the underlying urls::url adjusts itself to keep the invariants: url u( "" ); u.set_path("//index.htm"); (u == "/.//index.htm"); url u( "" ); u.is_absolute(true); u.segments().append({"", "index.htm"}); (u == "/.//index.htm"); So the eager urls::url is the one maintaining the invariants, but the segment or parameter views are a better way to operate on the URL when dealing with individual subcomponents. Thus, the functions are not exactly a subset of the STL because the operations are ensuring the invariants of the underlying url remain valid. (The names "segments" and "params" might be a little confusing because it sounds like it owns the data. Some other review has recommended mutable_segments_view/mutable_params_view.) The views are useful because it gives us a single contiguous string with the complete URL at the end. This buffer is always ready to be used by another application. All consecutive URL components are also always immediately available as a contiguous buffer. boost::asio::connect(sock, r.resolve(u.encoded_host)); or boost::beast::http::requesthttp::string_body req{http::verb::get, target, version}; req.set(http::field::host, u.encoded_host()); Besides performance reasons, this contiguous representation is quite useful because we don't have to reassemble the URLs or combinations of components in another string to be able to use it. They can go straight in a buffer sequence. The documentation should probably highlight that design a little more: the idea that we try to keep things in a single contiguous buffer and why. An isolated container owning only the segments or parameters wouldn't be very useful because it wouldn't do much more than a std::vector or a std::map would. These containers would maintain all the invariants we need in decoded segments and params and some other function could then percent-encode the data in these containers to paste that into a url. But what the library is attempting to achieve is avoiding this process. -- Alan Freitas https://github.com/alandefreitas