#include #include #include #include #include #include #include /* Given helper functions */ template T* retrieve(char* memory) { /* TODO: Properly interpret the memory pointer as a T pointer and return it */ /* NOTE: Remember to launder the pointer */ } void empty_dtor(char*) { } template void default_dtor(char* memory) { auto object = retrieve(memory); /* TODO: Call the destructor on object */ } /* Write Bounded_Any here */ /* Testcases */ int main() { // Make sure that we can create an empty Bounded_Any Bounded_Any<4> a1 { }; assert( !a1.has_value() ); // Make a1 an integer a1 = 5; assert( a1.has_type() ); assert( a1.get() == 5 ); // Try to assign it something that is larger than // what can be fit in the bounded any try { a1 = 5.0; assert( false ); } catch (...) { } // Make sure the error didn't change the currently stored data assert( a1.has_type() ); assert( a1.get() == 5 ); // Create a new block to test that destruction works properly { Bounded_Any<100> a2 { }; // Set the bounded any to a LARGE string (as to force allocations) a2 = std::string(1024, '+'); assert( a2.has_type() ); assert( a2.get() == std::string(1024, '+') ); // Clear the data (which should result in the string destructor being called) a2.clear(); assert( !a2.has_type() ); assert( !a2.has_value() ); // Insert a large vector instead, and make sure that the destructor of // Bounded_Any properly calls the std::vector destructor. a2 = std::vector(2048, 1); assert( a2.has_type>() ); assert( a2.get>() == std::vector(2048, 1) ); } a1.clear(); // Make sure clearing resets the any to its default state assert( !a1.has_type() ); assert( !a1.has_value() ); }