[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