[GSoC] Update on extend shared_ptr to support array
Fan You
youfan.noey@gmail.com
Wed Mar 25 15:13:00 GMT 2015
>2015-03-24 8:54 GMT-04:00 Jonathan Wakely <jwakely@redhat.com>:
> Have you submitted a formal GSoC proposal to Melange yet? I have just
> renewed my Melange account and applied to be a mentor again, so I
> can't see the proposals until that is approved.
Yes, I've already submitted it.
> There's an issue I'd forgotten about which we should probably address:
>
> In C++11 today, it is already possible to use std::shared_ptr<T[N]>,
> although it's hard to use correctly and almost useless. For example,
> this is valid in C++11:
>
> #include <memory>
>
> int main()
> {
> int array[3];
> std::shared_ptr<int[3]> p(&array, [](void*){});
> }
>
> Although it's hard to use, this is technically valid and has clearly
> defined semantics, which are different from
> std::experimental::shared_ptr<int[3]>. In particular,
> std::shared_ptr<int[3]>::element_type is int[3] but
> std::experimental::shared_ptr<int[3]>::element_type is int.
>
> (I'm not sure if a non-empty std::shared_ptr<T[]>, i.e. array of
> unknown bound, can be used in C++11, so that might be even more
> useless).
>
> So while you're implementing the new semantics, we need to decide if
> we want to continue supporting the old semantics (which are
> technically required for C++11 conformance, but it's possible no-one
> cares about that.)
>
> I hope I've explained that clearly, let me know if I didn't.
It's pretty clear, thanks :)
>
> I advised you to add a specialization of std::__shared_ptr<T[]>, so
> that std::experimental::shared_ptr<T[]> would be simple to write and
> most of the implementation would be in the __shared_ptr
> specialization. That makes it impossible to support the old C++11
> semantics, so it might not be the right approach (sorry!)
>
> I can see at least three options:
>
> (1) Ignore the C++11 requirements and just make __shared_ptr<T[]> and
> __shared_ptr<T[N]> meet the Fundamentals TS requirements. This
> would be the simplest option, but is not strictly conforming and
> carries some risk (C++17 might specify std::shared_ptr<T[]>
> differently from std::experimental::shared_ptr<T[]> and we'd have
> to change it again).
I don't know how much risk would C++17 put on this. But right, it's the
simplest solution for now.
>
> (2) Do not change __shared_ptr. Implement experimental::shared_ptr<T>
> by simply deriving from __shared_ptr<T>. Implement the array
> specializations experimental::shared_ptr<T[N]> and
> experimental::shared_ptr<T[]> by re-implementing them completely,
> without using __shared_ptr. That is quite a lot of work, and code
> duplication (you would need to write all the comparison operators
> again for the specializations).
This is my first idea and its the "safest" one, I guess. However,
In my first working sample, I also find that it will cause a lot duplications,
which is unnecessary. So, this may not be a good option.
>
> (3) Add a specialization for __shared_ptr<__libfund_v1<T>> where
> __libfund_v1 is just a simple tag type like:
>
> template<typename _Tp>
> struct __libfund_v1 { using type = _Tp; };
>
> The __shared_ptr<__libfund_v1<>> specialization would implement
> the Fundamentals TS semantics, i.e. array support, then make
> experimental::shared_ptr<T[N]> derive from
> __shared_ptr<__libfund_v1<T[N]>> so it uses the specialization.
> This would allow us to isolate the different semantics required by
> the Library Fundamentals TS in the new specialization, not
> changing the behaviour of the C++11 shared_ptr template.
>
> We could also add the following alias template to allow people to
> use the new specialization directly (for people who want to use
> __shared_ptr<T[], LP> with a non-default lock policy):
>
> namespace std { namespace experimental {
> template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
> using __shared_ptr = std::__shared_ptr<__libfund_v1<_Tp>, _Lp>;
> } }
>
>
> Any other suggestions?
>
> I think it would be good to discuss this (and maybe experiment with
> the different options) before doing too much more work that might go
> in a wrong direction.
>
The third one could be a good option. This one didn't actually add too much
complexity on the first option. I can start doing some experiments on it.
I have no other suggestion for now, maybe I will come up with some
during the experiment.
More information about the Libstdc++
mailing list