
On 1.2.2012. 17:53, Hite, Christopher wrote:
On 27.1.2012. 11:32, Domagoj Saric wrote:
a) the lifetime management bool was changed into a properly typed pointer (this actually takes the same amount of space while it provides a no-op get_ptr() member function as well as easier debugging as the contents of optional can now clearly be seen through the pointer, as opposed to gibberish in an opaque storage array) I'd support this only if were configurable. It takes more space for small or non-word-aligned data.
True, I was planning on automatically deciding between bool and pointer based on sizeof( T ) after adding lifetime management policy support (m)...
It might be more expensive on some systems to calculate the address and store it.
How? You have to fetch the address either way...
It would also break has_trivial_copy. If someone was naughty and memcopied them, the new version would lead to a very hard to find bug.
True, didn't think about trivial copy until Sebastian outlined the pass-POD-in-register requirements of the AMD x64 ABI. WRT to this it boils down to whether you want a no-op get_ptr() or your platform and compiler actually support passing PODs in registers _and_ most of the types you store in optionals actually satisfy the compiler/ABI requirements for that _and_ you mostly pass and return those optionals by value...
As for the debugger the new C++ allows for a union to contain a class. So if a placeholder implemention using such a union would show the data in debug.
But the pointer approach would also work with "real world" compilers ;)
h) optional marks itself as uninitialised _before_ calling the contained object's destructor (this makes it a little more robust in race conditions; it is of course not a complete solution for such scenarios, those require external "help" and/or (m)-reference counting to be implemented) Seems to contradict (g). I'd support something like that only if it can be configured out. Maybe there's some case completely out of optional's scope where you use atomic ops.
It doesn't (contradict (g)), this applies only to situations where you actually have to mark the optional as empty (such as when reset() is called).
If you factor out the aligned storage you can build something else that does ref-counting or a thread safe state machine or whatever.
With (m) I'd rather (in some distant future:) add a refcounting policy to optional (or some future underlying more generic class) so that users don't have to reimplement this...
k) the lifetime management pointer is now stored after the actual contained object (this helps in avoiding more complex/offset addressing when accessing optionals through pointers w/o checking whether they are initialised) Seems weird. If the front of T is more likely to be used (and old char buffer), your pointer may wind up in a different cache line.
Well yes, as I said this benefits only the cases where the pointer/bool is not accessed (when an optional is accessed through a pointer/reference). IOW in 99.9% of real world cases the point is quite moot but it did make sense at a particular stage of a project I'm working on (when you have dozens of hundreds of template generated functions you can actually measure savings in code size when you do even such micromanagement). It no longer matters for me but the layout of optional2 is still like that (currently) purely because it turned out like that (in the current stage of development) so I wrote point (k) nonetheless just for the feedback ;)
So the big thing I take away from all this it would be really nice if some things were configurable. How do we do that without breaking code?
Changing the signature to optional<T,Properties=optional_traits<T> >, might break code that uses boost::optional as a template template parameter.
Judging for example from the rationale for the lack of smart_ptr configurability or from the feedback I got for my improved boost::function proposal, it would be very difficult for this type of configurability for optional to get accepted. I was rather planing on making the best of optional with automatic/self configuration based on properties of T and then later (in a galaxy far far away:) propse an underlying library ("smart resource" or something like that), that would separate the lifetime management and storage concerns in a maximally configurable manner, on top of which traditional optional smart_ptr could be built... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman