C++ Logo

sg16

Advanced search

Re: [SG16] [isocpp-lib-ext] D1030R4 draft 2: std::filesystem::path_view

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Wed, 21 Oct 2020 17:12:07 +0100
On Fri, 16 Oct 2020 at 10:12, Niall Douglas via Lib-Ext <
lib-ext_at_[hidden]> wrote:

> On 15/10/2020 18:15, Peter Dimov wrote:
> > Niall Douglas wrote:
> >> >> If we insisted on Allocators, we would force a needless extra
> >> dynamic >> memory allocation and memory copy solely because we
> >> insisted on >> Allocators.
> >> >
> >> > I don't see why.
> >>
> >> My personal primary motivation are functions such as
> >>
> https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-rtlansistringtounicodestring
> >>
> >> or
> >>
> https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-rtlunicodestringtoansistring
> >>
> >> which are much more efficient if you let them allocate the destination
> >> buffer for you.
> >
> > OK, I see where you are coming from. However, I'm not quite sure that
> > this affects the allocator/deleter question. At the moment, you do this
> >
> > path_view::c_str<> tmp( path );
> >
> > to get the default allocation behavior, and you do this
> >
> > path_view::c_str<char, my_deleter> tmp( path, my_alloc_fn [,
> > my_deleter{...}] );
> >
> > to override it.
>
> Correct.
>
> > In the allocator-based version, you'd do this
> >
> > path_view::c_str<> tmp( path );
> >
> > to get the default behavior, and
> >
> > path_view::c_str<char, my_allocator> tmp( path [, my_alloc] );
> >
> > to override it>
> > There's no reason for the default allocator used in the first case to
> > not be able to deallocate (and allocate but that's not going to be
> > called) using the NT kernel API.
>
> Mmm. If you replace any notion of "the default allocator" with
> "implementation defined allocator", then what you propose would work for
> me.
>
> However, there is an additional issue: For me personally, Allocators
> ought to reserve space AND construct objects within i.e. bit clear the
> new allocation. That's inefficient here, because the reencode will
> create new objects into the new allocation, so bit clearing is wasted work.
>
> Now, you can simply say that we don't call construct() in the Allocator.
> But that seems to me to defeat the spirit of what people mean when they
> think of Allocators.
>

We have precedent for using allocators to obtain memory but not using them
to construct the objects. That's what std::basic_string does.



>
> > If you add a memory_resource* overload with nullptr meaning "default",
> > the second case can become
> >
> > path_view::c_str<> tmp( path, my_resource );
> >
> > at the cost of one additional pointer in c_str<>. Given that
> > sizeof(c_str<>) is 1K+, that's probably not going to be an issue.
> >
> > In fact with the right deduction guides these can turn into
> >
> > path_view::c_str tmp( path );
> >
> > path_view::c_str tmp( path, my_alloc_fn, my_deleter );
> >
> > for R4 and
> >
> > path_view::c_str tmp( path );
> >
> > path_view::c_str tmp( path, my_alloc );
> >
> > path_view::c_str tmp( path, my_resource );
> >
> > for the hypothetical allocator-taking interface.
>
> I'm not opposed to directly supporting memory_resource& as an extra
>

N.B. memory_resource* not memory_resource&

overload set. I like memory_resource, because it doesn't force a
> dependency on the memory_resource header, whereas bringing in a
> dependency on STL allocators drags in the not inconsiderable quantity of
> STL allocator machinery. I would really like that anything I add to the
> C++ standard library does not drag in a billion tokens of avoidable
> dependencies.
>
>
The entire <memory> header might be fairly large, but the
std::allocator_traits part is not, and that's all you need to support
allocators, isn't it? I don't think compromising the API to avoid that
dependency is a good trade off.



> A non obvious goal of path views is that they are standalone C++
> friendly i.e. allocators may not be available at all. I'll be stating
> that in the preamble to draft 3.
>
> Would directly supporting memory_resource& but not STL allocators
> directly work for you? Again I do want to emphasise it is trivially easy
> for users to wrap up a STL allocator into either the existing mechanism,
> or a memory_resource& for that matter.
>
>
Since we have no way in the standard (only in the Library Fundamentals TS)
to wrap an allocator into a memory_resource, but we do have a way to wrap a
memory_resource into an allocator, I think supporting allocators is the
more general approach. Saying "no, you have to use memory resources here"
is a plausible design choice, but it would be novel in the std::lib. We
haven't, as far as I am aware, decided that memory resources should be
preferred in new APIs.

Received on 2020-10-21 11:12:22