Files
mrubypp/mrubypp_converters.h
2025-10-21 19:29:36 +08:00

103 lines
2.8 KiB
C++

#ifndef MRUBYPP_STD_CONVERTERS_H
#define MRUBYPP_STD_CONVERTERS_H
#include "mrubypp_arena_guard.h"
#include <mruby.h>
#include <mruby/array.h>
#include <mruby/string.h>
#include <string>
#include <vector>
template <typename T> struct mrubypp_converter {
static mrb_value to_mrb(mrb_state *mrb, const T &var) {
static_assert(sizeof(T) == 0, "Specialization required");
return mrb_nil_value();
}
static T from_mrb(mrb_state *mrb, mrb_value value) {
static_assert(sizeof(T) == 0, "Specialization required");
return T();
}
};
template <> struct mrubypp_converter<int> {
static mrb_value to_mrb(mrb_state *mrb, int var) {
return mrb_fixnum_value(var);
}
static int from_mrb(mrb_state *mrb, mrb_value value) {
return mrb_fixnum(value);
}
};
template <> struct mrubypp_converter<unsigned int> {
static mrb_value to_mrb(mrb_state *mrb, unsigned int var) {
return mrb_fixnum_value(var);
}
static int from_mrb(mrb_state *mrb, mrb_value value) {
return mrb_fixnum(value);
}
};
template <> struct mrubypp_converter<float> {
static mrb_value to_mrb(mrb_state *mrb, float var) {
return mrb_float_value(mrb, var);
}
static double from_mrb(mrb_state *mrb, mrb_value value) {
return mrb_float(value);
}
};
template <> struct mrubypp_converter<double> {
static mrb_value to_mrb(mrb_state *mrb, double var) {
return mrb_float_value(mrb, var);
}
static double from_mrb(mrb_state *mrb, mrb_value value) {
return mrb_float(value);
}
};
template <> struct mrubypp_converter<std::string> {
static mrb_value to_mrb(mrb_state *mrb, const std::string &var) {
return mrb_str_new(mrb, var.data(), (mrb_int)var.size());
}
static std::string from_mrb(mrb_state *mrb, mrb_value value) {
if (mrb_string_p(value)) {
return std::string(RSTRING_PTR(value), RSTRING_LEN(value));
}
return {};
}
};
template <> struct mrubypp_converter<const char *> {
static mrb_value to_mrb(mrb_state *mrb, const char *var) {
return mrb_str_new(mrb, var, (mrb_int)strlen(var));
}
};
template <typename T> struct mrubypp_converter<std::vector<T>> {
static mrb_value to_mrb(mrb_state *mrb, const std::vector<T> &var) {
mrb_value ary = mrb_ary_new_capa(mrb, static_cast<mrb_int>(var.size()));
for (const T &el : var) {
mrubypp_arena_guard guard(mrb);
mrb_ary_push(mrb, ary, mrubypp_converter<T>::to_mrb(mrb, el));
}
return ary;
}
static std::vector<T> from_mrb(mrb_state *mrb, mrb_value value) {
mrubypp_arena_guard guard(mrb);
std::vector<T> result;
if (mrb_array_p(value)) {
int len = RARRAY_LEN(value);
for (int i = 0; i < len; ++i) {
result.append(
mrubypp_converter<T>::from_mrb(mrb, mrb_ary_ref(mrb, value, i)));
}
}
return result;
}
};
#endif // MRUBYPP_STD_CONVERTERS_H