diff options
author | Arne Juul <arnej@verizonmedia.com> | 2020-11-04 07:16:45 +0000 |
---|---|---|
committer | Arne Juul <arnej@verizonmedia.com> | 2020-11-04 07:31:04 +0000 |
commit | 9856a29b4685a0119c5f73ba93e5fd6bb16d13ea (patch) | |
tree | 3e08f16e1abd14b4cccb1c1f595cca6c5ac86d71 /eval | |
parent | 0f98e3423f392dfd154d37a15d49e176725e40cf (diff) |
move detect_type to its own header file
Diffstat (limited to 'eval')
-rw-r--r-- | eval/src/vespa/eval/instruction/detect_type.h | 75 | ||||
-rw-r--r-- | eval/src/vespa/eval/instruction/generic_join.cpp | 44 | ||||
-rw-r--r-- | eval/src/vespa/eval/instruction/generic_merge.cpp | 41 |
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 ¶m = 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 ¶m = unwrap_param<MergeParam>(param_in); |