This patch adds the <experimental/any> header as specified in the latest draft of the library fundamentals TS.
The any implementation is based off of libc++'s std::function. It uses the same storage methods and small object optimization.
Implementation Summary:
- Small Object Optimization:
- buffer size = 3*sizeof(void*)
- Three requirements for being a "small object".
- sizeof(__storage<T, Alloc>) <= 3*sizeof(void*)
- alignof(__storage<T,Alloc>) % alignof(aligned_storage<3*sizeof(void*)>) == 0
- is_nothrow_move_constructible<T>.
- Third condition needed to implement noexcept move and swap.
- an any instance contains a buffer and a __storage_base pointer.
- An object is stored locally when storage_ptr == (__storage_base*)&buffer.
- NOTE: GCC warns about type punning in the code above. Could that be a real defect?
- Uses allocator construction:
- Implementation based off of std::tuple's.
- Uses __uses_alloc_ctor from <__functional_base> to tag dispatch to the correct constructor.
- The copy/move constructors are not implementable.
- Supports _LIBCPP_NO_EXCEPTIONS.
- Does not support _LIBCPP_NO_RTTI.
Parts likely to contain defects:
- Allocators
- I haven't used allocators much and proper use is complex.
- The current implementation of __uses_alloc_ctor does not handle the 4th error case explicitly. I need to submit a patch for that separately.
- Type casting
- As mentioned above, GCC warns about type punning in the pointer comparisons.
- I always pass the derived storage pointer to placement new unlike std::function that sometimes passes the base storage pointer.
- Complex resource management (swap and copy constructors).
Open Questions:
- De-virtualization?
- This can be implemented in pure C++11. Can in be enabled in that mode?
- Whats is the best behavior for the unimplementable uses allocator move/copy constructors