Move accessors into XS
[gitmo/Mouse.git] / xs-src / mouse_instance.xs
diff --git a/xs-src/mouse_instance.xs b/xs-src/mouse_instance.xs
new file mode 100644 (file)
index 0000000..dd74c1c
--- /dev/null
@@ -0,0 +1,76 @@
+#include "mouse.h"\r
+\r
+#define CHECK_INSTANCE(instance) STMT_START{                          \
+        if(!(SvROK(instance) && SvTYPE(SvRV(instance)) == SVt_PVHV)){ \
+            croak("Invalid object for instance managers");            \
+        }                                                             \
+    } STMT_END
+
+SV*
+mouse_instance_create(pTHX_ HV* const stash) {
+    assert(stash);
+    return sv_bless( newRV_noinc((SV*)newHV()), stash );
+}
+
+SV*
+mouse_instance_clone(pTHX_ SV* const instance) {
+    HV* proto;
+    assert(instance);
+
+    CHECK_INSTANCE(instance);
+    proto = newHVhv((HV*)SvRV(instance));
+    return sv_bless( newRV_noinc((SV*)proto), SvSTASH(SvRV(instance)) );
+}
+
+bool
+mouse_instance_has_slot(pTHX_ SV* const instance, SV* const slot) {
+    assert(instance);
+    assert(slot);
+    CHECK_INSTANCE(instance);
+    return hv_exists_ent((HV*)SvRV(instance), slot, 0U);
+}
+
+SV*
+mouse_instance_get_slot(pTHX_ SV* const instance, SV* const slot) {
+    HE* he;
+    assert(instance);
+    assert(slot);
+    CHECK_INSTANCE(instance);
+    he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
+    return he ? HeVAL(he) : NULL;
+}
+
+SV*
+mouse_instance_set_slot(pTHX_ SV* const instance, SV* const slot, SV* const value) {
+    HE* he;
+    SV* sv;
+    assert(instance);
+    assert(slot);
+    assert(value);
+    CHECK_INSTANCE(instance);
+    he = hv_fetch_ent((HV*)SvRV(instance), slot, TRUE, 0U);
+    sv = HeVAL(he);
+    sv_setsv_mg(sv, value);
+    return sv;
+}
+
+SV*
+mouse_instance_delete_slot(pTHX_ SV* const instance, SV* const slot) {
+    assert(instance);
+    assert(slot);
+    CHECK_INSTANCE(instance);
+    return hv_delete_ent((HV*)SvRV(instance), slot, 0, 0U);
+}
+
+void
+mouse_instance_weaken_slot(pTHX_ SV* const instance, SV* const slot) {
+    HE* he;
+    assert(instance);
+    assert(slot);
+    CHECK_INSTANCE(instance);
+    he = hv_fetch_ent((HV*)SvRV(instance), slot, FALSE, 0U);
+    if(he){
+        sv_rvweaken(HeVAL(he));
+    }
+}
+\r