xref: /llvm-project/libc/test/src/__support/CPP/optional_test.cpp (revision f90f036efbe6879ecf1c9ff8cf0fb956b5ceb877)
13b631e47SJeff Bailey //===-- Unittests for Optional --------------------------------------------===//
23b631e47SJeff Bailey //
33b631e47SJeff Bailey // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43b631e47SJeff Bailey // See https://llvm.org/LICENSE.txt for license information.
53b631e47SJeff Bailey // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63b631e47SJeff Bailey //
73b631e47SJeff Bailey //===----------------------------------------------------------------------===//
83b631e47SJeff Bailey 
93b631e47SJeff Bailey #include "src/__support/CPP/optional.h"
10af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h"
113b631e47SJeff Bailey 
12b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::cpp::nullopt;
13b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::cpp::optional;
143b631e47SJeff Bailey 
1542e2946fSMichael Jones // This class has three properties for testing:
1642e2946fSMichael Jones // 1) No default constructor.
1742e2946fSMichael Jones // 2) A non-trivial destructor with an observable side-effect.
1842e2946fSMichael Jones // 3) Functions that can be called explicitly.
193b631e47SJeff Bailey class Contrived {
203b631e47SJeff Bailey   int *_a;
213b631e47SJeff Bailey 
223b631e47SJeff Bailey public:
Contrived(int * a)233b631e47SJeff Bailey   Contrived(int *a) : _a(a) {}
~Contrived()243b631e47SJeff Bailey   ~Contrived() { (*_a)++; }
2542e2946fSMichael Jones 
get_a()2642e2946fSMichael Jones   int get_a() { return *_a; }
inc_a()2742e2946fSMichael Jones   void inc_a() { (*_a)++; }
283b631e47SJeff Bailey };
293b631e47SJeff Bailey 
TEST(LlvmLibcOptionalTest,Tests)303b631e47SJeff Bailey TEST(LlvmLibcOptionalTest, Tests) {
313b631e47SJeff Bailey   optional<int> Trivial1(12);
323b631e47SJeff Bailey   ASSERT_TRUE(Trivial1.has_value());
333b631e47SJeff Bailey   ASSERT_EQ(Trivial1.value(), 12);
343b631e47SJeff Bailey   ASSERT_EQ(*Trivial1, 12);
353b631e47SJeff Bailey   Trivial1.reset();
363b631e47SJeff Bailey   ASSERT_FALSE(Trivial1.has_value());
373b631e47SJeff Bailey 
383b631e47SJeff Bailey   optional<int> Trivial2(12);
393b631e47SJeff Bailey   ASSERT_TRUE(Trivial2.has_value());
403b631e47SJeff Bailey   Trivial2 = nullopt;
413b631e47SJeff Bailey   ASSERT_FALSE(Trivial2.has_value());
423b631e47SJeff Bailey 
433b631e47SJeff Bailey   // For this test case, the destructor increments the pointed-to value.
443b631e47SJeff Bailey   int holding = 1;
45*f90f036eSmichaelrj-google   {
463b631e47SJeff Bailey     optional<Contrived> Complicated(&holding);
473b631e47SJeff Bailey     // Destructor was run once as part of copying the object.
483b631e47SJeff Bailey     ASSERT_EQ(holding, 2);
493b631e47SJeff Bailey     // Destructor was run a second time as part of destruction.
503b631e47SJeff Bailey     Complicated.reset();
513b631e47SJeff Bailey     ASSERT_EQ(holding, 3);
523b631e47SJeff Bailey     // Destructor was not run a third time as the object is already destroyed.
533b631e47SJeff Bailey     Complicated.reset();
543b631e47SJeff Bailey     ASSERT_EQ(holding, 3);
55*f90f036eSmichaelrj-google   }
56*f90f036eSmichaelrj-google   // Make sure the destructor isn't called when the optional is destroyed.
57*f90f036eSmichaelrj-google   ASSERT_EQ(holding, 3);
583b631e47SJeff Bailey 
593b631e47SJeff Bailey   // Test that assigning an optional to another works when set
603b631e47SJeff Bailey   optional<int> Trivial3(12);
613b631e47SJeff Bailey   optional<int> Trivial4 = Trivial3;
623b631e47SJeff Bailey   ASSERT_TRUE(Trivial4.has_value());
633b631e47SJeff Bailey   ASSERT_EQ(Trivial4.value(), 12);
643b631e47SJeff Bailey 
653b631e47SJeff Bailey   // Test that assigning an option to another works when unset
663b631e47SJeff Bailey   optional<int> Trivial5;
673b631e47SJeff Bailey   ASSERT_FALSE(Trivial5.has_value());
683b631e47SJeff Bailey   optional<int> Trivial6 = Trivial5;
693b631e47SJeff Bailey   ASSERT_FALSE(Trivial6.has_value());
7042e2946fSMichael Jones 
7142e2946fSMichael Jones   // Test operator->
7242e2946fSMichael Jones   int arrow_num = 5;
7342e2946fSMichael Jones   optional<Contrived> arrow_test(&arrow_num);
7442e2946fSMichael Jones   ASSERT_TRUE(arrow_test.has_value());
7542e2946fSMichael Jones   ASSERT_EQ(arrow_test->get_a(), arrow_num);
7642e2946fSMichael Jones   arrow_num = 10;
7742e2946fSMichael Jones   ASSERT_EQ(arrow_test->get_a(), arrow_num);
7842e2946fSMichael Jones   arrow_test->inc_a();
7942e2946fSMichael Jones   ASSERT_EQ(arrow_test->get_a(), arrow_num);
8042e2946fSMichael Jones   ASSERT_EQ(arrow_num, 11);
8142e2946fSMichael Jones   arrow_test.reset();
823b631e47SJeff Bailey }
83