1 // 2 // Copyright © 2017 Arm Ltd. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 #include <doctest/doctest.h> 6 7 #include <armnn/Optional.hpp> 8 #include <string> 9 10 #include <armnn/utility/IgnoreUnused.hpp> 11 12 namespace 13 { 14 PassStringRef(armnn::Optional<std::string &> value)15void PassStringRef(armnn::Optional<std::string&> value) 16 { 17 armnn::IgnoreUnused(value); 18 } 19 PassStringRefWithDefault(armnn::Optional<std::string &> value=armnn::EmptyOptional ())20void PassStringRefWithDefault(armnn::Optional<std::string&> value = armnn::EmptyOptional()) 21 { 22 armnn::IgnoreUnused(value); 23 } 24 25 } // namespace <anonymous> 26 27 TEST_SUITE("OptionalTests") 28 { 29 TEST_CASE("SimpleStringTests") 30 { 31 armnn::Optional<std::string> optionalString; 32 CHECK(static_cast<bool>(optionalString) == false); 33 CHECK(optionalString.has_value() == false); 34 CHECK((optionalString == armnn::Optional<std::string>())); 35 36 optionalString = std::string("Hello World"); 37 CHECK(static_cast<bool>(optionalString) == true); 38 CHECK(optionalString.has_value() == true); 39 CHECK(optionalString.value() == "Hello World"); 40 CHECK((optionalString == armnn::Optional<std::string>("Hello World"))); 41 42 armnn::Optional<std::string> otherString; 43 otherString = optionalString; 44 CHECK(static_cast<bool>(otherString) == true); 45 CHECK(otherString.value() == "Hello World"); 46 47 optionalString.reset(); 48 CHECK(static_cast<bool>(optionalString) == false); 49 CHECK(optionalString.has_value() == false); 50 51 const std::string stringValue("Hello World"); 52 armnn::Optional<std::string> optionalString2(stringValue); 53 CHECK(static_cast<bool>(optionalString2) == true); 54 CHECK(optionalString2.has_value() == true); 55 CHECK(optionalString2.value() == "Hello World"); 56 57 armnn::Optional<std::string> optionalString3(std::move(optionalString2)); 58 CHECK(static_cast<bool>(optionalString3) == true); 59 CHECK(optionalString3.has_value() == true); 60 CHECK(optionalString3.value() == "Hello World"); 61 } 62 63 TEST_CASE("StringRefTests") 64 { 65 armnn::Optional<std::string&> optionalStringRef{armnn::EmptyOptional()}; 66 CHECK(optionalStringRef.has_value() == false); 67 68 PassStringRef(optionalStringRef); 69 PassStringRefWithDefault(); 70 71 armnn::Optional<std::string&> optionalStringRef2 = optionalStringRef; 72 73 std::string helloWorld("Hello World"); 74 75 std::string& helloWorldRef = helloWorld; 76 armnn::Optional<std::string&> optionalHelloRef = helloWorldRef; 77 CHECK(optionalHelloRef.has_value() == true); 78 CHECK(optionalHelloRef.value() == "Hello World"); 79 80 armnn::Optional<std::string&> optionalHelloRef2 = helloWorld; 81 CHECK(optionalHelloRef2.has_value() == true); 82 CHECK(optionalHelloRef2.value() == "Hello World"); 83 84 armnn::Optional<std::string&> optionalHelloRef3{helloWorldRef}; 85 CHECK(optionalHelloRef3.has_value() == true); 86 CHECK(optionalHelloRef3.value() == "Hello World"); 87 88 armnn::Optional<std::string&> optionalHelloRef4{helloWorld}; 89 CHECK(optionalHelloRef4.has_value() == true); 90 CHECK(optionalHelloRef4.value() == "Hello World"); 91 92 // modify through the optional reference 93 optionalHelloRef4.value().assign("Long Other String"); 94 CHECK(helloWorld == "Long Other String"); 95 CHECK(optionalHelloRef.value() == "Long Other String"); 96 CHECK(optionalHelloRef2.value() == "Long Other String"); 97 CHECK(optionalHelloRef3.value() == "Long Other String"); 98 } 99 100 TEST_CASE("SimpleIntTests") 101 { 102 const int intValue = 123; 103 104 armnn::Optional<int> optionalInt; 105 CHECK(static_cast<bool>(optionalInt) == false); 106 CHECK(optionalInt.has_value() == false); 107 CHECK((optionalInt == armnn::Optional<int>())); 108 109 optionalInt = intValue; 110 CHECK(static_cast<bool>(optionalInt) == true); 111 CHECK(optionalInt.has_value() == true); 112 CHECK(optionalInt.value() == intValue); 113 CHECK((optionalInt == armnn::Optional<int>(intValue))); 114 115 armnn::Optional<int> otherOptionalInt; 116 otherOptionalInt = optionalInt; 117 CHECK(static_cast<bool>(otherOptionalInt) == true); 118 CHECK(otherOptionalInt.value() == intValue); 119 } 120 121 TEST_CASE("ObjectConstructedInPlaceTests") 122 { 123 struct SimpleObject 124 { 125 public: SimpleObjectSimpleObject126 SimpleObject(const std::string& name, int value) 127 : m_Name(name) 128 , m_Value(value) 129 {} 130 operator ==SimpleObject131 bool operator ==(const SimpleObject& other) 132 { 133 return m_Name == other.m_Name && 134 m_Value == other.m_Value; 135 } 136 137 private: 138 std::string m_Name; 139 int m_Value; 140 }; 141 142 std::string objectName("SimpleObject"); 143 int objectValue = 1; 144 SimpleObject referenceObject(objectName, objectValue); 145 146 // Use MakeOptional 147 armnn::Optional<SimpleObject> optionalObject1 = armnn::MakeOptional<SimpleObject>(objectName, objectValue); 148 CHECK(static_cast<bool>(optionalObject1) == true); 149 CHECK(optionalObject1.has_value() == true); 150 CHECK((optionalObject1.value() == referenceObject)); 151 152 // Call in-place constructor directly 153 armnn::Optional<SimpleObject> optionalObject2(CONSTRUCT_IN_PLACE, objectName, objectValue); 154 CHECK(static_cast<bool>(optionalObject1) == true); 155 CHECK(optionalObject1.has_value() == true); 156 CHECK((optionalObject1.value() == referenceObject)); 157 } 158 159 } 160