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