summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-01 22:39:31 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-01 22:39:31 +0100
commit6abc8b4c062c7333a98830004da894ff81613d5b (patch)
tree7b11179ef6775130fce0c4ef537fb3656f716852
parentabc3b4fbf996a647bcefb02e4ecf643b659577c9 (diff)
added possibility to define interfaces, the class::add() method has been renamed to class::method() and class::property() to prevent ambiguity in defining properties and methods
-rw-r--r--Examples/CppClassesInPhp/cppclassinphp.cpp41
-rw-r--r--Examples/CppClassesInPhp/cppclassinphp.php11
-rw-r--r--include/class.h48
-rw-r--r--include/classbase.h35
-rw-r--r--include/interface.h46
-rw-r--r--include/namespace.h28
-rw-r--r--src/classbase.cpp42
-rw-r--r--src/method.h1
8 files changed, 171 insertions, 81 deletions
diff --git a/Examples/CppClassesInPhp/cppclassinphp.cpp b/Examples/CppClassesInPhp/cppclassinphp.cpp
index ebc4969..23f86bf 100644
--- a/Examples/CppClassesInPhp/cppclassinphp.cpp
+++ b/Examples/CppClassesInPhp/cppclassinphp.cpp
@@ -41,26 +41,14 @@ public:
void myMethod(Php::Parameters &params)
{
+ // check number of parameters
+ if (params.size() != 1) throw Php::Exception("Invalid number of parameters supplied");
+
std::cout << "myMethod is called." << std::endl;
- std::cout << "_x: " << _x << std::endl;
_x = params[0];
- std::cout << "New _x" << _x << std::endl;
-
- Php::Value v = params[0];
-
- std::cout << "contains: " << v.contains("bla") << std::endl;
- std::cout << "value: " << v["bla"] << std::endl;
-
- v["something"] = "something else";
}
};
-void myFunction(Php::Parameters &params)
-{
- std::cout << "regular function" << std::endl;
-}
-
-
// Symbols are exported according to the "C" language
extern "C"
{
@@ -70,26 +58,29 @@ extern "C"
// create extension
static Php::Extension extension("Cpp_classes_in_php","1.0");
- // create a namespace too
- Php::Namespace ns("MyNamespace");
+ // build an interface
+ Php::Interface interface("MyInterface");
- // add custom function
- extension.add("myFunction", myFunction, { });
+ // add methods to the interface
+ interface.method("method1");
+ interface.method("method2");
+
+ // add the interface to the extension
+ extension.add(interface);
// we are going to define a class
Php::Class<MyCustomClass> customClass("MyClass");
// add methods to it
- customClass.add("myMethod", &MyCustomClass::myMethod, Php::Final, {});
- customClass.add("property1", "prop1");
- customClass.add("property2", "prop2", Php::Protected);
+ customClass.method("myMethod", &MyCustomClass::myMethod, Php::Final, {});
+ customClass.method("myMethod2", &MyCustomClass::myMethod);
+ customClass.property("property1", "prop1");
+ customClass.property("property2", "prop2", Php::Protected);
+ customClass.method("myAbstract");
// add the class to the extension
extension.add(customClass);
- // add the namespace to the extension
- extension.add(ns);
-
// return the extension module
return extension.module();
}
diff --git a/Examples/CppClassesInPhp/cppclassinphp.php b/Examples/CppClassesInPhp/cppclassinphp.php
index cf1e42c..c2076d3 100644
--- a/Examples/CppClassesInPhp/cppclassinphp.php
+++ b/Examples/CppClassesInPhp/cppclassinphp.php
@@ -6,12 +6,17 @@
* An example file to show the working of using a C++ class in PHP.
*/
-// run the regular function
-myFunction();
-
//create a MyCustomClass object, which is an object of a C++ class
$object = new MyClass();
+class ImplementedInterface implements MyInterface
+{
+}
+
+$object2 = new ImplementedInterface();
+
+return;
+
// run a function of the class
$object->myMethod(1);
diff --git a/include/class.h b/include/class.h
index 72615e5..61d5856 100644
--- a/include/class.h
+++ b/include/class.h
@@ -64,14 +64,28 @@ public:
* @param flags Optional flags
* @param args Argument descriptions
*/
- void add(const char *name, void(T::*method)(), int flags = Public, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_0>(method), flags, args); }
- void add(const char *name, void(T::*method)(Parameters &params), int flags = Public, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_1>(method), flags, args); }
- void add(const char *name, bool(T::*method)(), int flags = Public, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_2>(method), flags, args); }
- void add(const char *name, bool(T::*method)(Parameters &params), int flags = Public, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_3>(method), flags, args); }
- void add(const char *name, void(T::*method)(), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_0>(method), Public, args); }
- void add(const char *name, void(T::*method)(Parameters &params), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_1>(method), Public, args); }
- void add(const char *name, bool(T::*method)(), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_2>(method), Public, args); }
- void add(const char *name, bool(T::*method)(Parameters &params), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_3>(method), Public, args); }
+ void method(const char *name, void(T::*method)(), int flags, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_0>(method), flags, args); }
+ void method(const char *name, void(T::*method)(Parameters &params), int flags, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_1>(method), flags, args); }
+ void method(const char *name, bool(T::*method)(), int flags, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_2>(method), flags, args); }
+ void method(const char *name, bool(T::*method)(Parameters &params), int flags, const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_3>(method), flags, args); }
+ void method(const char *name, void(T::*method)(), const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_0>(method), Public, args); }
+ void method(const char *name, void(T::*method)(Parameters &params), const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_1>(method), Public, args); }
+ void method(const char *name, bool(T::*method)(), const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_2>(method), Public, args); }
+ void method(const char *name, bool(T::*method)(Parameters &params), const Arguments &args = {}) { ClassBase::method(name, static_cast<method_callback_3>(method), Public, args); }
+
+ /**
+ * Add an abstract method to the class
+ *
+ * This is only meaningful for classes that can be extended. Because the
+ * method is abstract, you will not have to pass an implementation. You
+ * can pass in flags to mark the method as protected
+ *
+ * @param name Name of the method
+ * @param flags Optional flags
+ * @param args Argument descriptions
+ */
+ void method(const char *name, int flags, const Arguments &args = {}) { ClassBase::method(name, flags | Abstract, args); }
+ void method(const char *name, const Arguments &args = {}) { ClassBase::method(name, Public | Abstract, args); }
/**
* Add a property to the class
@@ -86,15 +100,15 @@ public:
* @param value Actual property value
* @param flags Optional flags
*/
- void add(const char *name, std::nullptr_t value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, uint64_t value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, uint32_t value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, uint16_t value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, char value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, const char *value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, const std::string &value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, bool value, int flags = Public) { ClassBase::add(name, value, flags); }
- void add(const char *name, double value, int flags = Public) { ClassBase::add(name, value, flags); }
+ void property(const char *name, std::nullptr_t value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, uint64_t value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, uint32_t value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, uint16_t value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, char value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, const char *value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, const std::string &value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, bool value, int flags = Public) { ClassBase::property(name, value, flags); }
+ void property(const char *name, double value, int flags = Public) { ClassBase::property(name, value, flags); }
protected:
/**
diff --git a/include/classbase.h b/include/classbase.h
index 98a430e..1cfba83 100644
--- a/include/classbase.h
+++ b/include/classbase.h
@@ -109,10 +109,19 @@ protected:
* @param flags Optional flags
* @param args Description of the supported arguments
*/
- void add(const char *name, method_callback_0, int flags=0, const Arguments &args = {});
- void add(const char *name, method_callback_1, int flags=0, const Arguments &args = {});
- void add(const char *name, method_callback_2, int flags=0, const Arguments &args = {});
- void add(const char *name, method_callback_3, int flags=0, const Arguments &args = {});
+ 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 = {});
+
+ /**
+ * Add an abstract method to the class
+ *
+ * @param name Name of the method
+ * @param flags Optional flags (like public or protected)
+ * @param args Description of the supported arguments
+ */
+ void method(const char *name, int flags=0, const Arguments &args = {});
/**
* Add a property to the class
@@ -127,15 +136,15 @@ protected:
* @param value Actual property value
* @param flags Optional flags
*/
- void add(const char *name, std::nullptr_t value, int flags = Php::Public);
- void add(const char *name, int16_t value, int flags = Php::Public);
- void add(const char *name, int32_t value, int flags = Php::Public);
- void add(const char *name, int64_t value, int flags = Php::Public);
- void add(const char *name, bool value, int flags = Php::Public);
- void add(const char *name, char value, int flags = Php::Public);
- void add(const char *name, const std::string &value, int flags = Php::Public);
- void add(const char *name, const char *value, int flags = Php::Public);
- void add(const char *name, double value, int flags = Php::Public);
+ void property(const char *name, std::nullptr_t value, int flags = Php::Public);
+ void property(const char *name, int16_t value, int flags = Php::Public);
+ void property(const char *name, int32_t value, int flags = Php::Public);
+ void property(const char *name, int64_t value, int flags = Php::Public);
+ void property(const char *name, bool value, int flags = Php::Public);
+ void property(const char *name, char value, int flags = Php::Public);
+ void property(const char *name, const std::string &value, int flags = Php::Public);
+ void property(const char *name, const char *value, int flags = Php::Public);
+ void property(const char *name, double value, int flags = Php::Public);
private:
diff --git a/include/interface.h b/include/interface.h
index 7bdb5d6..38f85f3 100644
--- a/include/interface.h
+++ b/include/interface.h
@@ -11,11 +11,49 @@
namespace Php {
/**
- * @todo implementation, should be somehow an extension of a regular
- * class, but without methods to define methods
- *
- * the flag that should be passed to the base it 0x80
+ * Class definition
*/
+class Interface : private ClassBase
+{
+public:
+ /**
+ * Constructor
+ * @param name
+ */
+ Interface(const char *name) : ClassBase(name, 0x80) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~Interface() {}
+
+ /**
+ * Add a - of course abstract - method to the interface
+ * @param name Name of the method
+ * @param arguments Optional description of the arguments
+ */
+ void method(const char *name, const Arguments &arguments = {})
+ {
+ // call base
+ ClassBase::method(name, Abstract | Public, arguments);
+ }
+
+private:
+ /**
+ * Construct a new instance of the object
+ * @return Base
+ */
+ virtual Base* construct() override
+ {
+ // this does not occur for interfaces
+ return nullptr;
+ }
+
+ /**
+ * Namespaces have access to the private base class
+ */
+ friend class Namespace;
+};
/**
* End namespace
diff --git a/include/namespace.h b/include/namespace.h
index ef625fc..4cbf43e 100644
--- a/include/namespace.h
+++ b/include/namespace.h
@@ -78,7 +78,6 @@ public:
/**
* Add a native class to the extension by moving it
- * @param name Name of the class
* @param type The class implementation
*/
template<typename T>
@@ -93,7 +92,6 @@ public:
/**
* Add a native class to the extension by copying it
- * @param name Name of the class
* @param type The class implementation
*/
template<typename T>
@@ -105,6 +103,32 @@ public:
// and add it to the list of classes
_classes.push_back(std::unique_ptr<ClassBase>(copy));
}
+
+ /**
+ * Add an interface to the extension by moving it
+ * @param interface The interface properties
+ */
+ void add(Interface &&interface)
+ {
+ // make a copy of the object
+ auto *copy = new Interface(std::move(interface));
+
+ // and add it to the list of classes
+ _classes.push_back(std::unique_ptr<ClassBase>(copy));
+ }
+
+ /**
+ * Add an interface to the extension by copying it
+ * @param interface The interface properties
+ */
+ void add(const Interface &interface)
+ {
+ // make a copy of the object
+ auto *copy = new Interface(interface);
+
+ // and add it to the list of classes
+ _classes.push_back(std::unique_ptr<ClassBase>(copy));
+ }
/**
* Add a namespace to the extension by moving it
diff --git a/src/classbase.cpp b/src/classbase.cpp
index 71dd09d..3fabdea 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -165,13 +165,9 @@ void ClassBase::initialize(const std::string &prefix)
// the class entry
zend_class_entry entry;
- std::cout << "prefix " << prefix << std::endl;
-
// update the name
if (prefix.size() > 0) _name = prefix + "\\" + _name;
- std::cout << "init class " << _name << std::endl;
-
// initialize the class entry
INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), entries());
@@ -220,7 +216,7 @@ void ClassBase::initialize(const std::string &prefix)
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::add(const char *name, method_callback_0 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, method_callback_0 callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -233,7 +229,7 @@ void ClassBase::add(const char *name, method_callback_0 callback, int flags, con
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::add(const char *name, method_callback_1 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, method_callback_1 callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -246,7 +242,7 @@ void ClassBase::add(const char *name, method_callback_1 callback, int flags, con
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::add(const char *name, method_callback_2 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, method_callback_2 callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
@@ -259,19 +255,31 @@ void ClassBase::add(const char *name, method_callback_2 callback, int flags, con
* @param flags Optional flags
* @param args Description of the supported arguments
*/
-void ClassBase::add(const char *name, method_callback_3 callback, int flags, const Arguments &args)
+void ClassBase::method(const char *name, method_callback_3 callback, int flags, const Arguments &args)
{
// add the method
_methods.push_back(std::make_shared<Method>(name, callback, flags, args));
}
/**
+ * Add an abstract method to the class
+ * @param name Name of the method
+ * @param flags Optional flags (like public or protected)
+ * @param args Description of the supported arguments
+ */
+void ClassBase::method(const char *name, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.push_back(std::make_shared<Method>(name, Abstract | flags, args));
+}
+
+/**
* Add a property to the class
* @param name Name of the property
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, std::nullptr_t value, int flags)
+void ClassBase::property(const char *name, std::nullptr_t value, int flags)
{
// add property
_members.push_back(std::make_shared<NullMember>(name, flags));
@@ -283,7 +291,7 @@ void ClassBase::add(const char *name, std::nullptr_t value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, int16_t value, int flags)
+void ClassBase::property(const char *name, int16_t value, int flags)
{
// add property
_members.push_back(std::make_shared<LongMember>(name, value, flags));
@@ -295,7 +303,7 @@ void ClassBase::add(const char *name, int16_t value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, int32_t value, int flags)
+void ClassBase::property(const char *name, int32_t value, int flags)
{
// add property
_members.push_back(std::make_shared<LongMember>(name, value, flags));
@@ -307,7 +315,7 @@ void ClassBase::add(const char *name, int32_t value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, int64_t value, int flags)
+void ClassBase::property(const char *name, int64_t value, int flags)
{
// add property
_members.push_back(std::make_shared<LongMember>(name, value, flags));
@@ -319,7 +327,7 @@ void ClassBase::add(const char *name, int64_t value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, bool value, int flags)
+void ClassBase::property(const char *name, bool value, int flags)
{
// add property
_members.push_back(std::make_shared<BoolMember>(name, value, flags));
@@ -331,7 +339,7 @@ void ClassBase::add(const char *name, bool value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, char value, int flags)
+void ClassBase::property(const char *name, char value, int flags)
{
// add property
_members.push_back(std::make_shared<StringMember>(name, &value, 1, flags));
@@ -343,7 +351,7 @@ void ClassBase::add(const char *name, char value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, const std::string &value, int flags)
+void ClassBase::property(const char *name, const std::string &value, int flags)
{
// add property
_members.push_back(std::make_shared<StringMember>(name, value, flags));
@@ -355,7 +363,7 @@ void ClassBase::add(const char *name, const std::string &value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, const char *value, int flags)
+void ClassBase::property(const char *name, const char *value, int flags)
{
// add property
_members.push_back(std::make_shared<StringMember>(name, value, strlen(value), flags));
@@ -367,7 +375,7 @@ void ClassBase::add(const char *name, const char *value, int flags)
* @param value Actual property value
* @param flags Optional flags
*/
-void ClassBase::add(const char *name, double value, int flags)
+void ClassBase::property(const char *name, double value, int flags)
{
// add property
_members.push_back(std::make_shared<FloatMember>(name, value, flags));
diff --git a/src/method.h b/src/method.h
index 6a91068..8b545b0 100644
--- a/src/method.h
+++ b/src/method.h
@@ -31,6 +31,7 @@ public:
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, int flags, const Arguments &args) : Callable(name, args), _type(4), _flags(flags) { _callback.m0 = nullptr; }
/**
* Destructor