diff --git a/c/lib.cpp b/c/lib.cpp index 14332d85..a35acaa6 100644 --- a/c/lib.cpp +++ b/c/lib.cpp @@ -119,7 +119,7 @@ USEARCH_EXPORT usearch_index_t usearch_init(usearch_init_options_t* options, use reinterpret_cast(options->metric), // metric_punned_signature_t::array_array_k, // metric_kind, scalar_kind); - if (!metric) { + if (metric.missing()) { *error = "Unknown metric kind!"; return NULL; } diff --git a/include/usearch/index_plugins.hpp b/include/usearch/index_plugins.hpp index 8b1f6f87..25ab8ce4 100644 --- a/include/usearch/index_plugins.hpp +++ b/include/usearch/index_plugins.hpp @@ -1401,7 +1401,16 @@ class metric_punned_t { inline std::size_t dimensions() const noexcept { return dimensions_; } inline metric_kind_t metric_kind() const noexcept { return metric_kind_; } inline scalar_kind_t scalar_kind() const noexcept { return scalar_kind_; } - explicit inline operator bool() const noexcept { return metric_routed_ && metric_ptr_; } + inline explicit operator bool() const noexcept { return metric_routed_ && metric_ptr_; } + + /** + * @brief Checks fi we've failed to initialized the metric with provided arguments. + * + * It's different from `operator bool()` when it comes to explicitly uninitialized metrics. + * It's a common case, where a NULL state is created only to be overwritten later, when + * we recover an old index state from a file or a network. + */ + inline bool missing() const noexcept { return !bool(*this) && metric_kind_ != metric_kind_t::unknown_k; } inline char const* isa_name() const noexcept { if (!*this) diff --git a/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp b/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp index e5106882..e760b81a 100644 --- a/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +++ b/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp @@ -31,7 +31,7 @@ JNIEXPORT jlong JNICALL Java_cloud_unum_usearch_Index_c_1create( // index_dense_config_t config(static_cast(connectivity), static_cast(expansion_add), static_cast(expansion_search)); metric_punned_t metric(static_cast(dimensions), metric_kind, quantization); - if (!metric) { + if (metric.missing()) { jclass jc = (*env).FindClass("java/lang/Error"); if (jc) (*env).ThrowNew(jc, "Failed to initialize the metric!"); diff --git a/javascript/lib.cpp b/javascript/lib.cpp index e19a769c..0f87a914 100644 --- a/javascript/lib.cpp +++ b/javascript/lib.cpp @@ -86,7 +86,7 @@ CompiledIndex::CompiledIndex(Napi::CallbackInfo const& ctx) : Napi::ObjectWrap().Value(); metric_punned_t metric(dimensions, metric_kind, quantization); - if (!metric) { + if (metric.missing()) { Napi::TypeError::New(ctx.Env(), "Failed to initialize the metric!").ThrowAsJavaScriptException(); return; } diff --git a/objc/USearchObjective.mm b/objc/USearchObjective.mm index 9f7c3ce7..d336fc98 100644 --- a/objc/USearchObjective.mm +++ b/objc/USearchObjective.mm @@ -121,7 +121,7 @@ + (instancetype)make:(USearchMetric)metricKind dimensions:(UInt32)dimensions con index_config_t config(static_cast(connectivity)); metric_punned_t metric(dims, to_native_metric(metricKind), to_native_scalar(quantization)); - if (!metric) { + if (metric.missing()) { @throw [NSException exceptionWithName:@"Can't create an index" reason:@"The metric is not supported" userInfo:nil]; diff --git a/python/lib.cpp b/python/lib.cpp index f730083a..17413cff 100644 --- a/python/lib.cpp +++ b/python/lib.cpp @@ -122,7 +122,7 @@ static dense_index_py_t make_index( // metric_uintptr // ? metric_t(dimensions, metric_uintptr, metric_signature, metric_kind, scalar_kind) : metric_t(dimensions, metric_kind, scalar_kind); - if (!metric) + if (metric.missing()) throw std::invalid_argument("Unsupported metric!"); return index_dense_t::make(metric, config); diff --git a/rust/lib.cpp b/rust/lib.cpp index 14f6ccc4..f43477f7 100644 --- a/rust/lib.cpp +++ b/rust/lib.cpp @@ -131,7 +131,7 @@ std::unique_ptr new_native_index(IndexOptions const& options) { metric_kind_t metric_kind = rust_to_cpp_metric(options.metric); scalar_kind_t scalar_kind = rust_to_cpp_scalar(options.quantization); metric_punned_t metric(options.dimensions, metric_kind, scalar_kind); - if (!metric) + if (metric.missing()) throw std::invalid_argument("Unsupported metric or scalar type"); index_dense_config_t config(options.connectivity, options.expansion_add, options.expansion_search); config.multi = options.multi;