diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-10-01 02:12:35 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-10-01 02:12:35 +0000 |
commit | 4f09cd697cdcd0f55b9d74ef5586ca0ea78c00b5 (patch) | |
tree | 4e1367528bd2597649701f00b6246b4050a4c255 /llvm/unittests/ADT/OptionalTest.cpp | |
parent | 14798caac6935bec50abac2b6419c75331989f7a (diff) | |
download | bcm5719-llvm-4f09cd697cdcd0f55b9d74ef5586ca0ea78c00b5.tar.gz bcm5719-llvm-4f09cd697cdcd0f55b9d74ef5586ca0ea78c00b5.zip |
Add an emplace(...) method to llvm::Optional<T>.
This can be used for in-place initialization of non-moveable types.
For compilers that don't support variadic templates, only up to four
arguments are supported. We can always add more, of course, but this
should be good enough until we move to a later MSVC that has full
support for variadic templates.
Inspired by std::experimental::optional from the "Library Fundamentals" C++ TS.
Reviewed by David Blaikie.
llvm-svn: 218732
Diffstat (limited to 'llvm/unittests/ADT/OptionalTest.cpp')
-rw-r--r-- | llvm/unittests/ADT/OptionalTest.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp index 51c54523b88..5a763d76f45 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -177,6 +177,44 @@ TEST_F(OptionalTest, GetValueOr) { EXPECT_EQ(5, A.getValueOr(42)); } +struct MultiArgConstructor { + int x, y; + MultiArgConstructor(int x, int y) : x(x), y(y) {} + explicit MultiArgConstructor(int x, bool positive) + : x(x), y(positive ? x : -x) {} + + MultiArgConstructor(const MultiArgConstructor &) = delete; + MultiArgConstructor(MultiArgConstructor &&) = delete; + MultiArgConstructor &operator=(const MultiArgConstructor &) = delete; + MultiArgConstructor &operator=(MultiArgConstructor &&) = delete; + + static unsigned Destructions; + ~MultiArgConstructor() { + ++Destructions; + } + static void ResetCounts() { + Destructions = 0; + } +}; +unsigned MultiArgConstructor::Destructions = 0; + +TEST_F(OptionalTest, Emplace) { + MultiArgConstructor::ResetCounts(); + Optional<MultiArgConstructor> A; + + A.emplace(1, 2); + EXPECT_TRUE(A.hasValue()); + EXPECT_EQ(1, A->x); + EXPECT_EQ(2, A->y); + EXPECT_EQ(0u, MultiArgConstructor::Destructions); + + A.emplace(5, false); + EXPECT_TRUE(A.hasValue()); + EXPECT_EQ(5, A->x); + EXPECT_EQ(-5, A->y); + EXPECT_EQ(1u, MultiArgConstructor::Destructions); +} + struct MoveOnly { static unsigned MoveConstructions; static unsigned Destructions; @@ -286,6 +324,17 @@ TEST_F(OptionalTest, MoveOnlyAssigningAssignment) { EXPECT_EQ(1u, MoveOnly::Destructions); } +TEST_F(OptionalTest, MoveOnlyEmplace) { + Optional<MoveOnly> A; + MoveOnly::ResetCounts(); + A.emplace(4); + EXPECT_TRUE((bool)A); + EXPECT_EQ(4, A->val); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); +} + #if LLVM_HAS_RVALUE_REFERENCE_THIS TEST_F(OptionalTest, MoveGetValueOr) { |