Remove a duplicated macro: LooksLikeNumber
[gitmo/Mouse.git] / xs-src / Mouse.xs
index 250604d..efd1e94 100644 (file)
@@ -76,10 +76,10 @@ mouse_class_push_attribute_list(pTHX_ SV* const metaclass, AV* const attrall, HV
     }
 }
 
+XS(XS_Mouse__Object_BUILDARGS); /* prototype */
+
 static int
 mouse_class_has_custom_buildargs(pTHX_ HV* const stash) {
-    XS(XS_Mouse__Object_BUILDARGS); /* prototype */
-
     GV* const buildargs = gv_fetchmeth_autoload(stash, "BUILDARGS", sizeof("BUILDARGS")-1, 0);
 
     return buildargs && CvXSUB(GvCV(buildargs)) != XS_Mouse__Object_BUILDARGS;
@@ -123,7 +123,7 @@ mouse_class_update_xc(pTHX_ SV* const metaclass PERL_UNUSED_DECL, HV* const stas
         flags |= MOUSEf_XC_HAS_BUILDARGS;
     }
 
-    if(predicate_calls(metaclass, "__strict_constructor")){
+    if(predicate_calls(metaclass, "strict_constructor")){
         flags |= MOUSEf_XC_CONSTRUCTOR_IS_STRICT;
     }
 
@@ -297,7 +297,7 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const
     I32 const len   = AvFILLp(attrs) + 1;
     I32 i;
     AV* triggers_queue = NULL;
-    I32 used = 0;
+    U32 used = 0;
 
     assert(meta || object);
     assert(args);
@@ -445,6 +445,11 @@ mouse_get_modifier_storage(pTHX_
     return (AV*)SvRV(storage_ref);
 }
 
+DECL_BOOT(Mouse__Util);
+DECL_BOOT(Mouse__Util__TypeConstraints);
+DECL_BOOT(Mouse__Meta__Method__Accessor__XS);
+DECL_BOOT(Mouse__Meta__Attribute);
+
 MODULE = Mouse  PACKAGE = Mouse
 
 PROTOTYPES: DISABLE
@@ -459,10 +464,10 @@ BOOT:
     mouse_get_attribute      = newSVpvs_share("get_attribute");
     mouse_get_attribute_list = newSVpvs_share("get_attribute_list");
 
-    MOUSE_CALL_BOOT(Mouse__Util);
-    MOUSE_CALL_BOOT(Mouse__Util__TypeConstraints);
-    MOUSE_CALL_BOOT(Mouse__Meta__Method__Accessor__XS);
-    MOUSE_CALL_BOOT(Mouse__Meta__Attribute);
+    CALL_BOOT(Mouse__Util);
+    CALL_BOOT(Mouse__Util__TypeConstraints);
+    CALL_BOOT(Mouse__Meta__Method__Accessor__XS);
+    CALL_BOOT(Mouse__Meta__Attribute);
 
 
 MODULE = Mouse  PACKAGE = Mouse::Meta::Module
@@ -525,8 +530,6 @@ BOOT:
     INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id);
     INSTALL_SIMPLE_READER(Class, is_immutable);
 
-    INSTALL_SIMPLE_READER_WITH_KEY(Class, __strict_constructor,     strict_constructor);
-
     INSTALL_CLASS_HOLDER(Class, method_metaclass,     "Mouse::Meta::Method");
     INSTALL_CLASS_HOLDER(Class, attribute_metaclass,  "Mouse::Meta::Attribute");
     INSTALL_CLASS_HOLDER(Class, constructor_class,    "Mouse::Meta::Method::Constructor::XS");
@@ -613,6 +616,45 @@ CODE:
     mouse_class_initialize_object(aTHX_ meta, object, args, is_cloning);
 }
 
+void
+strict_constructor(SV* self, SV* value = NULL)
+CODE:
+{
+    SV* const slot      = sv_2mortal(newSVpvs_share("strict_constructor"));
+    SV* const stash_ref = mcall0(self, mouse_namespace);
+    HV* stash;
+
+    if(!(SvROK(stash_ref) && SvTYPE(SvRV(stash_ref)) == SVt_PVHV)) {
+        croak("namespace() didn't return a HASH reference");
+    }
+    stash = (HV*)SvRV(stash_ref);
+
+    if(value) { /* setter */
+        set_slot(self, slot, value);
+        mro_method_changed_in(stash);
+    }
+
+    value = get_slot(self, slot);
+
+    if(!value) {
+        AV* const isa   = mro_get_linear_isa(stash);
+        I32 const len   = av_len(isa) + 1;
+        I32 i;
+        for(i = 1; i < len; i++) {
+            SV* const klass = MOUSE_av_at(isa, i);
+            SV* const meta  = get_metaclass(klass);
+            if(!SvOK(meta)){
+                continue; /* skip non-Mouse classes */
+            }
+            value = get_slot(meta, slot);
+            if(value) {
+                break;
+            }
+        }
+    }
+    ST(0) = value ? value : &PL_sv_no;
+}
+
 MODULE = Mouse  PACKAGE = Mouse::Meta::Role
 
 BOOT:
@@ -625,7 +667,7 @@ void
 add_before_modifier(SV* self, SV* name, SV* modifier)
 CODE:
 {
-    av_push(mouse_get_modifier_storage(aTHX_ self, ix, name), newSVsv(modifier));
+    av_push(mouse_get_modifier_storage(aTHX_ self, (enum mouse_modifier_t)ix, name), newSVsv(modifier));
 }
 ALIAS:
     add_before_method_modifier = MOUSE_M_BEFORE
@@ -640,7 +682,7 @@ ALIAS:
     get_after_method_modifiers  = MOUSE_M_AFTER
 PPCODE:
 {
-    AV* const storage = mouse_get_modifier_storage(aTHX_ self, ix, name);
+    AV* const storage = mouse_get_modifier_storage(aTHX_ self, (enum mouse_modifier_t)ix, name);
     I32 const len     = av_len(storage) + 1;
     if(GIMME_V == G_ARRAY) {
         I32 i;