summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-13 23:35:54 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-13 23:35:54 +0100
commit2381b65c0bf4fc8a78e9040ffb4a1674bab4e2ad (patch)
treedc163b88edcd0f5c3e0fc06481dd66273a59ecc4 /src
parent4fea3363bafc0c19f610fa3bff10b488733a4eb1 (diff)
classes without a copy constructor can now also be used from PHP, and they automatically become unclonable
Diffstat (limited to 'src')
-rw-r--r--src/classbase.cpp13
-rw-r--r--src/includes.h1
2 files changed, 9 insertions, 5 deletions
diff --git a/src/classbase.cpp b/src/classbase.cpp
index 0a07566..ec316cd 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -363,7 +363,7 @@ zend_object_handlers *ClassBase::objectHandlers()
memcpy(&handlers, &std_object_handlers, sizeof(zend_object_handlers));
// install custom clone function
- handlers.clone_obj = &ClassBase::cloneObject;
+ handlers.clone_obj = clonable() ? &ClassBase::cloneObject : nullptr;
// functions for the Countable interface
handlers.count_elements = &ClassBase::countElements;
@@ -534,14 +534,16 @@ zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC)
// create a new base c++ object
auto *cpp = meta->clone(old_object->cpp);
- // report error on failure
+ // report error on failure (this does not occur because the cloneObject()
+ // method is only installed as handler when we have seen that there is indeed
+ // a copy constructor)
if (!cpp) throw Php::Exception(std::string("Unable to clone ") + entry->name);
// the thing we're going to return
zend_object_value result;
// set the handlers
- result.handlers = ClassBase::objectHandlers();
+ result.handlers = meta->objectHandlers();
// store the object
MixedObject *new_object = cpp->store(entry);
@@ -549,7 +551,8 @@ zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC)
// store the object in the object cache
result.handle = cpp->handle();
- // clone the members
+ // clone the members (this will also call the __clone() function if the user
+ // had registered that as a visible method)
zend_objects_clone_members(&new_object->php, result, &old_object->php, Z_OBJ_HANDLE_P(val));
// done
@@ -1094,7 +1097,7 @@ zend_object_value ClassBase::createObject(zend_class_entry *entry TSRMLS_DC)
zend_object_value result;
// set the handlers
- result.handlers = ClassBase::objectHandlers();
+ result.handlers = meta->objectHandlers();
// store the object
cpp->store(entry);
diff --git a/src/includes.h b/src/includes.h
index 0dd027c..50d4144 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -18,6 +18,7 @@
#include <memory>
#include <list>
#include <exception>
+#include <type_traits>
// for debug
#include <iostream>