summaryrefslogtreecommitdiffstats
path: root/eval
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-11-04 07:16:45 +0000
committerArne Juul <arnej@verizonmedia.com>2020-11-04 07:31:04 +0000
commit9856a29b4685a0119c5f73ba93e5fd6bb16d13ea (patch)
tree3e08f16e1abd14b4cccb1c1f595cca6c5ac86d71 /eval
parent0f98e3423f392dfd154d37a15d49e176725e40cf (diff)
move detect_type to its own header file
Diffstat (limited to 'eval')
-rw-r--r--eval/src/vespa/eval/instruction/detect_type.h75
-rw-r--r--eval/src/vespa/eval/instruction/generic_join.cpp44
-rw-r--r--eval/src/vespa/eval/instruction/generic_merge.cpp41
3 files changed, 77 insertions, 83 deletions
diff --git a/eval/src/vespa/eval/instruction/detect_type.h b/eval/src/vespa/eval/instruction/detect_type.h
new file mode 100644
index 00000000000..22c280f17ca
--- /dev/null
+++ b/eval/src/vespa/eval/instruction/detect_type.h
@@ -0,0 +1,75 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <typeindex>
+#include <array>
+
+#pragma once
+
+namespace vespalib::eval::instruction {
+
+/*
+ * Utilities for detecting implementation class by comparing
+ * typeindex(typeid(T)); for now these are local to this
+ * namespace, but we can consider moving them to a more
+ * common place (probably vespalib) if we see more use-cases.
+ */
+
+/**
+ * Recognize a (const) instance of type T. This is cheaper than
+ * dynamic_cast, but requires the object to be exactly of class T.
+ * Returns a pointer to the object as T if recognized, nullptr
+ * otherwise.
+ **/
+template<typename T, typename U>
+const T *
+recognize_by_type_index(const U & object)
+{
+ if (std::type_index(typeid(object)) == std::type_index(typeid(T))) {
+ return static_cast<const T *>(&object);
+ }
+ return nullptr;
+}
+
+/**
+ * Packs N recognized values into one object, used as return value
+ * from detect_type<T>.
+ *
+ * Use all_converted() or the equivalent bool cast operator to check
+ * if all objects were recognized. After this check is successful use
+ * get<0>(), get<1>() etc to get a reference to the objects.
+ **/
+template<typename T, size_t N>
+class RecognizedValues
+{
+private:
+ std::array<const T *, N> _pointers;
+public:
+ RecognizedValues(std::array<const T *, N> && pointers)
+ : _pointers(std::move(pointers))
+ {}
+ bool all_converted() const {
+ for (auto p : _pointers) {
+ if (p == nullptr) return false;
+ }
+ return true;
+ }
+ operator bool() const { return all_converted(); }
+ template<size_t idx> const T& get() const {
+ static_assert(idx < N);
+ return *_pointers[idx];
+ }
+};
+
+/**
+ * For all arguments, detect if they have typeid(T), convert to T if
+ * possible, and return a RecognizedValues packing the converted
+ * values.
+ **/
+template<typename T, typename... Args>
+RecognizedValues<T, sizeof...(Args)>
+detect_type(const Args &... args)
+{
+ return RecognizedValues<T, sizeof...(Args)>({(recognize_by_type_index<T>(args))...});
+}
+
+} // namespace
diff --git a/eval/src/vespa/eval/instruction/generic_join.cpp b/eval/src/vespa/eval/instruction/generic_join.cpp
index eabe1c362e2..25829576ba5 100644
--- a/eval/src/vespa/eval/instruction/generic_join.cpp
+++ b/eval/src/vespa/eval/instruction/generic_join.cpp
@@ -1,6 +1,7 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "generic_join.h"
+#include "detect_type.h"
#include <vespa/eval/eval/inline_operation.h>
#include <vespa/eval/eval/fast_value.hpp>
#include <vespa/eval/eval/wrap_param.h>
@@ -9,7 +10,6 @@
#include <vespa/vespalib/util/typify.h>
#include <vespa/vespalib/util/visit_ranges.h>
#include <cassert>
-#include <typeindex>
using namespace vespalib::eval::tensor_function;
@@ -69,48 +69,6 @@ void my_mixed_join_op(State &state, uint64_t param_in) {
//-----------------------------------------------------------------------------
-/** possible generic utility */
-template<typename T, typename U>
-const T *
-recognize_by_type_index(const U & object)
-{
- if (std::type_index(typeid(object)) == std::type_index(typeid(T))) {
- return static_cast<const T *>(&object);
- }
- return nullptr;
-}
-
-template<typename T, size_t N>
-class RecognizedValues
-{
-private:
- std::array<const T *, N> _pointers;
-public:
- RecognizedValues(std::array<const T *, N> && pointers)
- : _pointers(std::move(pointers))
- {}
- bool all_converted() const {
- for (auto p : _pointers) {
- if (p == nullptr) return false;
- }
- return true;
- }
- operator bool() const { return all_converted(); }
- template<size_t idx> const T& get() const {
- static_assert(idx < N);
- return *_pointers[idx];
- }
-};
-
-template<typename T, typename... Args>
-RecognizedValues<T, sizeof...(Args)>
-detect_type(const Args &... args)
-{
- return RecognizedValues<T, sizeof...(Args)>({(recognize_by_type_index<T>(args))...});
-}
-
-//-----------------------------------------------------------------------------
-
template <typename LCT, typename RCT, typename OCT, typename Fun>
void my_sparse_no_overlap_join_op(State &state, uint64_t param_in) {
const auto &param = unwrap_param<JoinParam>(param_in);
diff --git a/eval/src/vespa/eval/instruction/generic_merge.cpp b/eval/src/vespa/eval/instruction/generic_merge.cpp
index f340e7ad506..87be47a9c2e 100644
--- a/eval/src/vespa/eval/instruction/generic_merge.cpp
+++ b/eval/src/vespa/eval/instruction/generic_merge.cpp
@@ -1,5 +1,6 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "detect_type.h"
#include "generic_merge.h"
#include <vespa/eval/eval/inline_operation.h>
#include <vespa/eval/eval/fast_value.hpp>
@@ -118,46 +119,6 @@ void my_mixed_merge_op(State &state, uint64_t param_in) {
state.pop_pop_push(result_ref);
};
-/** possible generic utility */
-template<typename T, typename U>
-const T *
-recognize_by_type_index(const U & object)
-{
- if (std::type_index(typeid(object)) == std::type_index(typeid(T))) {
- return static_cast<const T *>(&object);
- }
- return nullptr;
-}
-
-template<typename T, size_t N>
-class RecognizedValues
-{
-private:
- std::array<const T *, N> _pointers;
-public:
- RecognizedValues(std::array<const T *, N> && pointers)
- : _pointers(std::move(pointers))
- {}
- bool all_converted() const {
- for (auto p : _pointers) {
- if (p == nullptr) return false;
- }
- return true;
- }
- operator bool() const { return all_converted(); }
- template<size_t idx> const T& get() const {
- static_assert(idx < N);
- return *_pointers[idx];
- }
-};
-
-template<typename T, typename... Args>
-RecognizedValues<T, sizeof...(Args)>
-detect_type(const Args &... args)
-{
- return RecognizedValues<T, sizeof...(Args)>({(recognize_by_type_index<T>(args))...});
-}
-
template <typename LCT, typename RCT, typename OCT, typename Fun>
void my_sparse_merge_op(State &state, uint64_t param_in) {
const auto &param = unwrap_param<MergeParam>(param_in);