Port ElementwiseBinary to CKW part 2

* Add fp16 support
* Implement broadcasting to elementwise binary
* Implement kernel name and kernel config id
* Always use explicit cast in ckw unary, binary and ternary elementwise
  functions. This is to address the accidental use of double literals,
  with other benefits.
* Refactor TypeConverter for smaller includes

Resolves COMPMID-6260

Change-Id: I26b726746f8c0dd7b5942ad379d56f4d7642d15f
Signed-off-by: SiCong Li <sicong.li@arm.com>
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/9999
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Jakub Sujak <jakub.sujak@arm.com>
Reviewed-by: Viet-Hoa Do <viet-hoa.do@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Benchmark: Arm Jenkins <bsgcomp@arm.com>
diff --git a/src/core/utils/StringUtils.cpp b/src/core/utils/StringUtils.cpp
index 938ee09..6d05c9b 100644
--- a/src/core/utils/StringUtils.cpp
+++ b/src/core/utils/StringUtils.cpp
@@ -23,13 +23,14 @@
  */
 #include "arm_compute/core/utils/StringUtils.h"
 
-#include <limits>
-#include <sstream>
 #include <algorithm>
 #include <cmath>
 #include <cstdint>
 #include <fstream>
+#include <limits>
 #include <map>
+#include <numeric>
+#include <sstream>
 #include <string>
 
 namespace arm_compute
@@ -61,4 +62,20 @@
 
     return ss.str();
 }
+
+std::string join(const std::vector<std::string> strings, const std::string &sep)
+{
+    if(strings.empty())
+    {
+        return "";
+    }
+    return std::accumulate(
+               std::next(strings.begin()),
+               strings.end(),
+               strings.at(0),
+               [&sep](const std::string & a, const std::string & b)
+    {
+        return a + sep + b;
+    });
+}
 }