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