/** @file GCObjectConverter.cpp * * @author Roland Conybeare, Nov 2025 **/ #include "GCObjectConverter.hpp" #include "DInteger.hpp" #include "number/IGCObject_DInteger.hpp" #include "DFloat.hpp" #include "number/IGCObject_DFloat.hpp" #include "DBoolean.hpp" #include "boolean/IGCObject_DBoolean.hpp" #include "DString.hpp" #include "string/IGCObject_DString.hpp" #include #include //#include "xo/alloc/Blob.hpp" namespace xo { using xo::mm::AGCObject; using xo::reflect::Reflect; using xo::reflect::TaggedPtr; using xo::reflect::TypeId; using xo::facet::obj; using xo::facet::typeseq; using xo::mm::AAllocator; namespace scm { namespace { // DInteger <-> T template obj int_to_gco(obj mm, TaggedPtr src) { T * native = src.recover_native(); assert(native); return DInteger::box(mm, *native); } template TaggedPtr gco_to_int(obj mm, obj obj) { /* mm cannot be GC allocator! * That's Object-only */ auto int_obj = xo::facet::obj::from(obj); //Integer::from(obj); if (!int_obj) { throw std::runtime_error (tostr("Object obj found where Integer expected", xtag("obj", obj))); } void * mem = mm.alloc(typeseq::id(), sizeof(T)); T * p = reinterpret_cast(mem); *p = int_obj.data()->value(); /* Note: * retval invalidated when * *mm cleared/recycled/collected */ return Reflect::make_tp(p); } // DFloat <-> T template xo::facet::obj float_to_gco(xo::facet::obj mm, TaggedPtr src) { T * native = src.recover_native(); assert(native); return DFloat::box(mm, *native); } template TaggedPtr gco_to_float(obj mm, obj obj) { auto float_obj = xo::facet::obj::from(obj); if (!float_obj) { throw std::runtime_error (tostr("Object obj found where Float expected", xtag("obj", obj))); } void * mem = mm.alloc(typeseq::id(), sizeof(T)); T * p = reinterpret_cast(mem); *p = float_obj.data()->value(); /* Note: * retval invalidated when *mm cleared/recycled/collected */ return Reflect::make_tp(p); } // DBoolean <-> T obj bool_to_gco(obj mm, TaggedPtr src) { bool * native = src.recover_native(); assert(native); return DBoolean::box(mm, *native); } TaggedPtr gco_to_bool(obj /*mm*/, obj obj) { static bool s_true = true; static bool s_false = false; auto bool_obj = xo::facet::obj::from(obj); if (!bool_obj) { throw std::runtime_error (tostr("Object obj found where Boolean expected", xtag("obj", obj))); } return Reflect::make_tp(bool_obj.data()->value() ? &s_true : &s_false); } // DString <-> T // w/ // T = std::string obj string_to_gco(obj mm, TaggedPtr src) { // try std::string.. std::string * native = src.recover_native(); assert(native); DString * dstr = DString::from_str(mm, *native); return xo::facet::obj(dstr); } TaggedPtr gco_to_string(obj mm, obj obj) { auto string_obj = xo::facet::obj::from(obj); if (!string_obj) { throw std::runtime_error (tostr("Object obj founcd where String expected", xtag("obj", obj))); } // still don't have impl for this // Need regular std::allocator interface // (void)mm; assert(false); } } ObjectConverter::ObjectConverter() { this->establish_conversion(&int_to_gco, &gco_to_int); this->establish_conversion(&int_to_gco, &gco_to_int); this->establish_conversion(&float_to_gco, &gco_to_float); this->establish_conversion(&bool_to_gco, &gco_to_bool); this->establish_conversion(&string_to_gco, &gco_to_string); } const ObjectConverter & ObjectConverter::instance() { static ObjectConverter s_instance; return s_instance; } obj ObjectConverter::tp_to_gco(obj mm, TaggedPtr x_tp, bool throw_flag) const { using xo::reflect::Reflect; using xo::reflect::TaggedPtr; const Converter * cvt = cvt_.lookup(x_tp.td()); if (cvt) { return (cvt->cvt_to_object_)(mm, x_tp); } else { if (throw_flag) { throw std::runtime_error (tostr("no to-object-converter available for instance of type", xtag("id", x_tp.td()->id()), xtag("name", x_tp.td()->short_name()))); } return obj(); } } TaggedPtr ObjectConverter::tp_from_gco(obj mm, obj obj, TypeId target_id, bool throw_flag) const { const Converter * cvt = cvt_.lookup(target_id); if (cvt) { return (cvt->cvt_from_object_)(mm, obj); } else { if (throw_flag) { throw std::runtime_error (tostr("no from-object-converter available for instance of type", xtag("id", target_id))); } return TaggedPtr::universal_null(); } } } } /* end GCObjectConverter.cpp */