Commit f3aac625 authored by twanvl's avatar twanvl

Always use intrusive_ptr, it was required anyway.

This means that we no longer need to pass smart pointers to this in thisP arguments, since we can construct a new intrusive_ptr to the same object from a regular C++ pointer.

(This change is manually merged from the non_null_pointer branch)
parent dcbfc035
...@@ -28,7 +28,7 @@ void AddCardsScript::perform(Set& set, vector<CardP>& out) { ...@@ -28,7 +28,7 @@ void AddCardsScript::perform(Set& set, vector<CardP>& out) {
Context& ctx = set.getContext(); Context& ctx = set.getContext();
ScriptValueP result = script.invoke(ctx); ScriptValueP result = script.invoke(ctx);
// Add cards to out // Add cards to out
ScriptValueP it = result->makeIterator(result); ScriptValueP it = result->makeIterator();
while (ScriptValueP item = it->next()) { while (ScriptValueP item = it->next()) {
CardP card = from_script<CardP>(item); CardP card = from_script<CardP>(item);
// is this a new card? // is this a new card?
......
...@@ -124,7 +124,7 @@ IMPLEMENT_REFLECTION(Style) { ...@@ -124,7 +124,7 @@ IMPLEMENT_REFLECTION(Style) {
} }
void init_object(const FieldP& field, StyleP& style) { void init_object(const FieldP& field, StyleP& style) {
if (!style) style = field->newStyle(field); if (!style) style = field->newStyle();
} }
template <> StyleP read_new<Style>(Reader&) { template <> StyleP read_new<Style>(Reader&) {
throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already")); throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already"));
...@@ -289,7 +289,7 @@ void Value::updateSortValue(Context& ctx) { ...@@ -289,7 +289,7 @@ void Value::updateSortValue(Context& ctx) {
void init_object(const FieldP& field, ValueP& value) { void init_object(const FieldP& field, ValueP& value) {
if (!value) if (!value)
value = field->newValue(field); value = field->newValue();
} }
template <> ValueP read_new<Value>(Reader&) { template <> ValueP read_new<Value>(Reader&) {
throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already")); throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already"));
......
...@@ -62,11 +62,9 @@ class Field : public IntrusivePtrVirtualBase { ...@@ -62,11 +62,9 @@ class Field : public IntrusivePtrVirtualBase {
Dependencies dependent_scripts; ///< Scripts that depend on values of this field Dependencies dependent_scripts; ///< Scripts that depend on values of this field
/// Creates a new Value corresponding to this Field /// Creates a new Value corresponding to this Field
/** thisP is a smart pointer to this */ virtual ValueP newValue() = 0;
virtual ValueP newValue(const FieldP& thisP) const = 0;
/// Creates a new Style corresponding to this Field /// Creates a new Style corresponding to this Field
/** thisP is a smart pointer to this */ virtual StyleP newStyle() = 0;
virtual StyleP newStyle(const FieldP& thisP) const = 0;
/// Type of this field /// Type of this field
virtual String typeName() const = 0; virtual String typeName() const = 0;
...@@ -129,11 +127,9 @@ class Style : public IntrusivePtrVirtualBase { ...@@ -129,11 +127,9 @@ class Style : public IntrusivePtrVirtualBase {
virtual StyleP clone() const = 0; virtual StyleP clone() const = 0;
/// Make a viewer object for values using this style /// Make a viewer object for values using this style
/** thisP is a smart pointer to this */ virtual ValueViewerP makeViewer(DataViewer& parent) = 0;
virtual ValueViewerP makeViewer(DataViewer& parent, const StyleP& thisP) = 0;
/// Make an editor object for values using this style /// Make an editor object for values using this style
/** thisP is a smart pointer to this */ virtual ValueViewerP makeEditor(DataEditor& parent) = 0;
virtual ValueViewerP makeEditor(DataEditor& parent, const StyleP& thisP) = 0;
/// Update scripted values of this style, return nonzero if anything has changed. /// Update scripted values of this style, return nonzero if anything has changed.
/** The caller should tellListeners() /** The caller should tellListeners()
...@@ -258,22 +254,20 @@ inline String type_name(const Value&) { ...@@ -258,22 +254,20 @@ inline String type_name(const Value&) {
// ----------------------------------------------------------------------------- : Utilities // ----------------------------------------------------------------------------- : Utilities
#define DECLARE_FIELD_TYPE(Type) \ #define DECLARE_FIELD_TYPE(Type) \
DECLARE_REFLECTION(); public: \ DECLARE_REFLECTION(); public: \
virtual ValueP newValue(const FieldP& thisP) const; \ virtual ValueP newValue(); \
virtual StyleP newStyle(const FieldP& thisP) const; \ virtual StyleP newStyle(); \
virtual String typeName() const virtual String typeName() const
// implement newStyle and newValue // implement newStyle and newValue
#define IMPLEMENT_FIELD_TYPE(Type, NAME) \ #define IMPLEMENT_FIELD_TYPE(Type, NAME) \
StyleP Type ## Field::newStyle(const FieldP& thisP) const { \ StyleP Type ## Field::newStyle() { \
assert(thisP.get() == this); \ return intrusive(new Type ## Style(intrusive_from_existing(this))); \
return intrusive(new Type ## Style(static_pointer_cast<Type ## Field>(thisP))); \ } \
} \ ValueP Type ## Field::newValue() { \
ValueP Type ## Field::newValue(const FieldP& thisP) const { \ return intrusive(new Type ## Value(intrusive_from_existing(this))); \
assert(thisP.get() == this); \ } \
return intrusive(new Type ## Value(static_pointer_cast<Type ## Field>(thisP))); \
} \
StyleP Type ## Style::clone() const { \ StyleP Type ## Style::clone() const { \
return intrusive(new Type ## Style(*this)); \ return intrusive(new Type ## Style(*this)); \
} \ } \
...@@ -284,12 +278,12 @@ inline String type_name(const Value&) { ...@@ -284,12 +278,12 @@ inline String type_name(const Value&) {
return _(NAME); \ return _(NAME); \
} }
#define DECLARE_STYLE_TYPE(Type) \ #define DECLARE_STYLE_TYPE(Type) \
DECLARE_REFLECTION(); public: \ DECLARE_REFLECTION(); public: \
DECLARE_HAS_FIELD(Type) \ DECLARE_HAS_FIELD(Type) \
virtual StyleP clone() const; \ virtual StyleP clone() const; \
virtual ValueViewerP makeViewer(DataViewer& parent, const StyleP& thisP); \ virtual ValueViewerP makeViewer(DataViewer& parent); \
virtual ValueViewerP makeEditor(DataEditor& parent, const StyleP& thisP) virtual ValueViewerP makeEditor(DataEditor& parent)
#define DECLARE_VALUE_TYPE(Type,ValueType_) \ #define DECLARE_VALUE_TYPE(Type,ValueType_) \
DECLARE_REFLECTION(); public: \ DECLARE_REFLECTION(); public: \
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
ScriptType GeneratedImage::type() const { return SCRIPT_IMAGE; } ScriptType GeneratedImage::type() const { return SCRIPT_IMAGE; }
String GeneratedImage::typeName() const { return _TYPE_("image"); } String GeneratedImage::typeName() const { return _TYPE_("image"); }
GeneratedImageP GeneratedImage::toImage(const ScriptValueP& thisP) const { GeneratedImageP GeneratedImage::toImage() const {
return static_pointer_cast<GeneratedImage>(thisP); return intrusive_from_existing(const_cast<GeneratedImage*>(this));
} }
Image GeneratedImage::generateConform(const Options& options) const { Image GeneratedImage::generateConform(const Options& options) const {
......
...@@ -62,7 +62,7 @@ class GeneratedImage : public ScriptValue { ...@@ -62,7 +62,7 @@ class GeneratedImage : public ScriptValue {
virtual ScriptType type() const; virtual ScriptType type() const;
virtual String typeName() const; virtual String typeName() const;
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const; virtual GeneratedImageP toImage() const;
}; };
/// Resize an image to conform to the options /// Resize an image to conform to the options
......
...@@ -35,7 +35,7 @@ DataEditor::DataEditor(Window* parent, int id, long style) ...@@ -35,7 +35,7 @@ DataEditor::DataEditor(Window* parent, int id, long style)
} }
ValueViewerP DataEditor::makeViewer(const StyleP& style) { ValueViewerP DataEditor::makeViewer(const StyleP& style) {
return style->makeEditor(*this, style); return style->makeEditor(*this);
} }
// ----------------------------------------------------------------------------- : Utility for ValueViewers // ----------------------------------------------------------------------------- : Utility for ValueViewers
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
//| License: GNU General Public License 2 or later (see file COPYING) | //| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+ //+----------------------------------------------------------------------------+
#ifndef HEADER_GUI_CONTROL_FILTER_CTRL #ifndef HEADER_GUI_CONTROL_FILTER_CTRL
#define HEADER_GUI_CONTROL_FILTER_CTRL #define HEADER_GUI_CONTROL_FILTER_CTRL
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
//| License: GNU General Public License 2 or later (see file COPYING) | //| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+ //+----------------------------------------------------------------------------+
#ifndef HEADER_GUI_PACKAGES_WINDOW #ifndef HEADER_GUI_PACKAGES_WINDOW
#define HEADER_GUI_PACKAGES_WINDOW #define HEADER_GUI_PACKAGES_WINDOW
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
......
...@@ -408,7 +408,7 @@ void ConsolePanel::exec(String const& command) { ...@@ -408,7 +408,7 @@ void ConsolePanel::exec(String const& command) {
ScriptType type = result->type(); ScriptType type = result->type();
if (type == SCRIPT_IMAGE) { if (type == SCRIPT_IMAGE) {
GeneratedImage::Options options(0,0, set->stylesheet.get(), set.get()); GeneratedImage::Options options(0,0, set->stylesheet.get(), set.get());
wxImage image = result->toImage(result)->generate(options); wxImage image = result->toImage()->generate(options);
message->bitmap = wxBitmap(image); message->bitmap = wxBitmap(image);
} else if (type == SCRIPT_COLOR) { } else if (type == SCRIPT_COLOR) {
message->text = result->toCode(); message->text = result->toCode();
......
...@@ -145,12 +145,11 @@ class ValueEditor { ...@@ -145,12 +145,11 @@ class ValueEditor {
} \ } \
public: public:
#define IMPLEMENT_VALUE_EDITOR(Type) \ #define IMPLEMENT_VALUE_EDITOR(Type) \
ValueViewerP Type##Style::makeEditor(DataEditor& parent, const StyleP& thisP) { \ ValueViewerP Type##Style::makeEditor(DataEditor& parent) { \
assert(thisP.get() == this); \ return intrusive(new Type##ValueEditor(parent, intrusive_from_existing(this))); \
return ValueViewerP(new Type##ValueEditor(parent, static_pointer_cast<Type##Style>(thisP))); \ } \
} \ Type##ValueEditor::Type##ValueEditor(DataEditor& parent, const Type##StyleP& style) \
Type##ValueEditor::Type##ValueEditor(DataEditor& parent, const Type##StyleP& style) \
: Type##ValueViewer(parent, style) : Type##ValueViewer(parent, style)
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
...@@ -201,7 +201,7 @@ void DataViewer::setData(IndexMap<FieldP,ValueP>& values, IndexMap<FieldP,ValueP ...@@ -201,7 +201,7 @@ void DataViewer::setData(IndexMap<FieldP,ValueP>& values, IndexMap<FieldP,ValueP
ValueViewerP DataViewer::makeViewer(const StyleP& style) { ValueViewerP DataViewer::makeViewer(const StyleP& style) {
return style->makeViewer(*this, style); return style->makeViewer(*this);
} }
void DataViewer::onAction(const Action& action, bool undone) { void DataViewer::onAction(const Action& action, bool undone) {
......
...@@ -113,10 +113,9 @@ class ValueViewer : public StyleListener { ...@@ -113,10 +113,9 @@ class ValueViewer : public StyleListener {
public: \ public: \
Type##ValueViewer(DataViewer& parent, const Type ## StyleP& style) Type##ValueViewer(DataViewer& parent, const Type ## StyleP& style)
#define IMPLEMENT_VALUE_VIEWER(Type) \ #define IMPLEMENT_VALUE_VIEWER(Type) \
ValueViewerP Type##Style::makeViewer(DataViewer& parent, const StyleP& thisP) { \ ValueViewerP Type##Style::makeViewer(DataViewer& parent) { \
assert(thisP.get() == this); \ return intrusive(new Type##ValueViewer(parent, intrusive_from_existing(this))); \
return ValueViewerP(new Type##ValueViewer(parent, static_pointer_cast<Type##Style>(thisP))); \
} }
......
...@@ -362,7 +362,7 @@ void Context::closeScope(size_t scope) { ...@@ -362,7 +362,7 @@ void Context::closeScope(size_t scope) {
void instrUnary (UnaryInstructionType i, ScriptValueP& a) { void instrUnary (UnaryInstructionType i, ScriptValueP& a) {
switch (i) { switch (i) {
case I_ITERATOR_C: case I_ITERATOR_C:
a = a->makeIterator(a); a = a->makeIterator();
break; break;
case I_NEGATE: { case I_NEGATE: {
ScriptType at = a->type(); ScriptType at = a->type();
......
...@@ -52,8 +52,8 @@ class DependencyUnion : public ScriptValue { ...@@ -52,8 +52,8 @@ class DependencyUnion : public ScriptValue {
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const { virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const {
return unified( a->dependencies(ctx,dep), b->dependencies(ctx,dep)); return unified( a->dependencies(ctx,dep), b->dependencies(ctx,dep));
} }
virtual ScriptValueP makeIterator(ScriptValueP thisP) const { virtual ScriptValueP makeIterator() const {
return unified(a->makeIterator(thisP), b->makeIterator(thisP)); return unified(a->makeIterator(), b->makeIterator());
} }
virtual ScriptValueP dependencyMember(const String& name, const Dependency& dep) const { virtual ScriptValueP dependencyMember(const String& name, const Dependency& dep) const {
return unified(a->dependencyMember(name,dep), b->dependencyMember(name,dep)); return unified(a->dependencyMember(name,dep), b->dependencyMember(name,dep));
...@@ -310,7 +310,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script) ...@@ -310,7 +310,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
ScriptValueP& a = stack.back(); ScriptValueP& a = stack.back();
switch (i.instr1) { switch (i.instr1) {
case I_ITERATOR_C: case I_ITERATOR_C:
a = a->makeIterator(a); // as normal a = a->makeIterator(); // as normal
break; break;
default: default:
a = dependency_dummy; a = dependency_dummy;
......
...@@ -455,7 +455,7 @@ int position_in_vector(const ScriptValueP& of, const ScriptValueP& in, const Scr ...@@ -455,7 +455,7 @@ int position_in_vector(const ScriptValueP& of, const ScriptValueP& in, const Scr
} }
} else { } else {
// unordered position // unordered position
ScriptValueP it = in->makeIterator(in); ScriptValueP it = in->makeIterator();
int i = 0; int i = 0;
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
if (equal(of, v)) return i; if (equal(of, v)) return i;
...@@ -488,7 +488,7 @@ ScriptValueP sort_script(Context& ctx, const ScriptValueP& list, ScriptValue& or ...@@ -488,7 +488,7 @@ ScriptValueP sort_script(Context& ctx, const ScriptValueP& list, ScriptValue& or
ScriptObject<Set*>* set = dynamic_cast<ScriptObject<Set*>*>(list.get()); ScriptObject<Set*>* set = dynamic_cast<ScriptObject<Set*>*>(list.get());
// sort a collection // sort a collection
vector<pair<String,ScriptValueP> > values; vector<pair<String,ScriptValueP> > values;
ScriptValueP it = list->makeIterator(list); ScriptValueP it = list->makeIterator();
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
ctx.setVariable(set ? _("card") : _("input"), v); ctx.setVariable(set ? _("card") : _("input"), v);
values.push_back(make_pair(order_by.eval(ctx)->toString(), v)); values.push_back(make_pair(order_by.eval(ctx)->toString(), v));
...@@ -563,7 +563,7 @@ SCRIPT_FUNCTION(filter_list) { ...@@ -563,7 +563,7 @@ SCRIPT_FUNCTION(filter_list) {
SCRIPT_PARAM_C(ScriptValueP, filter); SCRIPT_PARAM_C(ScriptValueP, filter);
// filter a collection // filter a collection
ScriptCustomCollectionP ret(new ScriptCustomCollection()); ScriptCustomCollectionP ret(new ScriptCustomCollection());
ScriptValueP it = input->makeIterator(input); ScriptValueP it = input->makeIterator();
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
ctx.setVariable(SCRIPT_VAR_input, v); ctx.setVariable(SCRIPT_VAR_input, v);
if (filter->eval(ctx)->toBool()) { if (filter->eval(ctx)->toBool()) {
...@@ -586,7 +586,7 @@ SCRIPT_FUNCTION(random_shuffle) { ...@@ -586,7 +586,7 @@ SCRIPT_FUNCTION(random_shuffle) {
SCRIPT_PARAM_C(ScriptValueP, input); SCRIPT_PARAM_C(ScriptValueP, input);
// convert to CustomCollection // convert to CustomCollection
ScriptCustomCollectionP ret(new ScriptCustomCollection()); ScriptCustomCollectionP ret(new ScriptCustomCollection());
ScriptValueP it = input->makeIterator(input); ScriptValueP it = input->makeIterator();
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
ret->value.push_back(v); ret->value.push_back(v);
} }
...@@ -625,7 +625,7 @@ SCRIPT_FUNCTION(random_select_many) { ...@@ -625,7 +625,7 @@ SCRIPT_FUNCTION(random_select_many) {
throw ScriptError(String::Format(_("Can not select %d items from a collection conaining only %d items"), count, input->itemCount())); throw ScriptError(String::Format(_("Can not select %d items from a collection conaining only %d items"), count, input->itemCount()));
} }
// transfer all to ret and shuffle // transfer all to ret and shuffle
ScriptValueP it = input->makeIterator(input); ScriptValueP it = input->makeIterator();
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
ret->value.push_back(v); ret->value.push_back(v);
} }
......
...@@ -25,7 +25,7 @@ SCRIPT_FUNCTION(new_card) { ...@@ -25,7 +25,7 @@ SCRIPT_FUNCTION(new_card) {
CardP new_card = intrusive(new Card(*game)); CardP new_card = intrusive(new Card(*game));
// set field values // set field values
SCRIPT_PARAM(ScriptValueP, input); SCRIPT_PARAM(ScriptValueP, input);
ScriptValueP it = input->makeIterator(input); ScriptValueP it = input->makeIterator();
ScriptValueP key; ScriptValueP key;
while (ScriptValueP v = it->next(&key)) { while (ScriptValueP v = it->next(&key)) {
assert(key); assert(key);
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
// convert any script value to a GeneratedImageP // convert any script value to a GeneratedImageP
GeneratedImageP image_from_script(const ScriptValueP& value) { GeneratedImageP image_from_script(const ScriptValueP& value) {
return value->toImage(value); return value->toImage();
} }
// ----------------------------------------------------------------------------- : ScriptableImage // ----------------------------------------------------------------------------- : ScriptableImage
......
...@@ -154,20 +154,9 @@ void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) { ...@@ -154,20 +154,9 @@ void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) {
void SetScriptManager::onAction(const Action& action, bool undone) { void SetScriptManager::onAction(const Action& action, bool undone) {
TYPE_CASE(action, ValueAction) { TYPE_CASE(action, ValueAction) {
if (action.card) { if (action.card) {
#ifdef USE_INTRUSIVE_PTR // we can just turn the Card* into a CardP
// we can just turn the Card* into a CardP updateValue(*action.valueP, intrusive_from_existing(const_cast<Card*>(action.card)));
updateValue(*action.valueP, CardP(const_cast<Card*>(action.card))); return;
return;
#else
// find the affected card
FOR_EACH(card, set.cards) {
if (card->data.contains(action.valueP)) {
updateValue(*action.valueP, card);
return;
}
}
assert(false);
#endif
} else { } else {
// is it a keyword's fake value? // is it a keyword's fake value?
KeywordTextValue* value = dynamic_cast<KeywordTextValue*>(action.valueP.get()); KeywordTextValue* value = dynamic_cast<KeywordTextValue*>(action.valueP.get());
......
...@@ -85,7 +85,7 @@ class ScriptDelayedError : public ScriptValue { ...@@ -85,7 +85,7 @@ class ScriptDelayedError : public ScriptValue {
virtual ScriptValueP getMember(const String& name) const; virtual ScriptValueP getMember(const String& name) const;
virtual ScriptValueP dependencyMember(const String& name, const Dependency&) const; virtual ScriptValueP dependencyMember(const String& name, const Dependency&) const;
virtual ScriptValueP dependencies(Context&, const Dependency&) const; virtual ScriptValueP dependencies(Context&, const Dependency&) const;
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const; virtual ScriptValueP makeIterator() const;
protected: protected:
virtual ScriptValueP do_eval(Context&, bool openScope) const; virtual ScriptValueP do_eval(Context&, bool openScope) const;
...@@ -111,7 +111,7 @@ struct ScriptIterator : public ScriptValue { ...@@ -111,7 +111,7 @@ struct ScriptIterator : public ScriptValue {
/// Return the next item for this iterator, or ScriptValueP() if there is no such item /// Return the next item for this iterator, or ScriptValueP() if there is no such item
virtual ScriptValueP next(ScriptValueP* key_out = nullptr) = 0; virtual ScriptValueP next(ScriptValueP* key_out = nullptr) = 0;
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const; virtual ScriptValueP makeIterator() const;
}; };
// make an iterator over a range // make an iterator over a range
...@@ -159,7 +159,7 @@ class ScriptCollection : public ScriptCollectionBase { ...@@ -159,7 +159,7 @@ class ScriptCollection : public ScriptCollectionBase {
return ScriptValue::getIndex(index); return ScriptValue::getIndex(index);
} }
} }
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const { virtual ScriptValueP makeIterator() const {
return intrusive(new ScriptCollectionIterator<Collection>(value)); return intrusive(new ScriptCollectionIterator<Collection>(value));
} }
virtual int itemCount() const { return (int)value->size(); } virtual int itemCount() const { return (int)value->size(); }
...@@ -227,7 +227,7 @@ class ScriptCustomCollection : public ScriptCollectionBase { ...@@ -227,7 +227,7 @@ class ScriptCustomCollection : public ScriptCollectionBase {
public: public:
virtual ScriptValueP getMember(const String& name) const; virtual ScriptValueP getMember(const String& name) const;
virtual ScriptValueP getIndex(int index) const; virtual ScriptValueP getIndex(int index) const;
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const; virtual ScriptValueP makeIterator() const;
virtual int itemCount() const { return (int)value.size(); } virtual int itemCount() const { return (int)value.size(); }
/// Collections can be compared by comparing pointers /// Collections can be compared by comparing pointers
virtual CompareWhat compareAs(String&, void const*& compare_ptr) const { virtual CompareWhat compareAs(String&, void const*& compare_ptr) const {
...@@ -251,7 +251,7 @@ class ScriptConcatCollection : public ScriptCollectionBase { ...@@ -251,7 +251,7 @@ class ScriptConcatCollection : public ScriptCollectionBase {
inline ScriptConcatCollection(ScriptValueP a, ScriptValueP b) : a(a), b(b) {} inline ScriptConcatCollection(ScriptValueP a, ScriptValueP b) : a(a), b(b) {}
virtual ScriptValueP getMember(const String& name) const; virtual ScriptValueP getMember(const String& name) const;
virtual ScriptValueP getIndex(int index) const; virtual ScriptValueP getIndex(int index) const;
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const; virtual ScriptValueP makeIterator() const;
virtual int itemCount() const { return a->itemCount() + b->itemCount(); } virtual int itemCount() const { return a->itemCount() + b->itemCount(); }
/// Collections can be compared by comparing pointers /// Collections can be compared by comparing pointers
virtual CompareWhat compareAs(String&, void const*& compare_ptr) const { virtual CompareWhat compareAs(String&, void const*& compare_ptr) const {
...@@ -279,8 +279,8 @@ class ScriptObject : public ScriptValue { ...@@ -279,8 +279,8 @@ class ScriptObject : public ScriptValue {
virtual bool toBool() const { ScriptValueP d = getDefault(); return d ? d->toBool() : ScriptValue::toBool(); } virtual bool toBool() const { ScriptValueP d = getDefault(); return d ? d->toBool() : ScriptValue::toBool(); }
virtual AColor toColor() const { ScriptValueP d = getDefault(); return d ? d->toColor() : ScriptValue::toColor(); } virtual AColor toColor() const { ScriptValueP d = getDefault(); return d ? d->toColor() : ScriptValue::toColor(); }
virtual String toCode() const { ScriptValueP d = getDefault(); return d ? d->toCode() : to_code(*value); } virtual String toCode() const { ScriptValueP d = getDefault(); return d ? d->toCode() : to_code(*value); }
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const { virtual GeneratedImageP toImage() const {
ScriptValueP d = getDefault(); return d ? d->toImage(d) : ScriptValue::toImage(thisP); ScriptValueP d = getDefault(); return d ? d->toImage() : ScriptValue::toImage();
} }
virtual ScriptValueP getMember(const String& name) const { virtual ScriptValueP getMember(const String& name) const {
#if USE_SCRIPT_PROFILING #if USE_SCRIPT_PROFILING
...@@ -308,12 +308,12 @@ class ScriptObject : public ScriptValue { ...@@ -308,12 +308,12 @@ class ScriptObject : public ScriptValue {
virtual void dependencyThis(const Dependency& dep) { virtual void dependencyThis(const Dependency& dep) {
mark_dependency_value(*value, dep); mark_dependency_value(*value, dep);
} }
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const { virtual ScriptValueP makeIterator() const {
ScriptValueP it = make_iterator(*value); ScriptValueP it = make_iterator(*value);
if (it) return it; if (it) return it;
ScriptValueP d = getDefault(); ScriptValueP d = getDefault();
if (d) return d->makeIterator(d); if (d) return d->makeIterator();
return ScriptValue::makeIterator(thisP); return ScriptValue::makeIterator();
} }
virtual int itemCount() const { virtual int itemCount() const {
int i = item_count(*value); int i = item_count(*value);
......
...@@ -25,11 +25,11 @@ bool ScriptValue::toBool() const { throw Script ...@@ -25,11 +25,11 @@ bool ScriptValue::toBool() const { throw Script
double ScriptValue::toDouble() const { throw ScriptErrorConversion(typeName(), _TYPE_("double" )); } double ScriptValue::toDouble() const { throw ScriptErrorConversion(typeName(), _TYPE_("double" )); }
AColor ScriptValue::toColor() const { throw ScriptErrorConversion(typeName(), _TYPE_("color" )); } AColor ScriptValue::toColor() const { throw ScriptErrorConversion(typeName(), _TYPE_("color" )); }
wxDateTime ScriptValue::toDateTime() const { throw ScriptErrorConversion(typeName(), _TYPE_("date" )); } wxDateTime ScriptValue::toDateTime() const { throw ScriptErrorConversion(typeName(), _TYPE_("date" )); }
GeneratedImageP ScriptValue::toImage(const ScriptValueP&) const { throw ScriptErrorConversion(typeName(), _TYPE_("image" )); } GeneratedImageP ScriptValue::toImage() const { throw ScriptErrorConversion(typeName(), _TYPE_("image" )); }
String ScriptValue::toCode() const { return toString(); } String ScriptValue::toCode() const { return toString(); }
ScriptValueP ScriptValue::do_eval(Context&, bool) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function"))); } ScriptValueP ScriptValue::do_eval(Context&, bool) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function"))); }
ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); } ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("collection"))); } ScriptValueP ScriptValue::makeIterator() const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("collection"))); }
int ScriptValue::itemCount() const { throw ScriptErrorConversion(typeName(), _TYPE_("collection")); } int ScriptValue::itemCount() const { throw ScriptErrorConversion(typeName(), _TYPE_("collection")); }
CompareWhat ScriptValue::compareAs(String& compare_str, void const*& compare_ptr) const { CompareWhat ScriptValue::compareAs(String& compare_str, void const*& compare_ptr) const {
compare_str = toCode(); compare_str = toCode();
...@@ -75,8 +75,8 @@ bool equal(const ScriptValueP& a, const ScriptValueP& b) { ...@@ -75,8 +75,8 @@ bool equal(const ScriptValueP& a, const ScriptValueP& b) {
} else if (at == SCRIPT_COLLECTION && bt == SCRIPT_COLLECTION) { } else if (at == SCRIPT_COLLECTION && bt == SCRIPT_COLLECTION) {
// compare each element // compare each element
if (a->itemCount() != b->itemCount()) return false; if (a->itemCount() != b->itemCount()) return false;
ScriptValueP a_it = a->makeIterator(a); ScriptValueP a_it = a->makeIterator();
ScriptValueP b_it = b->makeIterator(b); ScriptValueP b_it = b->makeIterator();
while (true) { while (true) {
ScriptValueP a_v = a_it->next(); ScriptValueP a_v = a_it->next();
ScriptValueP b_v = b_it->next(); ScriptValueP b_v = b_it->next();
...@@ -111,11 +111,11 @@ bool ScriptDelayedError::toBool() const { throw error; } ...@@ -111,11 +111,11 @@ bool ScriptDelayedError::toBool() const { throw error; }
AColor ScriptDelayedError::toColor() const { throw error; } AColor ScriptDelayedError::toColor() const { throw error; }
int ScriptDelayedError::itemCount() const { throw error; } int ScriptDelayedError::itemCount() const { throw error; }
CompareWhat ScriptDelayedError::compareAs(String&, void const*&) const { throw error; } CompareWhat ScriptDelayedError::compareAs(String&, void const*&) const { throw error; }
ScriptValueP ScriptDelayedError::getMember(const String&) const { return intrusive(new ScriptDelayedError(error)); } ScriptValueP ScriptDelayedError::getMember(const String&) const { return intrusive_from_existing(const_cast<ScriptDelayedError*>(this)); }
ScriptValueP ScriptDelayedError::dependencyMember(const String&, const Dependency&) const { return intrusive(new ScriptDelayedError(error)); } ScriptValueP ScriptDelayedError::dependencyMember(const String&, const Dependency&) const { return intrusive_from_existing(const_cast<ScriptDelayedError*>(this)); }
ScriptValueP ScriptDelayedError::do_eval(Context&, bool) const { return intrusive(new ScriptDelayedError(error)); } ScriptValueP ScriptDelayedError::do_eval(Context&, bool) const { return intrusive_from_existing(const_cast<ScriptDelayedError*>(this)); }
ScriptValueP ScriptDelayedError::dependencies(Context&, const Dependency&) const { return intrusive(new ScriptDelayedError(error)); } ScriptValueP ScriptDelayedError::dependencies(Context&, const Dependency&) const { return intrusive_from_existing(const_cast<ScriptDelayedError*>(this)); }
ScriptValueP ScriptDelayedError::makeIterator(const ScriptValueP& thisP) const { return thisP; } ScriptValueP ScriptDelayedError::makeIterator() const { return intrusive_from_existing(const_cast<ScriptDelayedError*>(this)); }
// ----------------------------------------------------------------------------- : Iterators // ----------------------------------------------------------------------------- : Iterators
...@@ -123,7 +123,7 @@ ScriptValueP ScriptDelayedError::makeIterator(const ScriptValueP& thisP) const ...@@ -123,7 +123,7 @@ ScriptValueP ScriptDelayedError::makeIterator(const ScriptValueP& thisP) const
ScriptType ScriptIterator::type() const { return SCRIPT_ITERATOR; } ScriptType ScriptIterator::type() const { return SCRIPT_ITERATOR; }
String ScriptIterator::typeName() const { return _("iterator"); } String ScriptIterator::typeName() const { return _("iterator"); }
CompareWhat ScriptIterator::compareAs(String&, void const*&) const { return COMPARE_NO; } CompareWhat ScriptIterator::compareAs(String&, void const*&) const { return COMPARE_NO; }
ScriptValueP ScriptIterator::makeIterator(const ScriptValueP& thisP) const { return thisP; } ScriptValueP ScriptIterator::makeIterator() const { return intrusive_from_existing(const_cast<ScriptIterator*>(this)); }
// Iterator over a range of integers // Iterator over a range of integers
class ScriptRangeIterator : public ScriptIterator { class ScriptRangeIterator : public ScriptIterator {
...@@ -170,25 +170,11 @@ class ScriptInt : public ScriptValue { ...@@ -170,25 +170,11 @@ class ScriptInt : public ScriptValue {
int value; int value;
}; };
#if defined(USE_POOL_ALLOCATOR) && !defined(USE_INTRUSIVE_PTR)
// deallocation function for pool allocated integers
void destroy_value(ScriptInt* v) {
boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::free(v);
}
#endif
ScriptValueP to_script(int v) { ScriptValueP to_script(int v) {
#ifdef USE_POOL_ALLOCATOR #ifdef USE_POOL_ALLOCATOR
#ifdef USE_INTRUSIVE_PTR return intrusive(
return ScriptValueP( new(boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::malloc())
new(boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::malloc()) ScriptInt(v));
ScriptInt(v));
#else
return ScriptValueP(
new(boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::malloc())
ScriptInt(v),
destroy_value); // deallocation function
#endif
#else #else
return intrusive(new ScriptInt(v)); return intrusive(new ScriptInt(v));
#endif #endif
...@@ -284,7 +270,7 @@ class ScriptString : public ScriptValue { ...@@ -284,7 +270,7 @@ class ScriptString : public ScriptValue {
} }
return date; return date;
} }
virtual GeneratedImageP toImage(const ScriptValueP&) const { virtual GeneratedImageP toImage() const {
if (value.empty()) { if (value.empty()) {
return intrusive(new BlankImage()); return intrusive(new BlankImage());
} else { } else {
...@@ -367,7 +353,7 @@ class ScriptNil : public ScriptValue { ...@@ -367,7 +353,7 @@ class ScriptNil : public ScriptValue {
virtual double toDouble() const { return 0.0; } virtual double toDouble() const { return 0.0; }
virtual int toInt() const { return 0; } virtual int toInt() const { return 0; }
virtual bool toBool() const { return false; } virtual bool toBool() const { return false; }
virtual GeneratedImageP toImage(const ScriptValueP&) const { virtual GeneratedImageP toImage() const {
return intrusive(new BlankImage()); return intrusive(new BlankImage());
} }
...@@ -386,13 +372,7 @@ ScriptValueP script_nil(new ScriptNil); ...@@ -386,13 +372,7 @@ ScriptValueP script_nil(new ScriptNil);
String ScriptCollectionBase::toCode() const { String ScriptCollectionBase::toCode() const {
String ret = _("["); String ret = _("[");
bool first = true; bool first = true;
#ifdef USE_INTRUSIVE_PTR ScriptValueP it = makeIterator();
// we can just turn this into a ScriptValueP
// TODO: remove thisP alltogether
ScriptValueP it = makeIterator(ScriptValueP(const_cast<ScriptValue*>(static_cast<const ScriptValue*>(this))));
#else
#error "makeIterator needs a ScriptValueP :("
#endif
while (ScriptValueP v = it->next()) { while (ScriptValueP v = it->next()) {
if (!first) ret += _(","); if (!first) ret += _(",");
first = false; first = false;
...@@ -442,9 +422,9 @@ ScriptValueP ScriptCustomCollection::getIndex(int index) const { ...@@ -442,9 +422,9 @@ ScriptValueP ScriptCustomCollection::getIndex(int index) const {
return ScriptValue::getIndex(index); return ScriptValue::getIndex(index);
} }
} }
ScriptValueP ScriptCustomCollection::makeIterator(const ScriptValueP& thisP) const { ScriptValueP ScriptCustomCollection::makeIterator() const {
return intrusive(new ScriptCustomCollectionIterator( return intrusive(new ScriptCustomCollectionIterator(
static_pointer_cast<ScriptCustomCollection>(thisP) intrusive_from_existing(const_cast<ScriptCustomCollection*>(this))
)); ));
} }
...@@ -488,8 +468,8 @@ ScriptValueP ScriptConcatCollection::getIndex(int index) const { ...@@ -488,8 +468,8 @@ ScriptValueP ScriptConcatCollection::getIndex(int index) const {
return b->getIndex(index - itemsInA); return b->getIndex(index - itemsInA);
} }
} }
ScriptValueP ScriptConcatCollection::makeIterator(const ScriptValueP& thisP) const { ScriptValueP ScriptConcatCollection::makeIterator() const {
return intrusive(new ScriptConcatCollectionIterator(a->makeIterator(a), b->makeIterator(b))); return intrusive(new ScriptConcatCollectionIterator(a->makeIterator(), b->makeIterator()));
} }
// ----------------------------------------------------------------------------- : Default arguments / closure // ----------------------------------------------------------------------------- : Default arguments / closure
......
...@@ -73,7 +73,7 @@ class ScriptValue : public IntrusivePtrBaseWithDelete { ...@@ -73,7 +73,7 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
/// Convert this value to a wxDateTime /// Convert this value to a wxDateTime
virtual wxDateTime toDateTime() const; virtual wxDateTime toDateTime() const;
/// Convert this value to an image /// Convert this value to an image
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const; virtual GeneratedImageP toImage() const;
/// Get a member variable from this value /// Get a member variable from this value
virtual ScriptValueP getMember(const String& name) const; virtual ScriptValueP getMember(const String& name) const;
...@@ -101,8 +101,7 @@ class ScriptValue : public IntrusivePtrBaseWithDelete { ...@@ -101,8 +101,7 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
virtual ScriptValueP simplifyClosure(ScriptClosure&) const; virtual ScriptValueP simplifyClosure(ScriptClosure&) const;
/// Return an iterator for the current collection, an iterator is a value that has next() /// Return an iterator for the current collection, an iterator is a value that has next()
/** thisP can be used to prevent destruction of the collection */ virtual ScriptValueP makeIterator() const;
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
/// Return the next item for this iterator, or ScriptValueP() if there is no such item /// Return the next item for this iterator, or ScriptValueP() if there is no such item
/** If key_out != 0, then it will recieve the key of the item */ /** If key_out != 0, then it will recieve the key of the item */
virtual ScriptValueP next(ScriptValueP* key_out = nullptr); virtual ScriptValueP next(ScriptValueP* key_out = nullptr);
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <util/atomic.hpp> #include <util/atomic.hpp>
#ifdef HAVE_FAST_ATOMIC #ifndef HAVE_FAST_ATOMIC
/// Using intrusive_ptr where possible? (as opposed to smart_ptr) /// Using intrusive_ptr where possible? (as opposed to smart_ptr)
#define USE_INTRUSIVE_PTR #error Need fast atomic type for intrusive_ptr
#endif #endif
// Use slightly less fancy template stuff, so msvc7.1 doesn't crash with an internal compiler error // Use slightly less fancy template stuff, so msvc7.1 doesn't crash with an internal compiler error
...@@ -25,9 +25,7 @@ ...@@ -25,9 +25,7 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#ifdef USE_INTRUSIVE_PTR #include <boost/intrusive_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#endif
// Can't do using namespace boost; // Can't do using namespace boost;
// because boost::shared_ptr conflicts with std::tr1::shared_ptr // because boost::shared_ptr conflicts with std::tr1::shared_ptr
...@@ -62,107 +60,95 @@ inline shared_ptr<T> shared(T* ptr) { ...@@ -62,107 +60,95 @@ inline shared_ptr<T> shared(T* ptr) {
// ----------------------------------------------------------------------------- : Intrusive pointers // ----------------------------------------------------------------------------- : Intrusive pointers
#ifdef USE_INTRUSIVE_PTR /// Declares the type TypeP as a intrusive_ptr<Type>
#define DECLARE_POINTER_TYPE(Type) \
class Type; \
typedef intrusive_ptr<Type> Type##P;
/// Declares the type TypeP as a intrusive_ptr<Type> /// Wrap a newly allocated pointer in an intrusive_ptr
#define DECLARE_POINTER_TYPE(Type) \ /** Usage:
class Type; \ * return intrusive(new T(stuff)));
typedef intrusive_ptr<Type> Type##P; */
template <typename T>
inline intrusive_ptr<T> intrusive(T* ptr) {
assert(ptr && ptr->ref_count == 0);
return intrusive_ptr<T>(ptr);
}
/// Wrap a newly allocated pointer in an intrusive_ptr /// Wrap an existing pointer in an intrusive_ptr
/** Usage: /** Usage:
* return intrusive(new T(stuff))); * return intrusive_from_existing(this);
*/ */
template <typename T> template <typename T>
inline intrusive_ptr<T> intrusive(T* ptr) { inline intrusive_ptr<T> intrusive_from_existing(T* ptr) {
return intrusive_ptr<T>(ptr); assert(ptr && ptr->ref_count > 0);
return intrusive_ptr<T>(ptr);
}
// ----------------------------------------------------------------------------- : Intrusive pointer base
template <typename T> class IntrusivePtrBase;
template <typename T> void intrusive_ptr_add_ref(IntrusivePtrBase<T>*);
template <typename T> void intrusive_ptr_release(IntrusivePtrBase<T>*);
/// Base class for objects wishing to use intrusive_ptrs.
/** There is no implicit virtual destructor, objects are destructed as type T
* Usage:
* @code
* DECLARE_POINTER_TYPE(MyClass);
* class MyClass : public IntrusivePtrBase<MyClass> { ... }
* @endcode
*/
template <typename T> class IntrusivePtrBase {
public:
inline IntrusivePtrBase() : ref_count(0) {}
// don't copy construct the reference count!
inline IntrusivePtrBase(const IntrusivePtrBase&) : ref_count(0) {}
// don't assign the reference count!
inline void operator = (const IntrusivePtrBase&) { }
protected:
/// Delete this object, can be overloaded
inline void destroy() {
delete static_cast<T*>(this);
} }
private:
AtomicInt ref_count;
friend void intrusive_ptr_add_ref <> (IntrusivePtrBase*);
friend void intrusive_ptr_release <> (IntrusivePtrBase*);
template <typename U> friend intrusive_ptr<U> intrusive(U*);
template <typename U> friend intrusive_ptr<U> intrusive_from_existing(U*);
};
template <typename T> void intrusive_ptr_add_ref(IntrusivePtrBase<T>* p) {
++(p->ref_count);
}
// ----------------------------------------------------------------------------- : Intrusive pointer base template <typename T> void intrusive_ptr_release(IntrusivePtrBase<T>* p) {
if (--p->ref_count == 0) {
template <typename T> class IntrusivePtrBase; static_cast<T*>(p)->destroy();
template <typename T> void intrusive_ptr_add_ref(IntrusivePtrBase<T>*);
template <typename T> void intrusive_ptr_release(IntrusivePtrBase<T>*);
/// Base class for objects wishing to use intrusive_ptrs.
/** There is no implicit virtual destructor, objects are destructed as type T
* Usage:
* @code
* DECLARE_POINTER_TYPE(MyClass);
* class MyClass : public IntrusivePtrBase<MyClass> { ... }
* @endcode
*/
template <typename T> class IntrusivePtrBase {
public:
inline IntrusivePtrBase() : ref_count(0) {}
// don't copy construct the reference count!
inline IntrusivePtrBase(const IntrusivePtrBase&) : ref_count(0) {}
// don't assign the reference count!
inline void operator = (const IntrusivePtrBase&) { }
protected:
/// Delete this object, can be overloaded
inline void destroy() {
delete static_cast<T*>(this);
}
private:
AtomicInt ref_count;
friend void intrusive_ptr_add_ref <> (IntrusivePtrBase*);
friend void intrusive_ptr_release <> (IntrusivePtrBase*);
};
template <typename T> void intrusive_ptr_add_ref(IntrusivePtrBase<T>* p) {
++(p->ref_count);
} }
}
template <typename T> void intrusive_ptr_release(IntrusivePtrBase<T>* p) { // ----------------------------------------------------------------------------- : Intrusive pointer base : virtual
if (--p->ref_count == 0) {
static_cast<T*>(p)->destroy(); /// IntrusivePtrBase with a virtual destructor
} class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
public:
virtual ~IntrusivePtrVirtualBase() {}
};
// ----------------------------------------------------------------------------- : Intrusive pointer base : with delete
/// Base class for objects wishing to use intrusive_ptrs, using a manual delete function
class IntrusivePtrBaseWithDelete : public IntrusivePtrBase<IntrusivePtrBaseWithDelete> {
public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
delete this;
} }
// ----------------------------------------------------------------------------- : Intrusive pointer base : virtual template <typename T> friend void intrusive_ptr_release(IntrusivePtrBase<T>*);
};
/// IntrusivePtrBase with a virtual destructor
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
public:
virtual ~IntrusivePtrVirtualBase() {}
};
// ----------------------------------------------------------------------------- : Intrusive pointer base : with delete
/// Base class for objects wishing to use intrusive_ptrs, using a manual delete function
class IntrusivePtrBaseWithDelete : public IntrusivePtrBase<IntrusivePtrBaseWithDelete> {
public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
delete this;
}
template <typename T> friend void intrusive_ptr_release(IntrusivePtrBase<T>*);
};
#else
#define DECLARE_POINTER_TYPE DECLARE_SHARED_POINTER_TYPE
#define intrusive_ptr shared_ptr
template <typename T> class IntrusivePtrBase {};
/// IntrusivePtrBase with a virtual destructor
class IntrusivePtrVirtualBase : public IntrusivePtrBase<IntrusivePtrVirtualBase> {
public:
virtual ~IntrusivePtrVirtualBase() {}
};
class IntrusivePtrBaseWithDelete : public IntrusivePtrBase<IntrusivePtrBaseWithDelete> {
public:
virtual ~IntrusivePtrBaseWithDelete() {}
protected:
/// Delete this object
virtual void destroy() {
delete this;
}
};
#endif
/// Pointer to 'anything' /// Pointer to 'anything'
typedef intrusive_ptr<IntrusivePtrVirtualBase> VoidP; typedef intrusive_ptr<IntrusivePtrVirtualBase> VoidP;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment