[Repost][RFC] Alternative any design

I posted this the same day 1.33 was released, but got no reply, I'd like to think it was due to bad timing rather than lack of interest. Any comments are welcome... ---- Original post ---- Hi, First of all, thanks to everyone who's commented on the proposed any alternative. Given that the alignment issue doesn't seem to be easy to solve, I'm thinking of giving up on trying to align correctly, and just skip the "in place storing of value" optimization when it might be an issue. So I'm wondering, is the following a proper way to detect alignment problems? <code> typedef void* any_buffer_base_type; // could be customized int const ANY_BUFFER_SIZE = sizeof(any_buffer_base_type); union object_holder { char buffer[ANY_BUFFER_SIZE]; void* pointer; any_buffer_base_type alignment_dummy_; }; template<typename T> struct optimize { enum { T_size_ = sizeof(T) , base_size_ = sizeof(any_buffer_base_type) , size_ok_ = (T_size_ <= base_size_) , T_align_ = alignment_of<T>::value , base_align_= alignment_of<any_buffer_base_type>::value , align_ok_ = ((base_align_ % T_align_) == 0) , value = size_ok_ && align_ok_ }; }; </code> I looked at Optional's alignment tecnique, and couldn't come up with how to use it, given that the stored type for any changes at runtime. If there's something I missed about this, any help would be welcome. My current solution is to use the above shown code (assuming it works, of course!), and fall back on heap based storage when optimization is deemed not possible. The 2nd question I had to ask is, how should any's alignment type be specified, with a configuration macro or through a template parameter? I haven't posted an updated version, given that there's some issues (other than alignment) still requiring attention. Thanks in advance for any help you might provide, Pablo Aguilar

First of all, thanks to everyone who's commented on the proposed any alternative.
Given that the alignment issue doesn't seem to be easy to solve, I'm thinking of giving up on trying to align correctly, and just skip the "in place storing of value" optimization when it might be an issue.
So I'm wondering, is the following a proper way to detect alignment problems?
I don't remember exactly the case but the problem was to store a member buffer properly aligned, so that it could be used instead of the dynamic allocation. I don't know if this can be enough for you but in my Shmem library I use boost::detail::max_align alignment to detect the most restrictive alignment of the platform so that I align memory returned from allocators to that boundary. alignment_of_max_align = ::boost::alignment_of<::boost::detail::max_align>::value Normally, the result is a 8 byte alignment. You could use an array of max_align structs as the buffer and overwrite it, since in practice the alignment is 8 bytes and max_align is usually 8 bytes so: template <...> class any { //Use a max_align arry as buffer boost::detail::max_align[max_bytes/sizeof(boost::detail::max_align]buf; }; 8 byte alignment align it anyways acceptable and although you round the buffer size to 8 bytes and waste 7 bytes for a single char, a call to "new" is going to waste at least 8 bytes in bookeeping and another 8 rounding it to the most restrictive alignment, becouse although new knows the type, is usually implemented on top of malloc. The member buffer will speed up allocations A LOT, because apart from avoiding the dynamic allocation to a stack pointer increment, it will avoid the mutex locking new usually has in multithreaded enviroments. Hope this works, Ion

Thanks! I've updated the implementation to use this. I'm still missing a proper implementation for optimized, different type swap, and a stronger exception safety guarantee for assignment. The latest version is available at the same place: http://tinyurl.com/9wv28 Tested and worked on VC6, VC7.1 and BC6 Pablo
I don't remember exactly the case but the problem was to store a member buffer properly aligned, so that it could be used instead of the dynamic allocation. I don't know if this can be enough for you but in my Shmem library I use boost::detail::max_align alignment to detect the most restrictive alignment of the platform so that I align memory returned from allocators to that boundary.
alignment_of_max_align = ::boost::alignment_of<::boost::detail::max_align>::value
Normally, the result is a 8 byte alignment. You could use an array of max_align structs as the buffer and overwrite it, since in practice the alignment is 8 bytes and max_align is usually 8 bytes so:
template <...> class any {
//Use a max_align arry as buffer boost::detail::max_align[max_bytes/sizeof(boost::detail::max_align]buf; };
8 byte alignment align it anyways acceptable and although you round the buffer size to 8 bytes and waste 7 bytes for a single char, a call to "new" is going to waste at least 8 bytes in bookeeping and another 8 rounding it to the most restrictive alignment, becouse although new knows the type, is usually implemented on top of malloc.
The member buffer will speed up allocations A LOT, because apart from avoiding the dynamic allocation to a stack pointer increment, it will avoid the mutex locking new usually has in multithreaded enviroments.
Hope this works,
Ion
participants (2)
-
Ion Gaztañaga
-
Pablo Aguilar