+2006-02-02 Darin Adler <darin@apple.com>
+
+ Reviewed by Maciej.
+
+ - http://bugzilla.opendarwin.org/show_bug.cgi?id=7005
+ add Noncopyable, OwnPtr, OwnArrayPtr to KXMLCore
+
+ * kxmlcore/Noncopyable.h: Added.
+ * kxmlcore/OwnArrayPtr.h: Added.
+ * kxmlcore/OwnPtr.h: Added.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added new files.
+
+ * kjs/function.h:
+ * kjs/function.cpp: Use OwnPtr for Parameter pointers.
+
+ * kjs/internal.h: Use Noncopyable for LabelStack.
+
+ * kjs/list.cpp: Use OwnArrayPtr for overflow.
+
+ * kjs/property_map.h:
+ * kjs/property_map.cpp: Use OwnArrayPtr for SavedProperties.
+ Use Vector for some stack buffers.
+
+ * kjs/regexp_object.h:
+ * kjs/regexp_object.cpp: Use OwnArrayPtr for lastOvector.
+
2006-01-31 Maciej Stachowiak <mjs@apple.com>
Reviewed by Darin.
65E217C008E7EECC0023E5F6 /* FastMalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E217BA08E7EECC0023E5F6 /* FastMalloc.h */; settings = {ATTRIBUTES = (Private, ); }; };
65EA4C9B092AF9E20093D800 /* JSLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65EA4C99092AF9E20093D800 /* JSLock.cpp */; };
65EA4C9C092AF9E20093D800 /* JSLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EA4C9A092AF9E20093D800 /* JSLock.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9303F568099118FA00AD71B8 /* OwnPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F567099118FA00AD71B8 /* OwnPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9303F56A0991190000AD71B8 /* Noncopyable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5690991190000AD71B8 /* Noncopyable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9303F5A509911A5800AD71B8 /* OwnArrayPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
930754C108B0F68000AB3056 /* pcre_compile.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754BF08B0F68000AB3056 /* pcre_compile.c */; };
930754D008B0F74600AB3056 /* pcre_tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754CE08B0F74500AB3056 /* pcre_tables.c */; };
930754D308B0F76300AB3056 /* pcre_globals.c in Sources */ = {isa = PBXBuildFile; fileRef = 930754D108B0F76200AB3056 /* pcre_globals.c */; };
70B16A270569A10900DB756D /* runtime_object.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = runtime_object.h; path = bindings/runtime_object.h; sourceTree = "<group>"; tabWidth = 8; };
8442A376074175C2000AE2ED /* softlinking.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = softlinking.c; path = bindings/softlinking.c; sourceTree = "<group>"; tabWidth = 8; };
84ABF1DE070B628C00A3AC05 /* npruntime_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = npruntime_impl.h; path = bindings/npruntime_impl.h; sourceTree = "<group>"; tabWidth = 8; };
+ 9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; };
+ 9303F5690991190000AD71B8 /* Noncopyable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Noncopyable.h; sourceTree = "<group>"; };
+ 9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnArrayPtr.h; sourceTree = "<group>"; };
930754BF08B0F68000AB3056 /* pcre_compile.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_compile.c; path = pcre/pcre_compile.c; sourceTree = "<group>"; tabWidth = 8; };
930754CE08B0F74500AB3056 /* pcre_tables.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_tables.c; path = pcre/pcre_tables.c; sourceTree = "<group>"; tabWidth = 8; };
930754D108B0F76200AB3056 /* pcre_globals.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_globals.c; path = pcre/pcre_globals.c; sourceTree = "<group>"; tabWidth = 8; };
65162EF108E6A21C007556CD /* kxmlcore */ = {
isa = PBXGroup;
children = (
+ 9303F5690991190000AD71B8 /* Noncopyable.h */,
+ 9303F567099118FA00AD71B8 /* OwnPtr.h */,
+ 9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */,
6592C316098B7DE10003D4F6 /* Vector.h */,
6592C317098B7DE10003D4F6 /* VectorTraits.h */,
657EEBBF094E445E008C9C7B /* HashCountedSet.h */,
148A1627095D16BB00666D0D /* ListRefPtr.h in Headers */,
6592C318098B7DE10003D4F6 /* Vector.h in Headers */,
6592C319098B7DE10003D4F6 /* VectorTraits.h in Headers */,
+ 9303F568099118FA00AD71B8 /* OwnPtr.h in Headers */,
+ 9303F56A0991190000AD71B8 /* Noncopyable.h in Headers */,
+ 9303F5A509911A5800AD71B8 /* OwnArrayPtr.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
class Parameter {
public:
- Parameter(const Identifier &n) : name(n), next(0L) { }
- ~Parameter() { delete next; }
+ Parameter(const Identifier &n) : name(n) { }
Identifier name;
- Parameter *next;
+ OwnPtr<Parameter> next;
};
FunctionImp::FunctionImp(ExecState *exec, const Identifier &n)
FunctionImp::~FunctionImp()
{
- delete param;
}
bool FunctionImp::implementsCall() const
void FunctionImp::addParameter(const Identifier &n)
{
- Parameter **p = ¶m;
+ OwnPtr<Parameter> *p = ¶m;
while (*p)
p = &(*p)->next;
- *p = new Parameter(n);
+ p->set(new Parameter(n));
}
UString FunctionImp::parameterString() const
{
UString s;
- const Parameter *p = param;
+ const Parameter *p = param.get();
while (p) {
if (!s.isEmpty())
s += ", ";
s += p->name.ustring();
- p = p->next;
+ p = p->next.get();
}
return s;
if (param) {
ListIterator it = args.begin();
- Parameter *p = param;
+ Parameter *p = param.get();
JSValue *v = *it;
while (p) {
if (it != args.end()) {
v = ++it;
} else
variable->put(exec, p->name, jsUndefined());
- p = p->next;
+ p = p->next.get();
}
}
#ifdef KJS_VERBOSE
JSValue *FunctionImp::lengthGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
{
FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase());
- const Parameter *p = thisObj->param;
+ const Parameter *p = thisObj->param.get();
int count = 0;
while (p) {
++count;
- p = p->next;
+ p = p->next.get();
}
return jsNumber(count);
}
Identifier FunctionImp::getParameterName(int index)
{
int i = 0;
- Parameter *p = param;
+ Parameter *p = param.get();
if(!p)
return Identifier::null();
// skip to the parameter we want
- while (i++ < index && (p = p->next))
+ while (i++ < index && (p = p->next.get()))
;
if (!p)
Identifier name = p->name;
// Are there any subsequent parameters with the same name?
- while ((p = p->next))
+ while ((p = p->next.get()))
if (p->name == name)
return Identifier::null();
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
*
*/
-#ifndef _KJS_FUNCTION_H_
-#define _KJS_FUNCTION_H_
+#ifndef KJS_FUNCTION_H
+#define KJS_FUNCTION_H
-#include "internal.h"
#include "array_instance.h"
+#include "internal.h"
+#include <kxmlcore/OwnPtr.h>
namespace KJS {
virtual const ClassInfo *classInfo() const { return &info; }
static const ClassInfo info;
protected:
- Parameter *param;
+ OwnPtr<Parameter> param;
Identifier ident;
private:
#include "types.h"
#include "interpreter.h"
#include "scope_chain.h"
+#include <kxmlcore/Noncopyable.h>
#include <kxmlcore/RefPtr.h>
#define I18N_NOOP(s) s
/**
* @short The "label set" in Ecma-262 spec
*/
- class LabelStack {
+ class LabelStack : Noncopyable {
public:
- LabelStack(): tos(0L), iterationDepth(0), switchDepth(0) {}
+ LabelStack(): tos(0), iterationDepth(0), switchDepth(0) {}
~LabelStack();
/**
bool inSwitch() const { return (switchDepth > 0); }
private:
- LabelStack(const LabelStack &other);
- LabelStack &operator=(const LabelStack &other);
-
struct StackElem {
Identifier id;
StackElem *prev;
#include "internal.h"
#include <algorithm>
+#include <kxmlcore/OwnArrayPtr.h>
#define DUMP_STATISTICS 0
{
ListImpState state;
int capacity;
- JSValue **overflow;
+ OwnArrayPtr<JSValue*> overflow;
union {
JSValue *values[inlineValuesSize];
imp->refCount = 1;
imp->valueRefCount = 1;
imp->capacity = 0;
- imp->overflow = 0;
#if DUMP_STATISTICS
if (++numLists > numListsHighWaterMark)
numListsHighWaterMark = numLists;
imp->refCount = 1;
imp->valueRefCount = !needsMarking;
imp->capacity = 0;
- imp->overflow = 0;
#if DUMP_STATISTICS
if (++numLists > numListsHighWaterMark)
++numListsBiggerThan[i];
#endif
- delete [] imp->overflow;
+ imp->overflow.clear();
if (imp->state == usedInPool) {
imp->state = unusedInPool;
if (i >= imp->capacity) {
int newCapacity = i * 2;
- JSValue **newOverflow = new JSValue * [newCapacity - inlineValuesSize];
- JSValue **oldOverflow = imp->overflow;
+ OwnArrayPtr<JSValue*> newOverflow(new JSValue* [newCapacity - inlineValuesSize]);
+ JSValue** oldOverflow = imp->overflow.get();
int oldOverflowSize = i - inlineValuesSize;
for (int j = 0; j != oldOverflowSize; j++)
newOverflow[j] = oldOverflow[j];
- delete [] oldOverflow;
- imp->overflow = newOverflow;
+ imp->overflow.swap(newOverflow);
imp->capacity = newCapacity;
}
for (int i = 0; i != inlineSize; ++i)
append(imp->values[i]);
- JSValue **overflow = imp->overflow;
+ JSValue** overflow = imp->overflow.get();
int overflowSize = size - inlineSize;
for (int i = 0; i != overflowSize; ++i)
append(overflow[i]);
for (int i = 1; i < inlineSize; ++i)
copy.append(imp->values[i]);
- JSValue **overflow = imp->overflow;
+ JSValue** overflow = imp->overflow.get();
int overflowSize = size - inlineSize;
for (int i = 0; i < overflowSize; ++i)
copy.append(overflow[i]);
/*
* This file is part of the KDE libraries
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#include "config.h"
#include "property_map.h"
-#include <kxmlcore/FastMalloc.h>
#include "object.h"
#include "protect.h"
#include "reference_list.h"
-
#include <algorithm>
+#include <kxmlcore/FastMalloc.h>
+#include <kxmlcore/Vector.h>
using std::max;
int attributes;
};
-SavedProperties::SavedProperties() : _count(0), _properties(0) { }
-
-SavedProperties::~SavedProperties()
-{
- delete [] _properties;
-}
+SavedProperties::SavedProperties() : _count(0) { }
+SavedProperties::~SavedProperties() { }
// Algorithm concepts from Algorithms in C++, Sedgewick.
}
// Allocate a buffer to use to sort the keys.
- Entry *fixedSizeBuffer[smallMapThreshold];
- Entry **sortedEnumerables;
- if (_table->keyCount <= smallMapThreshold)
- sortedEnumerables = fixedSizeBuffer;
- else
- sortedEnumerables = new Entry *[_table->keyCount];
+ Vector<Entry*, smallMapThreshold> sortedEnumerables(_table->keyCount);
// Get pointers to the enumerable entries in the buffer.
- Entry **p = sortedEnumerables;
+ Entry** p = sortedEnumerables.data();
int size = _table->size;
- Entry *entries = _table->entries;
+ Entry* entries = _table->entries;
for (int i = 0; i != size; ++i) {
- Entry *e = &entries[i];
+ Entry* e = &entries[i];
if (e->key && !(e->attributes & DontEnum))
*p++ = e;
}
// Sort the entries by index.
- qsort(sortedEnumerables, p - sortedEnumerables, sizeof(sortedEnumerables[0]), comparePropertyMapEntryIndices);
+ qsort(sortedEnumerables.data(), p - sortedEnumerables.data(), sizeof(Entry*), comparePropertyMapEntryIndices);
// Put the keys of the sorted entries into the reference list.
- Entry **q = sortedEnumerables;
- while (q != p)
- list.append(Reference(base, Identifier((*q++)->key)));
-
- // Deallocate the buffer.
- if (sortedEnumerables != fixedSizeBuffer)
- delete [] sortedEnumerables;
+ for (Entry** q = sortedEnumerables.data(); q != p; ++q)
+ list.append(Reference(base, Identifier((*q)->key)));
}
void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, JSObject *base) const
++count;
}
- delete [] p._properties;
-
+ p._properties.clear();
p._count = count;
- if (count == 0) {
- p._properties = 0;
+ if (count == 0)
return;
- }
- p._properties = new SavedProperty [count];
+ p._properties.set(new SavedProperty [count]);
- SavedProperty *prop = p._properties;
+ SavedProperty *prop = p._properties.get();
if (!_table) {
#if USE_SINGLE_ENTRY
// Another possibility would be to save the indices.
// Allocate a buffer to use to sort the keys.
- Entry *fixedSizeBuffer[smallMapThreshold];
- Entry **sortedEntries;
- if (count <= smallMapThreshold)
- sortedEntries = fixedSizeBuffer;
- else
- sortedEntries = new Entry *[count];
+ Vector<Entry*, smallMapThreshold> sortedEntries(count);
// Get pointers to the entries in the buffer.
- Entry **p = sortedEntries;
+ Entry** p = sortedEntries.data();
int size = _table->size;
- Entry *entries = _table->entries;
+ Entry* entries = _table->entries;
for (int i = 0; i != size; ++i) {
Entry *e = &entries[i];
if (e->key && !(e->attributes & (ReadOnly | Function)))
*p++ = e;
}
- assert(p - sortedEntries == count);
+ assert(p - sortedEntries.data() == count);
// Sort the entries by index.
- qsort(sortedEntries, p - sortedEntries, sizeof(sortedEntries[0]), comparePropertyMapEntryIndices);
+ qsort(sortedEntries.data(), p - sortedEntries.data(), sizeof(Entry*), comparePropertyMapEntryIndices);
// Put the sorted entries into the saved properties list.
- Entry **q = sortedEntries;
- while (q != p) {
- Entry *e = *q++;
+ for (Entry** q = sortedEntries.data(); q != p; ++q, ++prop) {
+ Entry* e = *q;
prop->key = Identifier(e->key);
prop->value = e->value;
prop->attributes = e->attributes;
- ++prop;
}
-
- // Deallocate the buffer.
- if (sortedEntries != fixedSizeBuffer)
- delete [] sortedEntries;
}
}
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
*
*/
-#ifndef _KJS_PROPERTY_MAP_H_
-#define _KJS_PROPERTY_MAP_H_
+#ifndef KJS_PROPERTY_MAP_H_
+#define KJS_PROPERTY_MAP_H_
#include "identifier.h"
+#include <kxmlcore/OwnArrayPtr.h>
namespace KJS {
private:
int _count;
- SavedProperty *_properties;
-
- SavedProperties(const SavedProperties&);
- SavedProperties& operator=(const SavedProperties&);
+ OwnArrayPtr<SavedProperty> _properties;
};
/**
short globalGetterSetterFlag;
int index;
};
+
/**
* Javascript Property Map.
*/
-
class PropertyMap {
public:
PropertyMap();
FunctionPrototype *funcProto,
RegExpPrototype *regProto)
- : InternalFunctionImp(funcProto), multiline(false), lastInput(""), lastOvector(0), lastNumSubPatterns(0)
+ : InternalFunctionImp(funcProto), multiline(false), lastInput(""), lastNumSubPatterns(0)
{
// ECMA 15.10.5.1 RegExp.prototype
putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
putDirect(lengthPropertyName, jsNumber(2), ReadOnly|DontDelete|DontEnum);
}
-RegExpObjectImp::~RegExpObjectImp()
-{
- delete [] lastOvector;
-}
-
/*
To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
expression matching through the performMatch function. We use cached results to calculate,
*ovector = tmpOvector;
if (!match.isNull()) {
- assert(tmpOvector);
+ ASSERT(tmpOvector);
lastInput = s;
- delete [] lastOvector;
- lastOvector = tmpOvector;
+ lastOvector.set(tmpOvector);
lastNumSubPatterns = r->subPatterns();
}
{
int i = lastNumSubPatterns;
if (i > 0) {
- assert(lastOvector);
+ ASSERT(lastOvector);
UString substring = lastInput.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i]);
return jsString(substring);
}
case RightContext:
return getRightContext();
default:
- assert(0);
+ ASSERT(0);
}
return jsString("");
multiline = value->toBoolean(exec);
break;
default:
- assert(0);
+ ASSERT(0);
}
}
#include "internal.h"
#include "function_object.h"
#include "regexp.h"
+#include <kxmlcore/OwnArrayPtr.h>
namespace KJS {
class ExecState;
RegExpObjectImp(ExecState *exec,
FunctionPrototype *funcProto,
RegExpPrototype *regProto);
- virtual ~RegExpObjectImp();
virtual bool implementsConstruct() const;
virtual JSObject *construct(ExecState *exec, const List &args);
virtual bool implementsCall() const;
// Global search cache / settings
bool multiline;
UString lastInput;
- int *lastOvector;
+ OwnArrayPtr<int> lastOvector;
unsigned lastNumSubPatterns;
static const ClassInfo info;
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KXMLCORE_NONCOPYABLE
+#define KXMLCORE_NONCOPYABLE
+
+// We don't want argument-dependent lookup to pull in everything from the KXMLCore
+// namespace when you use Noncopyable, so put it in its own namespace.
+
+namespace KXMLCoreNoncopyable {
+
+ class Noncopyable {
+ Noncopyable(const Noncopyable&);
+ Noncopyable& operator=(const Noncopyable&);
+ protected:
+ Noncopyable() { }
+ ~Noncopyable() { }
+ };
+
+} // namespace KXMLCoreNoncopyable
+
+using KXMLCoreNoncopyable::Noncopyable;
+
+#endif // KXMLCORE_NONCOPYABLE
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KXMLCORE_OWN_ARRAY_PTR_H
+#define KXMLCORE_OWN_ARRAY_PTR_H
+
+#include <algorithm>
+#include <kxmlcore/Assertions.h>
+#include <kxmlcore/Noncopyable.h>
+
+namespace KXMLCore {
+
+ template <typename T> class OwnArrayPtr : Noncopyable {
+ public:
+ explicit OwnArrayPtr(T* ptr = 0) : m_ptr(ptr) { }
+ ~OwnArrayPtr() { safeDelete(); }
+
+ T* get() const { return m_ptr; }
+ T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; }
+
+ void set(T* ptr) { ASSERT(m_ptr != ptr); safeDelete(); m_ptr = ptr; }
+ void clear() { safeDelete(); m_ptr = 0; }
+
+ T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
+ T* operator->() const { ASSERT(m_ptr); return m_ptr; }
+
+ T& operator[](std::ptrdiff_t i) const { ASSERT(m_ptr); ASSERT(i >= 0); return m_ptr[i]; }
+
+ bool operator!() const { return !m_ptr; }
+
+ // This conversion operator allows implicit conversion to bool but not to other integer types.
+ typedef T* (OwnArrayPtr::*UnspecifiedBoolType)() const;
+ operator UnspecifiedBoolType() const { return m_ptr ? &OwnArrayPtr::get : 0; }
+
+ void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); }
+
+ private:
+ void safeDelete() { typedef char known[sizeof(T) ? 1 : -1]; if (sizeof(known)) delete [] m_ptr; }
+
+ T* m_ptr;
+ };
+
+ template <typename T> inline void swap(OwnArrayPtr<T>& a, OwnArrayPtr<T>& b) { a.swap(b); }
+
+} // namespace KXMLCore
+
+using KXMLCore::OwnArrayPtr;
+
+#endif // KXMLCORE_OWN_ARRAY_PTR_H
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KXMLCORE_OWN_PTR_H
+#define KXMLCORE_OWN_PTR_H
+
+#include <algorithm>
+#include <kxmlcore/Assertions.h>
+#include <kxmlcore/Noncopyable.h>
+
+namespace KXMLCore {
+
+ template <typename T> class OwnPtr : Noncopyable {
+ public:
+ explicit OwnPtr(T* ptr = 0) : m_ptr(ptr) { }
+ ~OwnPtr() { safeDelete(); }
+
+ T* get() const { return m_ptr; }
+ T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; }
+
+ void set(T* ptr) { ASSERT(m_ptr != ptr); safeDelete(); m_ptr = ptr; }
+ void clear() { safeDelete(); m_ptr = 0; }
+
+ T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
+ T* operator->() const { ASSERT(m_ptr); return m_ptr; }
+
+ bool operator!() const { return !m_ptr; }
+
+ // This conversion operator allows implicit conversion to bool but not to other integer types.
+ typedef T* (OwnPtr::*UnspecifiedBoolType)() const;
+ operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::get : 0; }
+
+ void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
+
+ private:
+ void safeDelete() { typedef char known[sizeof(T) ? 1 : -1]; if (sizeof(known)) delete m_ptr; }
+
+ T* m_ptr;
+ };
+
+ template <typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) { a.swap(b); }
+
+} // namespace KXMLCore
+
+using KXMLCore::OwnPtr;
+
+#endif // KXMLCORE_OWN_PTR_H