1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// UNSUPPORTED: c++98, c++03, c++11, c++14 11 12// <any> 13 14// Check that the size and alignment of any are what we expect. 15 16#include <any> 17#include "any_helpers.h" 18 19constexpr std::size_t BufferSize = (sizeof(void*) * 3); 20constexpr std::size_t BufferAlignment = alignof(void*); 21// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986. 22// So we create "DoubleBufferAlignment" instead. 23constexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2; 24 25class SmallThrowsDtor 26{ 27public: 28 SmallThrowsDtor() {} 29 SmallThrowsDtor(SmallThrowsDtor const &) noexcept {} 30 SmallThrowsDtor(SmallThrowsDtor &&) noexcept {} 31 ~SmallThrowsDtor() noexcept(false) {} 32}; 33 34 35struct alignas(1) MaxSizeType { 36 char buff[BufferSize]; 37}; 38 39struct alignas(BufferAlignment) MaxAlignType { 40}; 41 42struct alignas(BufferAlignment) MaxSizeAndAlignType { 43 char buff[BufferSize]; 44}; 45 46 47struct alignas(1) OverSizeType { 48 char buff[BufferSize + 1]; 49}; 50 51struct alignas(DoubleBufferAlignment) OverAlignedType { 52}; 53 54struct alignas(DoubleBufferAlignment) OverSizeAndAlignedType { 55 char buff[BufferSize + 1]; 56}; 57 58int main() 59{ 60 using std::any; 61 using std::__any_imp::_IsSmallObject; 62 static_assert(_IsSmallObject<small>::value, ""); 63 static_assert(_IsSmallObject<void*>::value, ""); 64 static_assert(!_IsSmallObject<SmallThrowsDtor>::value, ""); 65 static_assert(!_IsSmallObject<large>::value, ""); 66 { 67 // Check a type that meets the size requirement *exactly* and has 68 // a lesser alignment requirement is considered small. 69 typedef MaxSizeType T; 70 static_assert(sizeof(T) == BufferSize, ""); 71 static_assert(alignof(T) < BufferAlignment, ""); 72 static_assert(_IsSmallObject<T>::value, ""); 73 } 74 { 75 // Check a type that meets the alignment requirement *exactly* and has 76 // a lesser size is considered small. 77 typedef MaxAlignType T; 78 static_assert(sizeof(T) < BufferSize, ""); 79 static_assert(alignof(T) == BufferAlignment, ""); 80 static_assert(_IsSmallObject<T>::value, ""); 81 } 82 { 83 // Check a type that meets the size and alignment requirements *exactly* 84 // is considered small. 85 typedef MaxSizeAndAlignType T; 86 static_assert(sizeof(T) == BufferSize, ""); 87 static_assert(alignof(T) == BufferAlignment, ""); 88 static_assert(_IsSmallObject<T>::value, ""); 89 } 90 { 91 // Check a type that meets the alignment requirements but is over-sized 92 // is not considered small. 93 typedef OverSizeType T; 94 static_assert(sizeof(T) > BufferSize, ""); 95 static_assert(alignof(T) < BufferAlignment, ""); 96 static_assert(!_IsSmallObject<T>::value, ""); 97 } 98 { 99 // Check a type that meets the size requirements but is over-aligned 100 // is not considered small. 101 typedef OverAlignedType T; 102 static_assert(sizeof(T) < BufferSize, ""); 103 static_assert(alignof(T) > BufferAlignment, ""); 104 static_assert(!_IsSmallObject<T>::value, ""); 105 } 106 { 107 // Check a type that exceeds both the size an alignment requirements 108 // is not considered small. 109 typedef OverSizeAndAlignedType T; 110 static_assert(sizeof(T) > BufferSize, ""); 111 static_assert(alignof(T) > BufferAlignment, ""); 112 static_assert(!_IsSmallObject<T>::value, ""); 113 } 114} 115