blob: ece97d2fdc0766feaea8c7330aa2adc8ae4d2f67 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <stddef.h>
#include <stdio.h>
class AShared;
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// AWeakRefData //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
struct AWeakRefData
{
AWeakRefData(void *_back) : ptr(NULL), prev(NULL), next(NULL), back(_back) { }
AShared *ptr;
AWeakRefData *prev;
AWeakRefData *next;
void *back;
};
struct AWeakRefDataList
{
AWeakRefDataList() : first(NULL), last(NULL) { }
AWeakRefData *first;
AWeakRefData *last;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// AShared //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
class AShared
{
public:
AShared();
virtual ~AShared();
void ref() { _refCount++; }
void deref() { _refCount--; if (_refCount == 0) delete this; }
int refCount() const { return _refCount; }
void addWeakRef(AWeakRefData *ref);
void removeWeakRef(AWeakRefData *ref);
int weakRefCount() const;
private:
int _refCount;
AWeakRefDataList _weakRefs;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// ARef //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
template <class T>
class ARef
{
public:
ARef() : _ptr(NULL) { }
ARef(T *ptr) : _ptr(NULL) { setPtr(ptr); }
ARef(const ARef<T> &other) : _ptr(NULL) { setPtr(other._ptr); }
~ARef() { setPtr(NULL); }
ARef<T> &operator=(const ARef<T> &other) {
setPtr(other._ptr);
return *this;
}
T &operator*() const { return *_ptr; }
T *operator->() const { return _ptr; }
T *ptr() const { return _ptr; }
bool isNull() const { return (_ptr == NULL); }
void setPtr(T *newPtr) {
T *oldPtr = _ptr;
if (newPtr != NULL)
newPtr->ref();
if (oldPtr != NULL)
oldPtr->deref();
_ptr = newPtr;
}
private:
T *_ptr;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// AWeakRef //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
class AWeakRef
{
public:
AWeakRef() : _data(this) { }
AWeakRef(T *ptr) : _data(this) { setPtr(ptr); }
AWeakRef(const AWeakRef<T> &other) : _data(this) { setPtr(other._data.ptr); }
~AWeakRef() { setPtr(NULL); }
AWeakRef &operator=(const AWeakRef<T> &other) {
setPtr(other._data.ptr);
return *this;
}
T &operator*() const { return *(static_cast<T*>(_data.ptr)); }
T *operator->() const { return static_cast<T*>(_data.ptr); }
T *ptr() const { return static_cast<T*>(_data.ptr); }
bool isNull() const { return (_data.ptr == NULL); }
void setPtr(AShared *newPtr) {
AShared *oldPtr = _data.ptr;
if (oldPtr != NULL)
oldPtr->removeWeakRef(&_data);
if (newPtr != NULL)
newPtr->addWeakRef(&_data);
_data.ptr = newPtr;
}
private:
AWeakRefData _data;
};