//===-- Unittests for Optional --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "src/__support/CPP/optional.h" #include "test/UnitTest/Test.h" using LIBC_NAMESPACE::cpp::nullopt; using LIBC_NAMESPACE::cpp::optional; // This class has three properties for testing: // 1) No default constructor. // 2) A non-trivial destructor with an observable side-effect. // 3) Functions that can be called explicitly. class Contrived { int *_a; public: Contrived(int *a) : _a(a) {} ~Contrived() { (*_a)++; } int get_a() { return *_a; } void inc_a() { (*_a)++; } }; TEST(LlvmLibcOptionalTest, Tests) { optional Trivial1(12); ASSERT_TRUE(Trivial1.has_value()); ASSERT_EQ(Trivial1.value(), 12); ASSERT_EQ(*Trivial1, 12); Trivial1.reset(); ASSERT_FALSE(Trivial1.has_value()); optional Trivial2(12); ASSERT_TRUE(Trivial2.has_value()); Trivial2 = nullopt; ASSERT_FALSE(Trivial2.has_value()); // For this test case, the destructor increments the pointed-to value. int holding = 1; { optional Complicated(&holding); // Destructor was run once as part of copying the object. ASSERT_EQ(holding, 2); // Destructor was run a second time as part of destruction. Complicated.reset(); ASSERT_EQ(holding, 3); // Destructor was not run a third time as the object is already destroyed. Complicated.reset(); ASSERT_EQ(holding, 3); } // Make sure the destructor isn't called when the optional is destroyed. ASSERT_EQ(holding, 3); // Test that assigning an optional to another works when set optional Trivial3(12); optional Trivial4 = Trivial3; ASSERT_TRUE(Trivial4.has_value()); ASSERT_EQ(Trivial4.value(), 12); // Test that assigning an option to another works when unset optional Trivial5; ASSERT_FALSE(Trivial5.has_value()); optional Trivial6 = Trivial5; ASSERT_FALSE(Trivial6.has_value()); // Test operator-> int arrow_num = 5; optional arrow_test(&arrow_num); ASSERT_TRUE(arrow_test.has_value()); ASSERT_EQ(arrow_test->get_a(), arrow_num); arrow_num = 10; ASSERT_EQ(arrow_test->get_a(), arrow_num); arrow_test->inc_a(); ASSERT_EQ(arrow_test->get_a(), arrow_num); ASSERT_EQ(arrow_num, 11); arrow_test.reset(); }