utility::string_view and core::detail::string_view
On Thu, Oct 23, 2025 at 4:17 AM Dmitry Arkhipov via Boost < boost@lists.boost.org> wrote:
Url's and Charconv's maintainers decided to not play along with the charade and reference boost::core::string_view directly with the obvious drawback that that type is not documented anywhere.
core::detail::string_view was added because this pull request FROM 2018 (seven years ago) was rejected: https://github.com/boostorg/utility/pull/51 We really need to fix this properly. In my opinion the maintainer of utility::string_view made the wrong choice when they rejected the pull request to make the constructors more useful. The consequence is that several Boost authors now use core::detail::string_view because it better satisfies user needs. At a time when people complain that Boost has its own version of std types, it would be best if we could come together and sort this. I would like to see the change which motivated core::detail::string view get applied to utility::string_view. Then we can change core::detail::string_view to be a deprecated alias, and after one release we can remove it. This solves everyone's problem: 1. Users get a type that works 2. Folks are not triggered by having two string views 3. Every library doesn't have to lift string_view into its own namespace 4. Cross-linking in documentation becomes possible With each new version of C++ we are asking more and more of Boost users. We are asking them to opt-in to our ecosystem which includes its own types similar yet sometimes incompatible with the standard types. It is our responsibility to make sure that we respect the user's trust, and deliver types which work for them. boost::utility::string_view breaks that trust at a time when we cannot afford to alienate. The consequence of the decision not to be flexible with the utility::string_view API is that now we have two string views. We have documentation issues. We have discovery issues. There is strife within the community. Yet more and more libraries are choosing core/detail/string_view.hpp instead of utility/string_view.hpp, simply because the core version works better. It is in the project's best interest to show the C++ community writ large that we can adapt and satisfy user needs. Lets do that by resolving the two string views. Thanks
On Thu, Oct 23, 2025, 11:41 PM Vinnie Falco via Boost <boost@lists.boost.org> wrote:
On Thu, Oct 23, 2025 at 4:17 AM Dmitry Arkhipov via Boost < boost@lists.boost.org> wrote:
Url's and Charconv's maintainers decided to not play along with the charade and reference boost::core::string_view directly with the obvious drawback that that type is not documented anywhere.
core::detail::string_view was added because this pull request FROM 2018 (seven years ago) was rejected: https://github.com/boostorg/utility/pull/51
We really need to fix this properly. In my opinion the maintainer of utility::string_view made the wrong choice when they rejected the pull request to make the constructors more useful.
[snip] I second this. Last year I was in the process of writing an issue to ask for this feature in boost::basic_string_view, when I discovered that it had already been discussed years earlier. From a user perspective, I work on a code base that was previously C++ <17, and is now C++ >=17. New code is written using std::string_view, but that doesn't negate the years of utilities and interfaces all throughout the code that use boost::string_view. At the end of the day, I just want to pass a std::string_view to an interface that expects a boost::string_view. I'm sure this is a common use case for people as their code moves to newer standards. I could either (1) convert my std::string_view to boost::string_view manually with data and size, (2) add a new overload to the utilities with proper constraints such that it's not ambiguous between the two overloads, or (3) replace the usage of boost::string_view with std::string_view outright. None of these are as simple as just passing a std::string_view to the interface, with no extra boilerplate or rejigging of the utility itself. C++17 is long since here, and std::string_view is a standard vocabulary type as much as std::string is. I think we're doing users a disservice by making them jump through hoops to convert between boost::string_view and std::string_view. This is a problem I've personally encountered, and I would be shocked if it isn't common. I'd love if we could reconsider, and give boost::string_view constructibility from (and convertibility to) std::string_view. Even better if that could be in time for 1.90. Thanks, Braden
El 24/10/2025 a las 6:39, Vinnie Falco via Boost escribió:
On Thu, Oct 23, 2025 at 4:17 AM Dmitry Arkhipov via Boost < boost@lists.boost.org> wrote:
Url's and Charconv's maintainers decided to not play along with the charade and reference boost::core::string_view directly with the obvious drawback that that type is not documented anywhere.
core::detail::string_view was added because this pull request FROM 2018 (seven years ago) was rejected: https://github.com/boostorg/utility/pull/51
We really need to fix this properly. In my opinion the maintainer of utility::string_view made the wrong choice when they rejected the pull request to make the constructors more useful. The consequence is that several Boost authors now use core::detail::string_view because it better satisfies user needs. At a time when people complain that Boost has its own version of std types, it would be best if we could come together and sort this.
The whole situation is messy, made more so but the fact that boost::core::string_view does not live in a detail namespace and yet is in header boost/core/detail/string_view.hpp and lacks documentation. A simple Github search shows that it's being used in the wild (i.e. outside Boost). Of course it'd be best if the authors involved agreed on a single, common string_view class across Boost. Barring that, my opinion is that boost::core::string_view should be properly lifted to public status and people will ultimately decide which one they use --this is unfortunately not the first case of such a situation, we already have it for iterator helpers provided both by Boost.Operator and Boost.Iterator. Joaquín M López Muñoz
The whole situation is messy, made more so but the fact that boost::core::string_view does not live in a detail namespace and yet is in header boost/core/detail/string_view.hpp and lacks documentation. A simple Github search shows that it's being used in the wild (i.e. outside Boost).
Of course it'd be best if the authors involved agreed on a single, common string_view class across Boost. Barring that, my opinion is that boost::core::string_view should be properly lifted to public status and people will ultimately decide which one they use --this is unfortunately not the first case of such a situation, we already have it for iterator helpers provided both by Boost.Operator and Boost.Iterator.
I use core::string_view in Boost.MySQL, too, because implicit conversion to std::string_view is super important for me. core::string_view has std::format support, too. Not having any of these would have forced me to upgrade to C++17 already. So I'd like to see core::string_view as a public type, as it's already widely used in our interfaces. Regards, Rubén.
On Tue, Nov 4, 2025 at 11:50 PM Ruben Perez via Boost <boost@lists.boost.org> wrote:
The whole situation is messy, made more so but the fact that boost::core::string_view does not live in a detail namespace and yet is in header boost/core/detail/string_view.hpp and lacks documentation. A simple Github search shows that it's being used in the wild (i.e. outside Boost).
Of course it'd be best if the authors involved agreed on a single, common string_view class across Boost. Barring that, my opinion is that boost::core::string_view should be properly lifted to public status and people will ultimately decide which one they use --this is unfortunately not the first case of such a situation, we already have it for iterator helpers provided both by Boost.Operator and Boost.Iterator.
I use core::string_view in Boost.MySQL, too, because implicit conversion to std::string_view is super important for me. core::string_view has std::format support, too. Not having any of these would have forced me to upgrade to C++17 already. So I'd like to see core::string_view as a public type, as it's already widely used in our interfaces.
Why don't we have a string_view in boost.compat? if we had a compat:;string_view that is identical to the C++17 implementation. We then have one standard with two implementations and not three slightly different string_views. Once compat adds this the consuming libraries (e.g. boost.mysql or boost.url) can use compat and the other implementations just become a relic that isn't used within boost anymore. The same would probably apply to core/span.
I use core::string_view in Boost.MySQL, too, because implicit conversion
to
std::string_view is super important for me. core::string_view has std::format support, too. Not having any of these would have forced me to upgrade to C++17 already. So I'd like to see core::string_view as a public type, as it's already widely used in our interfaces.
Why don't we have a string_view in boost.compat? if we had a compat:;string_view that is identical to the C++17 implementation. We then have one standard with two implementations and not three slightly different string_views.
Once compat adds this the consuming libraries (e.g. boost.mysql or boost.url) can use compat and the other implementations just become a relic that isn't used within boost anymore.
The same would probably apply to core/span.
This could be a good way to implement the "make it public" proposal. I already use Boost.Compat in MySQL, so I'd be happy to see string_view there. One thing to note is that boost::core::string_view does not support the Traits template parameter that boost::string_view and std::string_view do. I personally don't need this at all, but I don't know if that's true for the other libraries.
_______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/YJQLWHLW...
On 11/4/2025 5:05 PM, Klemens Morgenstern via Boost wrote: [...]
Why don't we have a string_view in boost.compat? if we had a compat:;string_view that is identical to the C++17 implementation. We then have one standard with two implementations and not three slightly different string_views.
Once compat adds this the consuming libraries (e.g. boost.mysql or boost.url) can use compat and the other implementations just become a relic that isn't used within boost anymore. Boost.Compat might be the ideal place for this (as it perfectly fits "Boost.Compat is a repository of C++11 implementations of standard components added in later C++ standards.").
But I suspect a string_view in Compat should necessarily have a Traits template argument? -- Gennaro Prota <https://prota.dev>
On Tue, Nov 4, 2025 at 8:26 AM Gennaro Prota via Boost < boost@lists.boost.org> wrote:
But I suspect a string_view in Compat should necessarily have a Traits template argument?
A good approach might be to start without the Traits and then only consider adding them when a demonstrable use-case arises. Thanks
El 04/11/2025 a las 17:05, Klemens Morgenstern via Boost escribió:
On Tue, Nov 4, 2025 at 11:50 PM Ruben Perez via Boost <boost@lists.boost.org> wrote:
The whole situation is messy, made more so but the fact that boost::core::string_view does not live in a detail namespace and yet is in header boost/core/detail/string_view.hpp and lacks documentation. A simple Github search shows that it's being used in the wild (i.e. outside Boost).
Of course it'd be best if the authors involved agreed on a single, common string_view class across Boost. Barring that, my opinion is that boost::core::string_view should be properly lifted to public status and people will ultimately decide which one they use --this is unfortunately not the first case of such a situation, we already have it for iterator helpers provided both by Boost.Operator and Boost.Iterator.
I use core::string_view in Boost.MySQL, too, because implicit conversion to std::string_view is super important for me. core::string_view has std::format support, too. Not having any of these would have forced me to upgrade to C++17 already. So I'd like to see core::string_view as a public type, as it's already widely used in our interfaces.
The main objection to the pull request was that a dependency was created. I'm sympathetic to that objection, I usually try to avoid explicit dependencies on Boost vs Std types and try to be interoperable with both. For instance, Boost.Interprocess timeouts can be used now with both Boost.Chrono and std::chrono types without including the corresponding headers, because you have the power of templates. I had the same problem with boost::container::basic_string. Should I construct it from boost or std string_views? If you are in a generic, templated class, many times you can support both: template<template <class, class> class BasicStringView> explicit basic_string(BasicStringView<CharT, Traits> sv, const allocator_type& a = allocator_type()) : base_t(allocator_traits_type::select_on_container_copy_construction(a)) { this->priv_terminate_string(); this->assign(sv); } where assign is: template<template <class, class> class BasicStringView> basic_string& operator=(BasicStringView<CharT, Traits> sv) { return this->assign(sv.data(), sv.size()); } Then a) the user has to include the proper include (not your problem) and b) your component is free of any dependency c) Other StringView types can be plugged if they offer I don't know if the proposed templated conversion operator would work flawlessly in all cases but I suggest we take this or similar templated approach so that utility/string_view does not depend on std::string_view, and we can then have a single string_view type in Boost. Just my 2 cents, Ion
The main objection to the pull request was that a dependency was created. I'm sympathetic to that objection, I usually try to avoid explicit dependencies on Boost vs Std types and try to be interoperable with both. For instance, Boost.Interprocess timeouts can be used now with both Boost.Chrono and std::chrono types without including the corresponding headers, because you have the power of templates.
I had the same problem with boost::container::basic_string. Should I construct it from boost or std string_views? If you are in a generic, templated class, many times you can support both:
template<template <class, class> class BasicStringView> explicit basic_string(BasicStringView<CharT, Traits> sv, const allocator_type& a = allocator_type()) : base_t(allocator_traits_type::select_on_container_copy_construction(a)) { this->priv_terminate_string(); this->assign(sv); }
where assign is:
template<template <class, class> class BasicStringView> basic_string& operator=(BasicStringView<CharT, Traits> sv) { return this->assign(sv.data(), sv.size()); }
Then a) the user has to include the proper include (not your problem) and b) your component is free of any dependency c) Other StringView types can be plugged if they offer
I don't know if the proposed templated conversion operator would work flawlessly in all cases but I suggest we take this or similar templated approach so that utility/string_view does not depend on std::string_view, and we can then have a single string_view type in Boost.
This is not viable for std::format is it?
El 04/11/2025 a las 17:31, Ruben Perez via Boost escribió:
This is not viable for std::format is it?
I haven't tried std::format yet, TBH. But std::format was not part of the mentioned pull request if I'm not wrong (core::string_view supports it, apparently): https://github.com/boostorg/utility/pull/51/commits/40614288c8616f430e59d7f5... Not an expert on std::format to know how we could achieve the same without a hard dependency (if possible). Best, Ion
Three points: a) Having different string_view types defined in two (or potentially more given the compat suggestion) Boost libraries strikes me as extremely confusing for the users (previous emails have shown it to be confusing for Boost contributors, so it must be even more so for naive users of Boost). It makes sesnse to pick one single design and (ideally though I understand backwards compatibility may be a concern) a single location. b) I personally think that allowing a string_view type to be constructible from std::string_view is eminently sensible and aids usability and interoperability between Boost and non-Boost libraries. People don't like introducing a dependency on std::string_view. That is easily solved by a templated constructor. Note that std::basic_string uses a similar trick (see constructor 9 on https://en.cppreference.com/w/cpp/string/basic_string/basic_string.html), and the StringViewLike type can be constrained in whatever way you are comfortable. (personally I don't have any objection to simply checking '__has_include(<string_view>)' and using it directly but I'm pointing out that if people don't like that there are alternatives) c) People seem to be mixing this up with <format> support. Such a constructor does not impact support for std::format or <fmt> - its presence or absence is entirely orthogonal to whether *::string_view provides std::format support. In fact adding support for std::format to a non-std string_view type is relatively straightforward (if need be I can do a simple demo in godbolt) - you know std::string_view must be available in C++20 (required for std::format) and can therefore create a formatter type that delegates to the formatter for std::string_view. On 04/11/2025 16:54, Ion Gaztañaga via Boost wrote:
El 04/11/2025 a las 17:31, Ruben Perez via Boost escribió:
This is not viable for std::format is it?
I haven't tried std::format yet, TBH. But std::format was not part of the mentioned pull request if I'm not wrong (core::string_view supports it, apparently):
https://github.com/boostorg/utility/pull/51/commits/40614288c8616f430e59d7f5...
Not an expert on std::format to know how we could achieve the same without a hard dependency (if possible).
Best,
Ion _______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/IZR5BY7P...
Ion Gaztañaga wrote:
Not an expert on std::format to know how we could achieve the same without a hard dependency (if possible).
It's going to be possible after P3070 https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2023/p3070r0.html by defining a function `format_as`, but that's C++29. By then, I sincerely hope that we would have mostly moved to C++17 and the point will have been made moot.
On 4 Nov 2025 19:26, Ion Gaztañaga via Boost wrote:
The main objection to the pull request was that a dependency was created. I'm sympathetic to that objection, I usually try to avoid explicit dependencies on Boost vs Std types and try to be interoperable with both. For instance, Boost.Interprocess timeouts can be used now with both Boost.Chrono and std::chrono types without including the corresponding headers, because you have the power of templates.
I had the same problem with boost::container::basic_string. Should I construct it from boost or std string_views? If you are in a generic, templated class, many times you can support both:
template<template <class, class> class BasicStringView> explicit basic_string(BasicStringView<CharT, Traits> sv, const allocator_type& a = allocator_type()) : base_t(allocator_traits_type::select_on_container_copy_construction(a)) { this->priv_terminate_string(); this->assign(sv); }
where assign is:
template<template <class, class> class BasicStringView> basic_string& operator=(BasicStringView<CharT, Traits> sv) { return this->assign(sv.data(), sv.size()); }
Then a) the user has to include the proper include (not your problem) and b) your component is free of any dependency c) Other StringView types can be plugged if they offer
I don't know if the proposed templated conversion operator would work flawlessly in all cases but I suggest we take this or similar templated approach so that utility/string_view does not depend on std::string_view, and we can then have a single string_view type in Boost.
boost/utility/string_view.hpp already includes <string>, which is a more expensive dependency than <string_view>. Replacing the former with the latter, when possible, would likely improve compile times. Though, honestly, I didn't quite understand the objection back then. It seemed, Marshall was under the impression that relying on BOOST_NO_CXX17_HDR_STRING_VIEW was problematic for some reason.
Andrey Semashev wrote:
Though, honestly, I didn't quite understand the objection back then. It seemed, Marshall was under the impression that relying on BOOST_NO_CXX17_HDR_STRING_VIEW was problematic for some reason.
Adding implicit conversions in this case had the potential to create a lot of subtle issues because code exists that does all sorts of funny things such as having conversion operators to char const*, or std::string, or boost::string_view, or std::string_view, or having overload sets taking all possible combinations of those. So I understand his reluctance to commit to the potential maintenance burden created by that. That is why we went the route we went; adding a second string_view with those conversions, not maintained by Marshall, so that the potential issues would not have to be addressed by him (but by me.) Everything is not 100% fine, https://github.com/boostorg/core/issues/167 but it mostly is, so I'd say we're at a point where we can make boost::string_view what core::string_view is. Since Core is not allowed to depend on Utility, one possible approach is to define boost::string_view in Core, make boost::core::string_view a using declaration, and include that in Utility. Although if people insist on arbitrary Traits support, we probably need to do something else. (Kind of unrelated, I see that I never got around to adding the string_view benchmarks to the Core repo. So much to do, so little time.)
Why not just let boost::string_view be an alias to std::string_view when you compile in C++17 mode? /Peter On Tue, Nov 4, 2025 at 7:04 PM Peter Dimov via Boost <boost@lists.boost.org> wrote:
Andrey Semashev wrote:
Though, honestly, I didn't quite understand the objection back then. It seemed, Marshall was under the impression that relying on BOOST_NO_CXX17_HDR_STRING_VIEW was problematic for some reason.
Adding implicit conversions in this case had the potential to create a lot of subtle issues because code exists that does all sorts of funny things such as having conversion operators to char const*, or std::string, or boost::string_view, or std::string_view, or having overload sets taking all possible combinations of those.
So I understand his reluctance to commit to the potential maintenance burden created by that.
That is why we went the route we went; adding a second string_view with those conversions, not maintained by Marshall, so that the potential issues would not have to be addressed by him (but by me.)
Everything is not 100% fine,
https://github.com/boostorg/core/issues/167
but it mostly is, so I'd say we're at a point where we can make boost::string_view what core::string_view is.
Since Core is not allowed to depend on Utility, one possible approach is to define boost::string_view in Core, make boost::core::string_view a using declaration, and include that in Utility.
Although if people insist on arbitrary Traits support, we probably need to do something else.
(Kind of unrelated, I see that I never got around to adding the string_view benchmarks to the Core repo. So much to do, so little time.)
_______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/FDNAEGE5...
Peter Koch Larsen wrote:
Why not just let boost::string_view be an alias to std::string_view when you compile in C++17 mode?
Because then the compiled library and the user code need to either both be built in C++17 mode, or both be built in not-C++17 mode, and this creates problems if you're using a prebuilt Boost, e.g. one from apt-get.
Am 04.11.25 um 19:03 schrieb Peter Dimov via Boost:
Andrey Semashev wrote:
Though, honestly, I didn't quite understand the objection back then. It seemed, Marshall was under the impression that relying on BOOST_NO_CXX17_HDR_STRING_VIEW was problematic for some reason. Adding implicit conversions in this case had the potential to create a lot of subtle issues because code exists that does all sorts of funny things such as having conversion operators to char const*, or std::string, or boost::string_view, or std::string_view, or having overload sets taking all possible combinations of those.
So I understand his reluctance to commit to the potential maintenance burden created by that.
That is why we went the route we went; adding a second string_view with those conversions, not maintained by Marshall, so that the potential issues would not have to be addressed by him (but by me.)
Everything is not 100% fine,
https://github.com/boostorg/core/issues/167
but it mostly is, so I'd say we're at a point where we can make boost::string_view what core::string_view is Doesn't this prove Marshalls point? `boost::core::string_view` is convertible to std::string and std::string_view so overloads of both will cause ambiguity.
This of course could be a "funny thing" to do but could reasonably occur if the string_view overload is e.g. conditional on C++17, or if having the null-termination allows a better code path. IMO if we can't have `boost::*::string_view` work as a drop-in for `std::string_view` without breaking things that weren't broken before we can't have those automatic conversions as much as I'd like to have them. If there aren't similar issues for *accepting* a boost-string_view then we could have at least the converting ctor so our interfaces can accept either type by specifying only boost-string_view. As a view-type is mainly an interface type anyway this might cover enough use cases already.
On Tue, 4 Nov 2025 at 12:05, Peter Dimov via Boost <boost@lists.boost.org> wrote:
Andrey Semashev wrote:
Though, honestly, I didn't quite understand the objection back then. It seemed, Marshall was under the impression that relying on BOOST_NO_CXX17_HDR_STRING_VIEW was problematic for some reason.
Adding implicit conversions in this case had the potential to create a lot of subtle issues because code exists that does all sorts of funny things such as having conversion operators to char const*, or std::string, or boost::string_view, or std::string_view, or having overload sets taking all possible combinations of those.
So I understand his reluctance to commit to the potential maintenance burden created by that.
That is why we went the route we went; adding a second string_view with those conversions, not maintained by Marshall, so that the potential issues would not have to be addressed by him (but by me.)
Everything is not 100% fine,
https://github.com/boostorg/core/issues/167
but it mostly is, so I'd say we're at a point where we can make boost::string_view what core::string_view is.
Unrelated to boost::core::string_view, I think that boost::string_view itself should be compatible with std::string_view, and it seems to create unexpected behaviour for the user when this isn't the case. Although I do understand the argument that it would break code in certain places for overload sets, so maybe that ship has sailed already. If there's something we can do about this, I would be in favour of it. Like I said in my previous message in this thread, the lack of interoperability causes major issues for people (read: me) trying to use std::string_view in a code base that has previously only used boost::string_view. Basically my argument is, having a string_view that is in the top-level "boost" namespace is a very different creature than having it in a sub-namespace. Any average Joe programmer using Boost will reach for boost::string_view without knowing about any other string_views defined in other libraries. I think it's surprising and misleading if the "useful and correct" string_view implementation isn't the one in the top-level "boost" namespace.
On 4 Nov 2025 19:05, Klemens Morgenstern via Boost wrote:
Why don't we have a string_view in boost.compat? if we had a compat:;string_view that is identical to the C++17 implementation. We then have one standard with two implementations and not three slightly different string_views.
If my counting is right, we'd have three, plus std::string_view. As if two weren't enough. BTW, the version in Boost.Compat wouldn't have a conversion operator to/from std::string_view because one doesn't exist in std::string_view and Boost.Compat implements standard components verbatim.
Once compat adds this the consuming libraries (e.g. boost.mysql or boost.url) can use compat and the other implementations just become a relic that isn't used within boost anymore.
The same would probably apply to core/span.
I use core::string_view in Boost.MySQL, too, because implicit conversion to std::string_view is super important for me. core::string_view has std::format support, too. Not having any of these would have forced me to upgrade to C++17 already. So I'd like to see core::string_view as a public type, as it's already widely used in our interfaces.
For the record, the problem with not having explicit std::format support is specially hostile for users because the problem manifests at runtime rather than compile-time. Since XXX::string_view is a range, it will be formatted as a range of characters instead of a string. You can see what it looks like here: https://godbolt.org/z/W7acqxYWd Copying a snippet here just in case: std::println("{}", std::string_view("hello world")); std::println("{}", boost::core::string_view("hello world")); std::println("{}", boost::string_view("hello world")); Prints: hello world hello world ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
In case anyone is curious how to implement support for <format> in boost::string_view by delegating to the formatter for std::string_view: https://godbolt.org/z/YsWKrEz3P On 04/11/2025 16:41, Ruben Perez via Boost wrote:
I use core::string_view in Boost.MySQL, too, because implicit conversion to std::string_view is super important for me. core::string_view has std::format support, too. Not having any of these would have forced me to upgrade to C++17 already. So I'd like to see core::string_view as a public type, as it's already widely used in our interfaces. For the record, the problem with not having explicit std::format support is specially hostile for users because the problem manifests at runtime rather than compile-time. Since XXX::string_view is a range, it will be formatted as a range of characters instead of a string. You can see what it looks like here: https://godbolt.org/z/W7acqxYWd
Copying a snippet here just in case:
std::println("{}", std::string_view("hello world")); std::println("{}", boost::core::string_view("hello world")); std::println("{}", boost::string_view("hello world"));
Prints:
hello world hello world ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'] _______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/LGBW4G4F...
Mungo Gill wrote:
In case anyone is curious how to implement support for <format> in boost::string_view by delegating to the formatter for std::string_view: https://godbolt.org/z/YsWKrEz3P
There's no way to portably forward-declare things in std (even if we discount the fact that this is explicitly called out as undefined behavior.) https://godbolt.org/z/9f5xMEPd1
On 4 Nov 2025 22:19, Peter Dimov via Boost wrote:
Mungo Gill wrote:
In case anyone is curious how to implement support for <format> in boost::string_view by delegating to the formatter for std::string_view: https://godbolt.org/z/YsWKrEz3P
There's no way to portably forward-declare things in std (even if we discount the fact that this is explicitly called out as undefined behavior.)
Although this is true, we also have utilities for doing this in all widespread implementations, and some Boost libraries already forward-declare std components: https://godbolt.org/z/GrEY377qb I wish this utility was made more public.
El 04/11/2025 a las 21:08, Andrey Semashev via Boost escribió:
On 4 Nov 2025 22:19, Peter Dimov via Boost wrote:
Mungo Gill wrote:
In case anyone is curious how to implement support for <format> in boost::string_view by delegating to the formatter for std::string_view: https://godbolt.org/z/YsWKrEz3P
There's no way to portably forward-declare things in std (even if we discount the fact that this is explicitly called out as undefined behavior.)
Although this is true, we also have utilities for doing this in all widespread implementations, and some Boost libraries already forward-declare std components:
https://godbolt.org/z/GrEY377qb
I wish this utility was made more public.
I just replied with the same content, we are somehow synchronized. We could also have a VERY lightweight library, properly tested, something like: https://github.com/olegpublicprofile/stdfwd Best, Ion
El 04/11/2025 a las 20:19, Peter Dimov via Boost escribió:
Mungo Gill wrote:
In case anyone is curious how to implement support for <format> in boost::string_view by delegating to the formatter for std::string_view: https://godbolt.org/z/YsWKrEz3P
There's no way to portably forward-declare things in std (even if we discount the fact that this is explicitly called out as undefined behavior.)
No standard way, but there is a practial way using some tricks https://github.com/boostorg/move/blob/develop/include/boost/move/detail/std_... https://github.com/boostorg/container/blob/develop/include/boost/container/d... See your example using Boost.Move internal headers: https://godbolt.org/z/Eez6f9cf5 In spite of the "official UB" I think we should have a StdFwd library in Boost (or maybe some header doing the ugly stuff in Boost.Config). Best, Ion
El 04/11/2025 a las 20:07, Mungo Gill via Boost escribió:
In case anyone is curious how to implement support for <format> in boost::string_view by delegating to the formatter for std::string_view: https://godbolt.org/z/YsWKrEz3P
I really don't like when the standard requires specializing std types to plug user-defined types in the system. That makes your type dependent on types and includes users might not need at all. Having to specialize std::formatter is an arbitraty decision that increases coupling. The alternative could be to have typedef of name "std_formatter_t" that could do the same work. I prefer the approach of defining some member functions, operations or typedefs that the standard library must find in your type, e.g.: having "operator < in your type" instead of a specializing std::less. Define "hash_value" instead of specializing "std::hash". Best, Ion
On Tue, Nov 4, 2025 at 1:50 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
I prefer the approach...
I like the tag_invoke model pioneered by Eric Niebler, et. al. who used to be active in Boost (where did he go?) Ironically with 3-year rapid "innovation" of C++ Standard versions the tag_invoke mechanism has fallen out of favor. See: https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf Thanks
El 04/11/2025 a las 23:23, Vinnie Falco escribió:
On Tue, Nov 4, 2025 at 1:50 PM Ion Gaztañaga via Boost <boost@lists.boost.org <mailto:boost@lists.boost.org>> wrote:
I prefer the approach...
I like the tag_invoke model pioneered by Eric Niebler, et. al. who used to be active in Boost (where did he go?) Ironically with 3-year rapid "innovation" of C++ Standard versions the tag_invoke mechanism has fallen out of favor.
See: https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf <https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf>
Interesting, but a bit convoluted for my taste ;-) Best, Ion
On Tue, Nov 4, 2025 at 2:59 PM Ion Gaztañaga <igaztanaga@gmail.com> wrote:
https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf <https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf>
Interesting, but a bit convoluted for my taste ;-)
Apologies, I should clarify. The paper goes on about Customization Point Objects ("CPOs") and what not, which is a lot of additional complexity. Some of that is justified as it relates to what is needed for a standard library implementation. We don't need all that, so just the plain `tag_invoke` is good enough. Boost.JSON uses this mechanism. The guidance becomes "overload tag_invoke for the desired tag and your type." So for example Boost.JSON declares the "value_to" tag, and in order to convert a json::value to your type T, you would write this function in the same namespace as T: void tag_invoke( boost::json::value_to_tag, T&, boost::json::value const& ); I like this better than specializing a class template for a few reasons. Thanks
On Wed, Nov 5, 2025, at 12:13 AM, Vinnie Falco via Boost wrote:
On Tue, Nov 4, 2025 at 2:59 PM Ion Gaztañaga <igaztanaga@gmail.com> wrote:
Interesting, but a bit convoluted for my taste ;-)
[...] in order to convert a json::value to your type T, you would write this function in the same namespace as T:
void tag_invoke( boost::json::value_to_tag, T&, boost::json::value const& );
I like this better than specializing a class template for a few reasons.
+1 I like the libraries that use this approach. It's the best way I know to truly decouple the provider and consumer of this extension mechanism. Seth
El 05/11/2025 a las 0:13, Vinnie Falco escribió:
On Tue, Nov 4, 2025 at 2:59 PM Ion Gaztañaga <igaztanaga@gmail.com <mailto:igaztanaga@gmail.com>> wrote:
> https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf <https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf> > <https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf <https://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1895r0.pdf>>
Interesting, but a bit convoluted for my taste ;-)
Apologies, I should clarify. The paper goes on about Customization Point Objects ("CPOs") and what not, which is a lot of additional complexity. Some of that is justified as it relates to what is needed for a standard library implementation. We don't need all that, so just the plain `tag_invoke` is good enough. Boost.JSON uses this mechanism. The guidance becomes "overload tag_invoke for the desired tag and your type." So for example Boost.JSON declares the "value_to" tag, and in order to convert a json::value to your type T, you would write this function in the same namespace as T:
void tag_invoke( boost::json::value_to_tag, T&, boost::json::value const& );
I like this better than specializing a class template for a few reasons.
Thanks for the explanation, this seems a useful extension of the plain ADL customization, avoiding name clashes between customization points. Best, Ion
participants (13)
-
Alexander Grund -
Andrey Semashev -
Braden Ganetsky -
Gennaro Prota -
Ion Gaztañaga -
Joaquin M López Muñoz -
Klemens Morgenstern -
Mungo Gill -
Peter Dimov -
Peter Koch Larsen -
Ruben Perez -
Seth -
Vinnie Falco