IVGCVSW-5091 Add Logical ops frontend and ref impl

* Add frontend and reference implementation for logical
  ops NOT, AND, OR.
* Unary NOT uses existing ElementwiseUnary layer and
  ElementwiseUnary descriptor.
* Binary AND/OR uses new layer LogicalBinary and new
  LogicalBinary descriptor.
* Add serialization/deserializion support and add missing
  ElementwiseUnary deserializer code.
* Add additional Boolean decoder in BaseIterator.hpp.

Signed-off-by: James Conroy <james.conroy@arm.com>
Change-Id: Id343b01174053a166de1b98b6175e04a5065f720
diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp
index 52c079f..f48c120 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -1105,6 +1105,53 @@
     return supported;
 }
 
+bool RefLayerSupport::IsLogicalBinarySupported(const TensorInfo& input0,
+                                               const TensorInfo& input1,
+                                               const TensorInfo& output,
+                                               const LogicalBinaryDescriptor& descriptor,
+                                               Optional<std::string&> reasonIfUnsupported) const
+{
+    IgnoreUnused(descriptor);
+
+    std::array<DataType, 1> supportedTypes =
+    {
+        DataType::Boolean
+    };
+
+    bool supported = true;
+    supported &= CheckSupportRule(TypeAnyOf(input0, supportedTypes), reasonIfUnsupported,
+                                  "Reference LogicalBinary: input 0 type not supported");
+    supported &= CheckSupportRule(TypeAnyOf(input1, supportedTypes), reasonIfUnsupported,
+                                  "Reference LogicalBinary: input 1 type not supported");
+
+    supported &= CheckSupportRule(TypesAreEqual(input0, output), reasonIfUnsupported,
+                                  "Reference LogicalBinary: input and output types do not match");
+
+    return supported;
+}
+
+bool RefLayerSupport::IsLogicalUnarySupported(const TensorInfo& input,
+                                              const TensorInfo& output,
+                                              const ElementwiseUnaryDescriptor& descriptor,
+                                              Optional<std::string&> reasonIfUnsupported) const
+{
+    IgnoreUnused(descriptor);
+
+    std::array<DataType, 1> supportedTypes =
+    {
+        DataType::Boolean
+    };
+
+    bool supported = true;
+    supported &= CheckSupportRule(TypeAnyOf(input, supportedTypes), reasonIfUnsupported,
+                                  "Reference LogicalUnary: input type not supported");
+
+    supported &= CheckSupportRule(TypesAreEqual(input, output), reasonIfUnsupported,
+                                  "Reference LogicalUnary: input and output types do not match");
+
+    return supported;
+}
+
 bool RefLayerSupport::IsLogSoftmaxSupported(const TensorInfo& input,
                                             const TensorInfo& output,
                                             const LogSoftmaxDescriptor& descriptor,