IVGCVSW-1975 : total removal of boost::optional from the public interface
Change-Id: Ib38a6216ebcdc350c75c028951b3f18f36a2f6b7
diff --git a/include/armnn/Optional.hpp b/include/armnn/Optional.hpp
index 47afca8..e55702d 100644
--- a/include/armnn/Optional.hpp
+++ b/include/armnn/Optional.hpp
@@ -8,8 +8,6 @@
#include <type_traits>
#include <cstring>
-#include <boost/optional.hpp>
-
// Optional is a drop in replacement for std::optional until we migrate
// to c++-17. Only a subset of the optional features are implemented that
// we intend to use in ArmNN.
@@ -25,9 +23,6 @@
// - value() returns a reference to the held object
//
-// There is a deprecated and limited support for boost::optional in this class,
-// which will be removed in the 19.02 release.
-
namespace armnn
{
@@ -35,7 +30,6 @@
// to have default value for an Optional in a function declaration.
struct EmptyOptional {};
-
// OptionalBase is the common functionality between reference and non-reference
// optional types.
class OptionalBase
@@ -65,6 +59,28 @@
bool m_HasValue;
};
+struct HasGetMemberFunction
+{
+ template <class T>
+ static auto Check(T* p) -> decltype(p->get(), std::true_type());
+
+ template <class T>
+ static auto Check(...) -> std::false_type;
+};
+
+//
+// Predicate checking for boost::optional compatibility
+//
+template <typename T>
+struct CheckBoostOptionalSignature
+{
+ using ResultType = decltype(HasGetMemberFunction::Check<T>(0));
+
+ static constexpr bool Result() {
+ return std::is_same<std::true_type, ResultType>::value;
+ }
+};
+
//
// The default implementation is the non-reference case. This
// has an unsigned char array for storing the optional value which
@@ -91,8 +107,11 @@
*this = other;
}
- // temporary support for limited conversion from boost
- OptionalReferenceSwitch(const boost::optional<T>& other)
+ // enable construction from types that matches the CheckBoostOptionalSignature
+ // predicate
+ template <typename O,
+ typename = std::enable_if_t<CheckBoostOptionalSignature<O>::Result()>>
+ OptionalReferenceSwitch(const O& other)
: Base{}
{
*this = other;
@@ -116,11 +135,20 @@
return *this;
}
- // temporary support for limited conversion from boost
- OptionalReferenceSwitch& operator=(const boost::optional<T>& other)
+ OptionalReferenceSwitch& operator=(EmptyOptional)
{
reset();
- if (other.is_initialized())
+ return *this;
+ }
+
+ // enable copying from types that matches the CheckBoostOptionalSignature
+ // predicate
+ template <typename O,
+ typename = std::enable_if_t<CheckBoostOptionalSignature<O>::Result()>>
+ OptionalReferenceSwitch& operator=(const O& other)
+ {
+ reset();
+ if (other)
{
Construct(other.get());
}
@@ -128,12 +156,6 @@
return *this;
}
- OptionalReferenceSwitch& operator=(EmptyOptional)
- {
- reset();
- return *this;
- }
-
~OptionalReferenceSwitch()
{
reset();
@@ -267,13 +289,15 @@
public:
using BaseSwitch = OptionalReferenceSwitch<std::is_reference<T>::value, T>;
- Optional(const T& value) : BaseSwitch{value} {}
Optional() noexcept : BaseSwitch{} {}
+ Optional(const T& value) : BaseSwitch{value} {}
Optional(EmptyOptional empty) : BaseSwitch{empty} {}
Optional(const Optional& other) : BaseSwitch{other} {}
+ Optional(const BaseSwitch& other) : BaseSwitch{other} {}
- // temporary support for limited conversion from boost
- Optional(const boost::optional<T>& other) : BaseSwitch{other} {}
+ template <typename O,
+ typename = std::enable_if_t<CheckBoostOptionalSignature<O>::Result()>>
+ Optional(const O& other) : BaseSwitch{other} {}
};
}
diff --git a/src/armnn/test/OptionalTest.cpp b/src/armnn/test/OptionalTest.cpp
index 87fd156..a869c7e 100644
--- a/src/armnn/test/OptionalTest.cpp
+++ b/src/armnn/test/OptionalTest.cpp
@@ -111,6 +111,10 @@
BoostCompatibilityTester(armnn::Optional<std::string>(), false, "");
BoostCompatibilityTester(armnn::Optional<std::string>("Hello World"), true, "Hello World");
+ // verify boost signature selector
+ BOOST_TEST(armnn::CheckBoostOptionalSignature<boost::optional<std::string>>::Result() == true);
+ BOOST_TEST(armnn::CheckBoostOptionalSignature<armnn::Optional<std::string>>::Result() == false);
+
// the real thing is to see that we can pass a boost::optional in place
// of an ArmNN Optional
boost::optional<std::string> empty;