std::int64_t collection::count(view_or_value filter, const options::count& options) {
    scoped_bson_t bson_filter{filter};
    bson_error_t error;

    const mongoc_read_prefs_t* rp_ptr = NULL;

    if (options.read_preference()) {
        rp_ptr = options.read_preference()->_impl->read_preference_t;
    }

    // Some options must be added via the options struct
    bsoncxx::builder::stream::document cmd_opts_builder{};

    if (options.max_time()) {
        cmd_opts_builder << "maxTimeMS" << bsoncxx::types::b_int64{options.max_time()->count()};
    }

    if (options.hint()) {
        cmd_opts_builder << concatenate(options.hint()->to_document());
    }

    scoped_bson_t cmd_opts_bson{cmd_opts_builder.view()};

    auto result = libmongoc::collection_count_with_opts(
        _get_impl().collection_t, static_cast<mongoc_query_flags_t>(0), bson_filter.bson(),
        options.skip().value_or(0), options.limit().value_or(0), cmd_opts_bson.bson(), rp_ptr,
        &error);

    if (result < 0) {
        throw_exception<query_exception>(error);
    }

    return result;
}
std::int64_t collection::count(bsoncxx::document::view filter, const options::count& options) {
    scoped_bson_t bson_filter{filter};
    bson_error_t error;

    const mongoc_read_prefs_t* rp_ptr = NULL;

    if (options.read_preference()) {
        rp_ptr = options.read_preference()->_impl->read_preference_t;
    }

    auto result = libmongoc::collection_count(
        _impl->collection_t, static_cast<mongoc_query_flags_t>(0), bson_filter.bson(),
        options.skip().value_or(0), options.limit().value_or(0), rp_ptr, &error);

    if (result < 0) {
        throw exception::operation();
    }

    return result;
}
std::int64_t collection::count(bsoncxx::document::view filter, const options::count& options) {
    scoped_bson_t bson_filter{filter};
    bson_error_t error;

    const mongoc_read_prefs_t* rp_ptr = NULL;

    if (options.read_preference()) {
        rp_ptr = options.read_preference()->_impl->read_preference_t;
    }

    // Some options must be added via the options struct
    bsoncxx::builder::stream::document cmd_opts_builder{};

    if (options.hint()) {
        cmd_opts_builder << bsoncxx::builder::stream::concatenate{options.hint()->to_document()};
    }

    scoped_bson_t cmd_opts_bson{cmd_opts_builder.view()};

    auto result = libmongoc::collection_count_with_opts(
        _impl->collection_t, static_cast<mongoc_query_flags_t>(0), bson_filter.bson(),
        options.skip().value_or(0), options.limit().value_or(0), cmd_opts_bson.bson(), rp_ptr,
        &error);

    if (result < 0) {
        throw exception::query(std::make_tuple(error.message, error.code));
    }

    return result;
}