summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-12 15:45:19 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-12 15:45:19 +0100
commit21edee4d584dbf757b006349e903ff7a3b398a1d (patch)
tree2532ec92649726a2ff59ba440c4090e80c679d9d
parent4415b472ae57e367e1fcece4c04355b55a868a1b (diff)
support for static methods
-rw-r--r--include/class.h28
-rw-r--r--include/classbase.h43
-rw-r--r--include/namespace.h18
-rw-r--r--src/classbase.cpp70
-rw-r--r--src/function.h8
-rw-r--r--src/method.h46
-rw-r--r--src/namespace.cpp8
-rw-r--r--src/parameters.cpp5
8 files changed, 169 insertions, 57 deletions
diff --git a/include/class.h b/include/class.h
index 427aa64..d1afab2 100644
--- a/include/class.h
+++ b/include/class.h
@@ -73,7 +73,7 @@ public:
virtual ~Class() {}
/**
- * Add a method to the class
+ * Add a regular method to the class
*
* The method will be accessible as one of the class methods in your PHP
* code. When the method is called, it will automatically be forwarded
@@ -105,6 +105,30 @@ public:
void method(const char *name, Value (T::*method)(Parameters &params) const, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_7>(method), Public, args); }
/**
+ * Add a static method to a class
+ *
+ * In C++ a static method is just a plain function, that only at compile
+ * time has access to the private variables. You can therefore also supply
+ * global functions as static method, and real static methods (that do not
+ * even have to come from the same class.
+ *
+ * In PHP scripts, the function will only be callable as real static method
+ *
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Argument descriptions
+ */
+ void method(const char *name, const native_callback_0 &function, int flags, const Arguments &args = {}) { ClassBase::method(name, function, flags, args); }
+ void method(const char *name, const native_callback_1 &function, int flags, const Arguments &args = {}) { ClassBase::method(name, function, flags, args); }
+ void method(const char *name, const native_callback_2 &function, int flags, const Arguments &args = {}) { ClassBase::method(name, function, flags, args); }
+ void method(const char *name, const native_callback_3 &function, int flags, const Arguments &args = {}) { ClassBase::method(name, function, flags, args); }
+ void method(const char *name, const native_callback_0 &function, const Arguments &args = {}) { ClassBase::method(name, function, Public, args); }
+ void method(const char *name, const native_callback_1 &function, const Arguments &args = {}) { ClassBase::method(name, function, Public, args); }
+ void method(const char *name, const native_callback_2 &function, const Arguments &args = {}) { ClassBase::method(name, function, Public, args); }
+ void method(const char *name, const native_callback_3 &function, const Arguments &args = {}) { ClassBase::method(name, function, Public, args); }
+
+ /**
* Add an abstract method to the class
*
* This is only meaningful for classes that can be extended. Because the
@@ -198,7 +222,7 @@ private:
// compare the two objects
if (*t1 < *t2) return -1;
- if (*t1 > *t2) return 1;
+ if (*t2 < *t1) return 1;
// they must be identical
return 0;
diff --git a/include/classbase.h b/include/classbase.h
index 01f1d55..814feaf 100644
--- a/include/classbase.h
+++ b/include/classbase.h
@@ -28,6 +28,16 @@ union _zend_function;
namespace Php {
/**
+ * A couple of predefined native callback functions that can be registered.
+ * These are functions that optional accept a Request and/or Parameters object,
+ * and that either return void or a Value object.
+ */
+typedef void (*native_callback_0)();
+typedef void (*native_callback_1)(Parameters &);
+typedef Value (*native_callback_2)();
+typedef Value (*native_callback_3)(Parameters &);
+
+/**
* Method signatures
*/
typedef void (Base::*method_callback_0)();
@@ -151,14 +161,31 @@ protected:
* @param flags Optional flags
* @param args Description of the supported arguments
*/
- void method(const char *name, method_callback_0, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_1, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_2, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_3, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_4, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_5, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_6, int flags=0, const Arguments &args = {});
- void method(const char *name, method_callback_7, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_0 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_1 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_2 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_3 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_4 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_5 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_6 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const method_callback_7 &method, int flags=0, const Arguments &args = {});
+
+ /**
+ * Add a static method to the class
+ *
+ * Because a C++ static method is just a regular function, that happens to
+ * have access to the private variables of the class at compile time, you
+ * can register any function that matches one of the function signatures
+ *
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+ void method(const char *name, const native_callback_0 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const native_callback_1 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const native_callback_2 &method, int flags=0, const Arguments &args = {});
+ void method(const char *name, const native_callback_3 &method, int flags=0, const Arguments &args = {});
/**
* Add an abstract method to the class
diff --git a/include/namespace.h b/include/namespace.h
index 4cbf43e..9d6e6f2 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -14,16 +14,6 @@
namespace Php {
/**
- * A couple of predefined native callback functions that can be registered.
- * These are functions that optional accept a Request and/or Parameters object,
- * and that either return void or a Value object.
- */
-typedef void (*native_callback_0)();
-typedef void (*native_callback_1)(Parameters &);
-typedef Value (*native_callback_2)();
-typedef Value (*native_callback_3)(Parameters &);
-
-/**
* Forward declaration
*/
class Function;
@@ -71,10 +61,10 @@ public:
* @param function The function to add
* @param arguments Optional argument specification
*/
- void add(const char *name, native_callback_0 function, const Arguments &arguments = {});
- void add(const char *name, native_callback_1 function, const Arguments &arguments = {});
- void add(const char *name, native_callback_2 function, const Arguments &arguments = {});
- void add(const char *name, native_callback_3 function, const Arguments &arguments = {});
+ void add(const char *name, const native_callback_0 &function, const Arguments &arguments = {});
+ void add(const char *name, const native_callback_1 &function, const Arguments &arguments = {});
+ void add(const char *name, const native_callback_2 &function, const Arguments &arguments = {});
+ void add(const char *name, const native_callback_3 &function, const Arguments &arguments = {});
/**
* Add a native class to the extension by moving it
diff --git a/src/classbase.cpp b/src/classbase.cpp
index f7d8d94..03c5512 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -1133,7 +1133,7 @@ void ClassBase::initialize(const std::string &prefix)
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_0 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_0 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1146,7 +1146,7 @@ void ClassBase::method(const char *name, method_callback_0 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_1 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_1 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1159,7 +1159,7 @@ void ClassBase::method(const char *name, method_callback_1 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_2 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_2 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1172,7 +1172,7 @@ void ClassBase::method(const char *name, method_callback_2 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_3 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_3 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1185,7 +1185,7 @@ void ClassBase::method(const char *name, method_callback_3 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_4 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_4 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1198,7 +1198,7 @@ void ClassBase::method(const char *name, method_callback_4 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_5 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_5 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1211,7 +1211,7 @@ void ClassBase::method(const char *name, method_callback_5 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_6 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_6 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -1224,13 +1224,65 @@ void ClassBase::method(const char *name, method_callback_6 callback, int flags,
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::method(const char *name, method_callback_7 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, const method_callback_7 &callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
}
/**
+ * Add a static method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+void ClassBase::method(const char *name, const native_callback_0 &method, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.push_back(std::make_shared<Method>(name, method, flags | ZEND_ACC_STATIC, args));
+}
+
+/**
+ * Add a static method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+void ClassBase::method(const char *name, const native_callback_1 &method, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.push_back(std::make_shared<Method>(name, method, flags | ZEND_ACC_STATIC, args));
+}
+
+/**
+ * Add a static method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+void ClassBase::method(const char *name, const native_callback_2 &method, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.push_back(std::make_shared<Method>(name, method, flags | ZEND_ACC_STATIC, args));
+}
+
+/**
+ * Add a static method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+void ClassBase::method(const char *name, const native_callback_3 &method, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.push_back(std::make_shared<Method>(name, method, flags | ZEND_ACC_STATIC, args));
+}
+
+/**
* Add an abstract method to the class
* @param name Name of the method
* @param flags Optional flags (like public or protected)
@@ -1242,6 +1294,8 @@ void ClassBase::method(const char *name, int flags, const Arguments &args)
_methods.push_back(std::make_shared<Method>(name, Abstract | flags, args));
}
+
+
/**
* Add a property to the class
* @param name Name of the property
diff --git a/src/function.h b/src/function.h
index eabc2e2..fd60944 100644
--- a/src/function.h
+++ b/src/function.h
@@ -24,10 +24,10 @@ public:
* @param name Function name
* @param function The native C function
*/
- Function(const char *name, native_callback_0 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(0) { _function.f0 = function; }
- Function(const char *name, native_callback_1 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(1) { _function.f1 = function; }
- Function(const char *name, native_callback_2 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(2) { _function.f2 = function; }
- Function(const char *name, native_callback_3 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(3) { _function.f3 = function; }
+ Function(const char *name, const native_callback_0 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(0) { _function.f0 = function; }
+ Function(const char *name, const native_callback_1 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(1) { _function.f1 = function; }
+ Function(const char *name, const native_callback_2 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(2) { _function.f2 = function; }
+ Function(const char *name, const native_callback_3 &function, const Arguments &arguments = {}) : Callable(name, arguments), _type(3) { _function.f3 = function; }
/**
* Copy constructor
diff --git a/src/method.h b/src/method.h
index f305d42..dd18a9a 100644
--- a/src/method.h
+++ b/src/method.h
@@ -27,15 +27,19 @@ public:
* @param flags Access flags
* @param args Argument description
*/
- Method(const char *name, method_callback_0 callback, int flags, const Arguments &args) : Callable(name, args), _type(0), _flags(flags) { _callback.m0 = callback; }
- Method(const char *name, method_callback_1 callback, int flags, const Arguments &args) : Callable(name, args), _type(1), _flags(flags) { _callback.m1 = callback; }
- Method(const char *name, method_callback_2 callback, int flags, const Arguments &args) : Callable(name, args), _type(2), _flags(flags) { _callback.m2 = callback; }
- Method(const char *name, method_callback_3 callback, int flags, const Arguments &args) : Callable(name, args), _type(3), _flags(flags) { _callback.m3 = callback; }
- Method(const char *name, method_callback_4 callback, int flags, const Arguments &args) : Callable(name, args), _type(4), _flags(flags) { _callback.m4 = callback; }
- Method(const char *name, method_callback_5 callback, int flags, const Arguments &args) : Callable(name, args), _type(5), _flags(flags) { _callback.m5 = callback; }
- Method(const char *name, method_callback_6 callback, int flags, const Arguments &args) : Callable(name, args), _type(6), _flags(flags) { _callback.m6 = callback; }
- Method(const char *name, method_callback_7 callback, int flags, const Arguments &args) : Callable(name, args), _type(7), _flags(flags) { _callback.m7 = callback; }
- Method(const char *name, int flags, const Arguments &args) : Callable(name, args), _type(9999), _flags(flags) { _callback.m0 = nullptr; }
+ Method(const char *name, const method_callback_0 &callback, int flags, const Arguments &args) : Callable(name, args), _type(0), _flags(flags) { _callback.m0 = callback; }
+ Method(const char *name, const method_callback_1 &callback, int flags, const Arguments &args) : Callable(name, args), _type(1), _flags(flags) { _callback.m1 = callback; }
+ Method(const char *name, const method_callback_2 &callback, int flags, const Arguments &args) : Callable(name, args), _type(2), _flags(flags) { _callback.m2 = callback; }
+ Method(const char *name, const method_callback_3 &callback, int flags, const Arguments &args) : Callable(name, args), _type(3), _flags(flags) { _callback.m3 = callback; }
+ Method(const char *name, const method_callback_4 &callback, int flags, const Arguments &args) : Callable(name, args), _type(4), _flags(flags) { _callback.m4 = callback; }
+ Method(const char *name, const method_callback_5 &callback, int flags, const Arguments &args) : Callable(name, args), _type(5), _flags(flags) { _callback.m5 = callback; }
+ Method(const char *name, const method_callback_6 &callback, int flags, const Arguments &args) : Callable(name, args), _type(6), _flags(flags) { _callback.m6 = callback; }
+ Method(const char *name, const method_callback_7 &callback, int flags, const Arguments &args) : Callable(name, args), _type(7), _flags(flags) { _callback.m7 = callback; }
+ Method(const char *name, const native_callback_0 &callback, int flags, const Arguments &args) : Callable(name, args), _type(8), _flags(flags) { _callback.m8 = callback; }
+ Method(const char *name, const native_callback_1 &callback, int flags, const Arguments &args) : Callable(name, args), _type(9), _flags(flags) { _callback.m9 = callback; }
+ Method(const char *name, const native_callback_2 &callback, int flags, const Arguments &args) : Callable(name, args), _type(10), _flags(flags) { _callback.m10 = callback; }
+ Method(const char *name, const native_callback_3 &callback, int flags, const Arguments &args) : Callable(name, args), _type(11), _flags(flags) { _callback.m11 = callback; }
+ Method(const char *name, int flags, const Arguments &args) : Callable(name, args), _type(9999), _flags(flags) { _callback.m0 = nullptr; }
/**
* Copy and move constructors
@@ -86,6 +90,10 @@ public:
case 5: (base->*_callback.m5)(parameters); return Value();
case 6: return (base->*_callback.m6)();
case 7: return (base->*_callback.m7)(parameters);
+ case 8: _callback.m8(); return Value();
+ case 9: _callback.m9(parameters); return Value();
+ case 10: return _callback.m10();
+ case 11: return _callback.m11(parameters);
default: return Value();
}
}
@@ -109,14 +117,18 @@ private:
* @var void*
*/
union {
- method_callback_0 m0;
- method_callback_1 m1;
- method_callback_2 m2;
- method_callback_3 m3;
- method_callback_4 m4;
- method_callback_5 m5;
- method_callback_6 m6;
- method_callback_7 m7;
+ method_callback_0 m0;
+ method_callback_1 m1;
+ method_callback_2 m2;
+ method_callback_3 m3;
+ method_callback_4 m4;
+ method_callback_5 m5;
+ method_callback_6 m6;
+ method_callback_7 m7;
+ native_callback_0 m8;
+ native_callback_1 m9;
+ native_callback_2 m10;
+ native_callback_3 m11;
} _callback;
};
diff --git a/src/namespace.cpp b/src/namespace.cpp
index 5efaf45..8dda791 100644
--- a/src/namespace.cpp
+++ b/src/namespace.cpp
@@ -19,7 +19,7 @@ namespace Php {
* @param function The function to add
* @param arguments Optional argument specification
*/
-void Namespace::add(const char *name, native_callback_0 function, const Arguments &arguments)
+void Namespace::add(const char *name, const native_callback_0 &function, const Arguments &arguments)
{
// add a function
_functions.push_back(std::make_shared<Function>(name, function, arguments));
@@ -31,7 +31,7 @@ void Namespace::add(const char *name, native_callback_0 function, const Argument
* @param function The function to add
* @param arguments Optional argument specification
*/
-void Namespace::add(const char *name, native_callback_1 function, const Arguments &arguments)
+void Namespace::add(const char *name, const native_callback_1 &function, const Arguments &arguments)
{
// add a function
_functions.push_back(std::make_shared<Function>(name, function, arguments));
@@ -43,7 +43,7 @@ void Namespace::add(const char *name, native_callback_1 function, const Argument
* @param function The function to add
* @param arguments Optional argument specification
*/
-void Namespace::add(const char *name, native_callback_2 function, const Arguments &arguments)
+void Namespace::add(const char *name, const native_callback_2 &function, const Arguments &arguments)
{
// add a function
_functions.push_back(std::make_shared<Function>(name, function, arguments));
@@ -55,7 +55,7 @@ void Namespace::add(const char *name, native_callback_2 function, const Argument
* @param function The function to add
* @param arguments Optional argument specification
*/
-void Namespace::add(const char *name, native_callback_3 function, const Arguments &arguments)
+void Namespace::add(const char *name, const native_callback_3 &function, const Arguments &arguments)
{
// add a function
_functions.push_back(std::make_shared<Function>(name, function, arguments));
diff --git a/src/parameters.cpp b/src/parameters.cpp
index 2fb2eef..b923bd5 100644
--- a/src/parameters.cpp
+++ b/src/parameters.cpp
@@ -39,6 +39,11 @@ Parameters::Parameters(zval *this_ptr, int argc TSRMLS_DC) : _this(this_ptr)
*/
Base *Parameters::object()
{
+ // do we have a this pointer in the first place? The member is not set
+ // when static methods are being called, or when a regular function is
+ // called in a static context
+ if (!_this) return nullptr;
+
// get the mixed object
MixedObject *obj = (MixedObject *)zend_object_store_get_object(_this TSRMLS_CC);