17175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier//===----------------------------------------------------------------------===//
27175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier//
37175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier//                     The LLVM Compiler Infrastructure
47175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier//
57175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
67175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier// Source Licenses. See LICENSE.TXT for details.
77175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier//
87175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier//===----------------------------------------------------------------------===//
97175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier
107175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier// UNSUPPORTED: c++98, c++03, c++11
117175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier
127175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier// <experimental/any>
137175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier
147175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier// Check that the size and alignment of any are what we expect.
157175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier
167175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier#include <experimental/any>
17e739d54f86e3a7f0b051f7190ffd8d40ed05ca44Eric Fiselier#include "experimental_any_helpers.h"
187175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier
192c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierconstexpr std::size_t BufferSize = (sizeof(void*) * 3);
202c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierconstexpr std::size_t BufferAlignment = alignof(void*);
212c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986.
222c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier// So we create "DoubleBufferAlignment" instead.
232c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierconstexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2;
242c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
257175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselierclass SmallThrowsDtor
267175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier{
277175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselierpublic:
287175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    SmallThrowsDtor() {}
297175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    SmallThrowsDtor(SmallThrowsDtor const &) noexcept {}
307175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    SmallThrowsDtor(SmallThrowsDtor &&) noexcept {}
317175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    ~SmallThrowsDtor() noexcept(false) {}
327175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier};
337175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier
342c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
352c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierstruct alignas(1) MaxSizeType {
362c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    char buff[BufferSize];
372c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier};
382c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
392c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierstruct alignas(BufferAlignment) MaxAlignType {
402c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier};
412c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
422c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierstruct alignas(BufferAlignment) MaxSizeAndAlignType {
432c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    char buff[BufferSize];
442c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier};
452c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
462c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
472c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierstruct alignas(1) OverSizeType {
482c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    char buff[BufferSize + 1];
492c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier};
502c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
512c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierstruct alignas(DoubleBufferAlignment) OverAlignedType {
522c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier};
532c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
542c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselierstruct alignas(DoubleBufferAlignment) OverSizeAndAlignedType {
552c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    char buff[BufferSize + 1];
562c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier};
572c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier
587175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselierint main()
597175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier{
607175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    using std::experimental::any;
617175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    using std::experimental::__any_imp::_IsSmallObject;
627175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    static_assert(_IsSmallObject<small>::value, "");
637175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    static_assert(_IsSmallObject<void*>::value, "");
647175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
657175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier    static_assert(!_IsSmallObject<large>::value, "");
662c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    {
672c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // Check a type that meets the size requirement *exactly* and has
682c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // a lesser alignment requirement is considered small.
692c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        typedef MaxSizeType T;
702c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(sizeof(T) == BufferSize, "");
712c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(alignof(T) < BufferAlignment,   "");
722c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(_IsSmallObject<T>::value, "");
732c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    }
742c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    {
752c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // Check a type that meets the alignment requirement *exactly* and has
762c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // a lesser size is considered small.
772c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        typedef MaxAlignType T;
782c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(sizeof(T) < BufferSize, "");
792c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(alignof(T) == BufferAlignment,   "");
802c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(_IsSmallObject<T>::value, "");
812c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    }
822c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    {
832c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // Check a type that meets the size and alignment requirements *exactly*
842c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // is considered small.
852c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        typedef MaxSizeAndAlignType T;
862c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(sizeof(T) == BufferSize, "");
872c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(alignof(T) == BufferAlignment,   "");
882c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(_IsSmallObject<T>::value, "");
892c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    }
902c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    {
912c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // Check a type that meets the alignment requirements but is over-sized
922c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // is not considered small.
932c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        typedef OverSizeType T;
942c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(sizeof(T) > BufferSize, "");
952c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(alignof(T) < BufferAlignment, "");
962c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(!_IsSmallObject<T>::value, "");
972c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    }
982c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    {
992c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // Check a type that meets the size requirements but is over-aligned
1002c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // is not considered small.
1012c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        typedef OverAlignedType T;
1022c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(sizeof(T) < BufferSize, "");
1032c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(alignof(T) > BufferAlignment, "");
1042c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(!_IsSmallObject<T>::value, "");
1052c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    }
1062c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    {
1072c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // Check a type that exceeds both the size an alignment requirements
1082c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        // is not considered small.
1092c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        typedef OverSizeAndAlignedType T;
1102c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(sizeof(T) > BufferSize, "");
1112c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(alignof(T) > BufferAlignment, "");
1122c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier        static_assert(!_IsSmallObject<T>::value, "");
1132c9141a0a27ee28f7489c188001ba554b9b70d1aEric Fiselier    }
1147175a079211ec78c8232d9d55fa4c1f9eeae803dEric Fiselier}
115