#pragma once
#include <executorch/runtime/backend/options.h>
#include <executorch/runtime/core/error.h>
#include <executorch/runtime/core/span.h>
#include <executorch/runtime/platform/assert.h>
#include <cstring>
namespace executorch {
namespace runtime {
class LoadBackendOptionsMap final {
public:
LoadBackendOptionsMap() : size_(0) {
for (size_t i = 0; i < kMaxBackends; ++i) {
entries_[i].backend_id[0] = '\0';
}
}
Error set_options(const char* backend_id, Span<BackendOption> options) {
if (backend_id == nullptr || backend_id[0] == '\0') {
return Error::InvalidArgument;
}
return set_options_impl(backend_id, options);
}
template <typename Builder>
Error set_options(Builder& builder) {
return set_options_impl(builder.backend_id(), builder.view());
}
private:
Error set_options_impl(const char* backend_id, Span<BackendOption> options) {
for (size_t i = 0; i < size_; ++i) {
if (std::strcmp(entries_[i].backend_id, backend_id) == 0) {
entries_[i].options = options;
return Error::Ok;
}
}
if (size_ >= kMaxBackends) {
return Error::InvalidArgument;
}
const size_t id_len = std::strlen(backend_id);
if (id_len >= kMaxBackendIdLength) {
return Error::InvalidArgument;
}
std::memcpy(entries_[size_].backend_id, backend_id, id_len);
entries_[size_].backend_id[id_len] = '\0';
entries_[size_].options = options;
++size_;
return Error::Ok;
}
public:
Span<const BackendOption> get_options(const char* backend_id) const {
if (backend_id == nullptr) {
return Span<const BackendOption>(nullptr, static_cast<size_t>(0));
}
for (size_t i = 0; i < size_; ++i) {
if (std::strcmp(entries_[i].backend_id, backend_id) == 0) {
return Span<const BackendOption>(
entries_[i].options.data(), entries_[i].options.size());
}
}
return Span<const BackendOption>(nullptr, static_cast<size_t>(0));
}
bool has_options(const char* backend_id) const {
if (backend_id == nullptr) {
return false;
}
for (size_t i = 0; i < size_; ++i) {
if (std::strcmp(entries_[i].backend_id, backend_id) == 0) {
return true;
}
}
return false;
}
size_t size() const {
return size_;
}
struct EntryView {
const char* backend_id = nullptr;
Span<const BackendOption> options;
};
EntryView entry_at(size_t index) const {
ET_DCHECK_MSG(
index < size_,
"entry_at index %zu out of bounds (size=%zu)",
index,
size_);
return EntryView{
entries_[index].backend_id,
Span<const BackendOption>(
entries_[index].options.data(), entries_[index].options.size())};
}
private:
static constexpr size_t kMaxBackends = 8;
static constexpr size_t kMaxBackendIdLength = 64;
struct Entry {
char backend_id[kMaxBackendIdLength];
Span<BackendOption> options;
};
Entry entries_[kMaxBackends];
size_t size_;
};
} }