#include #include #include #include #include struct checker { static unsigned cnt; checker() { ++cnt; } checker(const checker&) { ++cnt; } checker(checker&&) noexcept { ++cnt; } ~checker() { --cnt; } }; unsigned checker::cnt = 0; int main() { using option::option; auto check_cnt = [](unsigned expect) { if (expect != checker::cnt) { std::printf("Checker: expect=%u cnt=%u\n", expect, checker::cnt); std::abort(); } }; { const option kO1{}; const option kO2{::option::none{}}; assert(!kO1.has_value()); assert(!kO2.has_value()); } // Assume we start test with cnt=0. check_cnt(0); { option o1(checker{}); // copy construct option o2 = o1; // move construct option o3 = o1.take(); assert(!o1.has_value()); assert(o2.has_value()); assert(o3.has_value()); // move option option o4 = std::move(o2); assert(!o2.has_value()); assert(o4.has_value()); option o5; // copy assign o5 = o4; assert(o4.has_value()); assert(o5.has_value()); option o6; // move assign o6 = std::move(o5); assert(!o5.has_value()); assert(o6.has_value()); // take reference to inner auto x = o3.value(); // take ownership of inner auto y = o4.take(); assert(!o1.has_value()); assert(!o2.has_value()); assert(o3.has_value()); assert(!o4.has_value()); } // Expect to finish test with cnt=0. check_cnt(0); { option o1; assert(!o1.has_value()); o1.emplace(); assert(o1.has_value()); } // Expect to finish test with cnt=0. check_cnt(0); return 0; }