[PATCH] [libcxx] Add <experimental/any> header for LFTS.
Eric Fiselier
eric at efcs.ca
Tue Jul 15 02:33:05 PDT 2014
Hi mclow.lists,
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
http://reviews.llvm.org/D4514
Files:
include/experimental/any
src/any.cpp
test/experimental/any/any.class/any.assign/copy_large_throws.pass.cpp
test/experimental/any/any.class/any.assign/copy_self.pass.cpp
test/experimental/any/any.class/any.assign/copy_small_throws.pass.cpp
test/experimental/any/any.class/any.assign/copy_to_empty.pass.cpp
test/experimental/any/any.class/any.assign/copy_to_large.pass.cpp
test/experimental/any/any.class/any.assign/copy_to_small.pass.cpp
test/experimental/any/any.class/any.assign/large_value_copy_throws.pass.cpp
test/experimental/any/any.class/any.assign/move_noexcept.pass.cpp
test/experimental/any/any.class/any.assign/move_self.pass.cpp
test/experimental/any/any.class/any.assign/move_to_empty.pass.cpp
test/experimental/any/any.class/any.assign/move_to_large.pass.cpp
test/experimental/any/any.class/any.assign/move_to_small.pass.cpp
test/experimental/any/any.class/any.assign/small_value_copy_throws.pass.cpp
test/experimental/any/any.class/any.assign/value_move_throws.pass.cpp
test/experimental/any/any.class/any.assign/value_non_copyable_assign.fail.cpp
test/experimental/any/any.class/any.assign/value_to_empty.pass.cpp
test/experimental/any/any.class/any.assign/value_to_large.pass.cpp
test/experimental/any/any.class/any.assign/value_to_small.pass.cpp
test/experimental/any/any.class/any.cons/alloc.pass.cpp
test/experimental/any/any.class/any.cons/alloc_copy.pass.cpp
test/experimental/any/any.class/any.cons/alloc_copy_throws.pass.cpp
test/experimental/any/any.class/any.cons/alloc_move.pass.cpp
test/experimental/any/any.class/any.cons/alloc_move_throws.pass.cpp
test/experimental/any/any.class/any.cons/alloc_non_copyable_value.fail.cpp
test/experimental/any/any.class/any.cons/alloc_value.pass.cpp
test/experimental/any/any.class/any.cons/alloc_value_alloc_throws.pass.cpp
test/experimental/any/any.class/any.cons/alloc_value_throws.pass.cpp
test/experimental/any/any.class/any.cons/copy.pass.cpp
test/experimental/any/any.class/any.cons/copy_throws.pass.cpp
test/experimental/any/any.class/any.cons/default.pass.cpp
test/experimental/any/any.class/any.cons/move.pass.cpp
test/experimental/any/any.class/any.cons/move_throws.pass.cpp
test/experimental/any/any.class/any.cons/non_copyable_value.fail.cpp
test/experimental/any/any.class/any.cons/uses_allocator_alloc_at_end.pass.cpp
test/experimental/any/any.class/any.cons/uses_allocator_allocator_arg_t.pass.cpp
test/experimental/any/any.class/any.cons/uses_allocator_both_signatures.pass.cpp
test/experimental/any/any.class/any.cons/value.pass.cpp
test/experimental/any/any.class/any.cons/value_copy_throws.pass.cpp
test/experimental/any/any.class/any.cons/value_move_throws.pass.cpp
test/experimental/any/any.class/any.modifiers/clear.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_empty_empty.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_empty_large.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_empty_small.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_large_large.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_large_small.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_noexcept.pass.cpp
test/experimental/any/any.class/any.modifiers/swap_small_small.pass.cpp
test/experimental/any/any.class/any.observers/empty.pass.cpp
test/experimental/any/any.class/any.observers/type.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/bad_type.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/empty.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/large_value.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/noexcept.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/nullptr.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.nothrow/small_value.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/const_lvalue_cast_const_correctness.fail.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/const_lvalue_cast_not_copy_constructible.fail.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/empty.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/large.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/lvalue_cast_not_copy_constructible.fail.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/non_copy_ref.pass.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/rvalue_cast_not_copy_constructible.fail.cpp
test/experimental/any/any.nonmembers/any.cast/any.cast.throws/small.pass.cpp
test/experimental/any/any.nonmembers/any.cast/nothing_to_do.pass.cpp
test/experimental/any/any.nonmembers/swap.pass.cpp
test/experimental/any/count_new.hpp
test/experimental/any/large_type.hpp
test/experimental/any/small_type.hpp
test/experimental/any/version.pass.cpp
www/ts1z_status.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4514.11422.patch
Type: text/x-patch
Size: 209880 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140715/89a5fbbe/attachment.bin>
More information about the cfe-commits
mailing list