Optional.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/std/hash.h>
  9. #include <AzCore/std/optional.h>
  10. #include "UserTypes.h"
  11. using AZStd::optional;
  12. using AZStd::nullopt;
  13. using AZStd::in_place;
  14. namespace OptionalTestClasses
  15. {
  16. class NonTriviallyDestructableClass
  17. {
  18. public:
  19. ~NonTriviallyDestructableClass() {}
  20. };
  21. class NonTriviallyConstructibleClass
  22. {
  23. public:
  24. NonTriviallyConstructibleClass() {}
  25. };
  26. class ConstructibleClass
  27. {
  28. public:
  29. enum Tag
  30. {
  31. TheTag
  32. };
  33. ConstructibleClass(Tag) {}
  34. };
  35. class ConstructibleWithInitializerListClass
  36. {
  37. public:
  38. ConstructibleWithInitializerListClass(std::initializer_list<const char*> il, int theInt)
  39. : m_char(*il.begin())
  40. , m_int(theInt)
  41. {
  42. }
  43. const char* m_char;
  44. int m_int;
  45. };
  46. } // end namespace OptionalTestClasses
  47. namespace UnitTest
  48. {
  49. using namespace OptionalTestClasses;
  50. class OptionalFixture
  51. : public LeakDetectionFixture
  52. {
  53. };
  54. static_assert(!(optional<int>()), "optional constructed with no args should be false");
  55. static_assert(!(optional<int>(nullopt)), "optional constructed with nullopt should be false");
  56. TEST_F(OptionalFixture, ConstructorNonTrivial)
  57. {
  58. optional<NonTriviallyConstructibleClass> opt;
  59. EXPECT_FALSE(bool(opt)) << "optional constructed with no args should be false";
  60. }
  61. TEST_F(OptionalFixture, ConstructorInPlace)
  62. {
  63. const optional<int> opt(in_place, 5);
  64. EXPECT_TRUE(bool(opt)) << "optional constructed with args should be true";
  65. EXPECT_EQ(*opt, 5);
  66. }
  67. TEST_F(OptionalFixture, ConstructorInPlaceNonTriviallyDestructable)
  68. {
  69. const optional<NonTriviallyDestructableClass> opt(in_place);
  70. EXPECT_TRUE(bool(opt)) << "optional constructed with args should be true";
  71. }
  72. TEST_F(OptionalFixture, ConstructorInPlaceWithInitializerList)
  73. {
  74. const optional<ConstructibleWithInitializerListClass> opt(in_place, {"O3DE"}, 4);
  75. EXPECT_TRUE(bool(opt)) << "optional constructed with args should be true";
  76. }
  77. TEST_F(OptionalFixture, ConstructorCopyTrivial)
  78. {
  79. const optional<int> opt(in_place, 5);
  80. const optional<int> optCopy(opt);
  81. EXPECT_EQ(bool(opt), bool(optCopy)) << "Copying an optional should result in the same bool() value";
  82. }
  83. TEST_F(OptionalFixture, ConstructorMoveTrivial)
  84. {
  85. const optional<int> opt(in_place, 5);
  86. const optional<int> optMoved(AZStd::move(opt));
  87. EXPECT_EQ(bool(opt), bool(optMoved)) << "Moving an optional should result in the same bool() value";
  88. }
  89. TEST_F(OptionalFixture, ConstructorMoveNonTrivial)
  90. {
  91. AZStd::string s1 {"Hello"};
  92. AZStd::string s2(AZStd::move(s1));
  93. EXPECT_NE(s1, s2);
  94. optional<AZStd::string> opt {"Hello"};
  95. const optional<AZStd::string> optMoved(AZStd::move(opt));
  96. EXPECT_EQ(bool(opt), bool(optMoved)) << "Moving an optional should result in the same bool() value";
  97. EXPECT_NE(opt.value(), optMoved.value());
  98. }
  99. TEST_F(OptionalFixture, CanAssignFromEmptyOptional)
  100. {
  101. optional<int> opt1;
  102. opt1 = {};
  103. EXPECT_FALSE(bool(opt1)) << "Optional should still be empty";
  104. }
  105. TEST_F(OptionalFixture, AZStdHashActuallyCompiles)
  106. {
  107. constexpr optional<int> opt1{ 5 };
  108. constexpr size_t hashValue = AZStd::hash<optional<int>>{}(opt1);
  109. static_assert(hashValue != 0, "Hash of engaged optional of int within non-zero value should not be 0");
  110. EXPECT_NE(0, hashValue);
  111. }
  112. } // end namespace UnitTest