blob: b2c8545eb36f078d3fd2eb878f0256c58aaa8901 [file] [log] [blame]
//===-- 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<int> Trivial1(12);
ASSERT_TRUE(Trivial1.has_value());
ASSERT_EQ(Trivial1.value(), 12);
ASSERT_EQ(*Trivial1, 12);
Trivial1.reset();
ASSERT_FALSE(Trivial1.has_value());
optional<int> 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<Contrived> 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<int> Trivial3(12);
optional<int> Trivial4 = Trivial3;
ASSERT_TRUE(Trivial4.has_value());
ASSERT_EQ(Trivial4.value(), 12);
// Test that assigning an option to another works when unset
optional<int> Trivial5;
ASSERT_FALSE(Trivial5.has_value());
optional<int> Trivial6 = Trivial5;
ASSERT_FALSE(Trivial6.has_value());
// Test operator->
int arrow_num = 5;
optional<Contrived> 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();
}