10b575de8ed0b628d84d256f5846500b0385979bdTim Murray/*
20b575de8ed0b628d84d256f5846500b0385979bdTim Murray * Copyright (C) 2013 The Android Open Source Project
30b575de8ed0b628d84d256f5846500b0385979bdTim Murray *
40b575de8ed0b628d84d256f5846500b0385979bdTim Murray * Licensed under the Apache License, Version 2.0 (the "License");
50b575de8ed0b628d84d256f5846500b0385979bdTim Murray * you may not use this file except in compliance with the License.
60b575de8ed0b628d84d256f5846500b0385979bdTim Murray * You may obtain a copy of the License at
70b575de8ed0b628d84d256f5846500b0385979bdTim Murray *
80b575de8ed0b628d84d256f5846500b0385979bdTim Murray *      http://www.apache.org/licenses/LICENSE-2.0
90b575de8ed0b628d84d256f5846500b0385979bdTim Murray *
100b575de8ed0b628d84d256f5846500b0385979bdTim Murray * Unless required by applicable law or agreed to in writing, software
110b575de8ed0b628d84d256f5846500b0385979bdTim Murray * distributed under the License is distributed on an "AS IS" BASIS,
120b575de8ed0b628d84d256f5846500b0385979bdTim Murray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b575de8ed0b628d84d256f5846500b0385979bdTim Murray * See the License for the specific language governing permissions and
140b575de8ed0b628d84d256f5846500b0385979bdTim Murray * limitations under the License.
150b575de8ed0b628d84d256f5846500b0385979bdTim Murray */
160b575de8ed0b628d84d256f5846500b0385979bdTim Murray
170b575de8ed0b628d84d256f5846500b0385979bdTim Murray#ifndef ANDROID_REF_BASE_H
180b575de8ed0b628d84d256f5846500b0385979bdTim Murray#define ANDROID_REF_BASE_H
190b575de8ed0b628d84d256f5846500b0385979bdTim Murray
200b575de8ed0b628d84d256f5846500b0385979bdTim Murray
210b575de8ed0b628d84d256f5846500b0385979bdTim Murray#include <stdint.h>
220b575de8ed0b628d84d256f5846500b0385979bdTim Murray#include <sys/types.h>
230b575de8ed0b628d84d256f5846500b0385979bdTim Murray#include <stdlib.h>
240b575de8ed0b628d84d256f5846500b0385979bdTim Murray#include <string.h>
250b575de8ed0b628d84d256f5846500b0385979bdTim Murray
260b575de8ed0b628d84d256f5846500b0385979bdTim Murray#include "StrongPointer.h"
270b575de8ed0b628d84d256f5846500b0385979bdTim Murray#include "TypeHelpers.h"
280b575de8ed0b628d84d256f5846500b0385979bdTim Murray
290b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
300b575de8ed0b628d84d256f5846500b0385979bdTim Murraynamespace android {
310b575de8ed0b628d84d256f5846500b0385979bdTim Murray
320b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass TextOutput;
330b575de8ed0b628d84d256f5846500b0385979bdTim MurrayTextOutput& printWeakPointer(TextOutput& to, const void* val);
340b575de8ed0b628d84d256f5846500b0385979bdTim Murray
350b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
360b575de8ed0b628d84d256f5846500b0385979bdTim Murray
370b575de8ed0b628d84d256f5846500b0385979bdTim Murray#define COMPARE_WEAK(_op_)                                      \
380b575de8ed0b628d84d256f5846500b0385979bdTim Murrayinline bool operator _op_ (const sp<T>& o) const {              \
390b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return m_ptr _op_ o.m_ptr;                                  \
400b575de8ed0b628d84d256f5846500b0385979bdTim Murray}                                                               \
410b575de8ed0b628d84d256f5846500b0385979bdTim Murrayinline bool operator _op_ (const T* o) const {                  \
420b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return m_ptr _op_ o;                                        \
430b575de8ed0b628d84d256f5846500b0385979bdTim Murray}                                                               \
440b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename U>                                            \
450b575de8ed0b628d84d256f5846500b0385979bdTim Murrayinline bool operator _op_ (const sp<U>& o) const {              \
460b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return m_ptr _op_ o.m_ptr;                                  \
470b575de8ed0b628d84d256f5846500b0385979bdTim Murray}                                                               \
480b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename U>                                            \
490b575de8ed0b628d84d256f5846500b0385979bdTim Murrayinline bool operator _op_ (const U* o) const {                  \
500b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return m_ptr _op_ o;                                        \
510b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
520b575de8ed0b628d84d256f5846500b0385979bdTim Murray
530b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
540b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass ReferenceMover;
550b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass ReferenceConverterBase {
560b575de8ed0b628d84d256f5846500b0385979bdTim Murraypublic:
570b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual size_t getReferenceTypeSize() const = 0;
580b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual void* getReferenceBase(void const*) const = 0;
590b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline virtual ~ReferenceConverterBase() { }
600b575de8ed0b628d84d256f5846500b0385979bdTim Murray};
610b575de8ed0b628d84d256f5846500b0385979bdTim Murray
620b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
630b575de8ed0b628d84d256f5846500b0385979bdTim Murray
640b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass RefBase
650b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
660b575de8ed0b628d84d256f5846500b0385979bdTim Murraypublic:
670b575de8ed0b628d84d256f5846500b0385979bdTim Murray            void            incStrong(const void* id) const;
680b575de8ed0b628d84d256f5846500b0385979bdTim Murray            void            decStrong(const void* id) const;
690b575de8ed0b628d84d256f5846500b0385979bdTim Murray
700b575de8ed0b628d84d256f5846500b0385979bdTim Murray            void            forceIncStrong(const void* id) const;
710b575de8ed0b628d84d256f5846500b0385979bdTim Murray
720b575de8ed0b628d84d256f5846500b0385979bdTim Murray            //! DEBUGGING ONLY: Get current strong ref count.
730b575de8ed0b628d84d256f5846500b0385979bdTim Murray            int32_t         getStrongCount() const;
740b575de8ed0b628d84d256f5846500b0385979bdTim Murray
750b575de8ed0b628d84d256f5846500b0385979bdTim Murray    class weakref_type
760b575de8ed0b628d84d256f5846500b0385979bdTim Murray    {
770b575de8ed0b628d84d256f5846500b0385979bdTim Murray    public:
780b575de8ed0b628d84d256f5846500b0385979bdTim Murray        RefBase*            refBase() const;
790b575de8ed0b628d84d256f5846500b0385979bdTim Murray
800b575de8ed0b628d84d256f5846500b0385979bdTim Murray        void                incWeak(const void* id);
810b575de8ed0b628d84d256f5846500b0385979bdTim Murray        void                decWeak(const void* id);
820b575de8ed0b628d84d256f5846500b0385979bdTim Murray
830b575de8ed0b628d84d256f5846500b0385979bdTim Murray        // acquires a strong reference if there is already one.
840b575de8ed0b628d84d256f5846500b0385979bdTim Murray        bool                attemptIncStrong(const void* id);
850b575de8ed0b628d84d256f5846500b0385979bdTim Murray
860b575de8ed0b628d84d256f5846500b0385979bdTim Murray        // acquires a weak reference if there is already one.
870b575de8ed0b628d84d256f5846500b0385979bdTim Murray        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
880b575de8ed0b628d84d256f5846500b0385979bdTim Murray        // for proper use.
890b575de8ed0b628d84d256f5846500b0385979bdTim Murray        bool                attemptIncWeak(const void* id);
900b575de8ed0b628d84d256f5846500b0385979bdTim Murray
910b575de8ed0b628d84d256f5846500b0385979bdTim Murray        //! DEBUGGING ONLY: Get current weak ref count.
920b575de8ed0b628d84d256f5846500b0385979bdTim Murray        int32_t             getWeakCount() const;
930b575de8ed0b628d84d256f5846500b0385979bdTim Murray
940b575de8ed0b628d84d256f5846500b0385979bdTim Murray        //! DEBUGGING ONLY: Print references held on object.
950b575de8ed0b628d84d256f5846500b0385979bdTim Murray        void                printRefs() const;
960b575de8ed0b628d84d256f5846500b0385979bdTim Murray
970b575de8ed0b628d84d256f5846500b0385979bdTim Murray        //! DEBUGGING ONLY: Enable tracking for this object.
980b575de8ed0b628d84d256f5846500b0385979bdTim Murray        // enable -- enable/disable tracking
990b575de8ed0b628d84d256f5846500b0385979bdTim Murray        // retain -- when tracking is enable, if true, then we save a stack trace
1000b575de8ed0b628d84d256f5846500b0385979bdTim Murray        //           for each reference and dereference; when retain == false, we
1010b575de8ed0b628d84d256f5846500b0385979bdTim Murray        //           match up references and dereferences and keep only the
1020b575de8ed0b628d84d256f5846500b0385979bdTim Murray        //           outstanding ones.
1030b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1040b575de8ed0b628d84d256f5846500b0385979bdTim Murray        void                trackMe(bool enable, bool retain);
1050b575de8ed0b628d84d256f5846500b0385979bdTim Murray    };
1060b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1070b575de8ed0b628d84d256f5846500b0385979bdTim Murray            weakref_type*   createWeak(const void* id) const;
1080b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1090b575de8ed0b628d84d256f5846500b0385979bdTim Murray            weakref_type*   getWeakRefs() const;
1100b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1110b575de8ed0b628d84d256f5846500b0385979bdTim Murray            //! DEBUGGING ONLY: Print references held on object.
1120b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline  void            printRefs() const { getWeakRefs()->printRefs(); }
1130b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1140b575de8ed0b628d84d256f5846500b0385979bdTim Murray            //! DEBUGGING ONLY: Enable tracking of object.
1150b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline  void            trackMe(bool enable, bool retain)
1160b575de8ed0b628d84d256f5846500b0385979bdTim Murray    {
1170b575de8ed0b628d84d256f5846500b0385979bdTim Murray        getWeakRefs()->trackMe(enable, retain);
1180b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
1190b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1200b575de8ed0b628d84d256f5846500b0385979bdTim Murray    typedef RefBase basetype;
1210b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1220b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprotected:
1230b575de8ed0b628d84d256f5846500b0385979bdTim Murray                            RefBase();
1240b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual                 ~RefBase();
1250b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1260b575de8ed0b628d84d256f5846500b0385979bdTim Murray    //! Flags for extendObjectLifetime()
1270b575de8ed0b628d84d256f5846500b0385979bdTim Murray    enum {
1280b575de8ed0b628d84d256f5846500b0385979bdTim Murray        OBJECT_LIFETIME_STRONG  = 0x0000,
1290b575de8ed0b628d84d256f5846500b0385979bdTim Murray        OBJECT_LIFETIME_WEAK    = 0x0001,
1300b575de8ed0b628d84d256f5846500b0385979bdTim Murray        OBJECT_LIFETIME_MASK    = 0x0001
1310b575de8ed0b628d84d256f5846500b0385979bdTim Murray    };
1320b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1330b575de8ed0b628d84d256f5846500b0385979bdTim Murray            void            extendObjectLifetime(int32_t mode);
1340b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1350b575de8ed0b628d84d256f5846500b0385979bdTim Murray    //! Flags for onIncStrongAttempted()
1360b575de8ed0b628d84d256f5846500b0385979bdTim Murray    enum {
1370b575de8ed0b628d84d256f5846500b0385979bdTim Murray        FIRST_INC_STRONG = 0x0001
1380b575de8ed0b628d84d256f5846500b0385979bdTim Murray    };
1390b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1400b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual void            onFirstRef();
1410b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual void            onLastStrongRef(const void* id);
1420b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
1430b575de8ed0b628d84d256f5846500b0385979bdTim Murray    virtual void            onLastWeakRef(const void* id);
1440b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1450b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprivate:
1460b575de8ed0b628d84d256f5846500b0385979bdTim Murray    friend class ReferenceMover;
1470b575de8ed0b628d84d256f5846500b0385979bdTim Murray    static void moveReferences(void* d, void const* s, size_t n,
1480b575de8ed0b628d84d256f5846500b0385979bdTim Murray            const ReferenceConverterBase& caster);
1490b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1500b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprivate:
1510b575de8ed0b628d84d256f5846500b0385979bdTim Murray    friend class weakref_type;
1520b575de8ed0b628d84d256f5846500b0385979bdTim Murray    class weakref_impl;
1530b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1540b575de8ed0b628d84d256f5846500b0385979bdTim Murray                            RefBase(const RefBase& o);
1550b575de8ed0b628d84d256f5846500b0385979bdTim Murray            RefBase&        operator=(const RefBase& o);
1560b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1570b575de8ed0b628d84d256f5846500b0385979bdTim Murray        weakref_impl* const mRefs;
1580b575de8ed0b628d84d256f5846500b0385979bdTim Murray};
1590b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1600b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
1610b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1620b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate <class T>
1630b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass LightRefBase
1640b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
1650b575de8ed0b628d84d256f5846500b0385979bdTim Murraypublic:
1660b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline LightRefBase() : mCount(0) { }
1670b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline void incStrong(__attribute__((unused)) const void* id) const {
1680b575de8ed0b628d84d256f5846500b0385979bdTim Murray        __sync_fetch_and_add(&mCount, 1);
1690b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
1700b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline void decStrong(__attribute__((unused)) const void* id) const {
1710b575de8ed0b628d84d256f5846500b0385979bdTim Murray        if (__sync_fetch_and_sub(&mCount, 1) == 1) {
1720b575de8ed0b628d84d256f5846500b0385979bdTim Murray            delete static_cast<const T*>(this);
1730b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
1740b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
1750b575de8ed0b628d84d256f5846500b0385979bdTim Murray    //! DEBUGGING ONLY: Get current strong ref count.
1760b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline int32_t getStrongCount() const {
1770b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return mCount;
1780b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
1790b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1800b575de8ed0b628d84d256f5846500b0385979bdTim Murray    typedef LightRefBase<T> basetype;
1810b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1820b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprotected:
1830b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline ~LightRefBase() { }
1840b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1850b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprivate:
1860b575de8ed0b628d84d256f5846500b0385979bdTim Murray    friend class ReferenceMover;
1870b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline static void moveReferences(void* d, void const* s, size_t n,
1880b575de8ed0b628d84d256f5846500b0385979bdTim Murray            const ReferenceConverterBase& caster) { }
1890b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1900b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprivate:
1910b575de8ed0b628d84d256f5846500b0385979bdTim Murray    mutable volatile int32_t mCount;
1920b575de8ed0b628d84d256f5846500b0385979bdTim Murray};
1930b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1940b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
1950b575de8ed0b628d84d256f5846500b0385979bdTim Murray
1960b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate <typename T>
1970b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass wp
1980b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
1990b575de8ed0b628d84d256f5846500b0385979bdTim Murraypublic:
2000b575de8ed0b628d84d256f5846500b0385979bdTim Murray    typedef typename RefBase::weakref_type weakref_type;
2010b575de8ed0b628d84d256f5846500b0385979bdTim Murray
20244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    inline wp() : m_ptr(nullptr) { }
2030b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2040b575de8ed0b628d84d256f5846500b0385979bdTim Murray    wp(T* other);
2050b575de8ed0b628d84d256f5846500b0385979bdTim Murray    wp(const wp<T>& other);
2060b575de8ed0b628d84d256f5846500b0385979bdTim Murray    wp(const sp<T>& other);
2070b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> wp(U* other);
2080b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> wp(const sp<U>& other);
2090b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> wp(const wp<U>& other);
2100b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2110b575de8ed0b628d84d256f5846500b0385979bdTim Murray    ~wp();
2120b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2130b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // Assignment
2140b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2150b575de8ed0b628d84d256f5846500b0385979bdTim Murray    wp& operator = (T* other);
2160b575de8ed0b628d84d256f5846500b0385979bdTim Murray    wp& operator = (const wp<T>& other);
2170b575de8ed0b628d84d256f5846500b0385979bdTim Murray    wp& operator = (const sp<T>& other);
2180b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2190b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> wp& operator = (U* other);
2200b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> wp& operator = (const wp<U>& other);
2210b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> wp& operator = (const sp<U>& other);
2220b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2230b575de8ed0b628d84d256f5846500b0385979bdTim Murray    void set_object_and_refs(T* other, weakref_type* refs);
2240b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2250b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // promotion to sp
2260b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2270b575de8ed0b628d84d256f5846500b0385979bdTim Murray    sp<T> promote() const;
2280b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2290b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // Reset
2300b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2310b575de8ed0b628d84d256f5846500b0385979bdTim Murray    void clear();
2320b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2330b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // Accessors
2340b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2350b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline  weakref_type* get_refs() const { return m_refs; }
2360b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2370b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline  T* unsafe_get() const { return m_ptr; }
2380b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2390b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // Operators
2400b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2410b575de8ed0b628d84d256f5846500b0385979bdTim Murray    COMPARE_WEAK(==)
2420b575de8ed0b628d84d256f5846500b0385979bdTim Murray    COMPARE_WEAK(!=)
2430b575de8ed0b628d84d256f5846500b0385979bdTim Murray    COMPARE_WEAK(>)
2440b575de8ed0b628d84d256f5846500b0385979bdTim Murray    COMPARE_WEAK(<)
2450b575de8ed0b628d84d256f5846500b0385979bdTim Murray    COMPARE_WEAK(<=)
2460b575de8ed0b628d84d256f5846500b0385979bdTim Murray    COMPARE_WEAK(>=)
2470b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2480b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline bool operator == (const wp<T>& o) const {
2490b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
2500b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
2510b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U>
2520b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline bool operator == (const wp<U>& o) const {
2530b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return m_ptr == o.m_ptr;
2540b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
2550b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2560b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline bool operator > (const wp<T>& o) const {
2570b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
2580b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
2590b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U>
2600b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline bool operator > (const wp<U>& o) const {
2610b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
2620b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
2630b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2640b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline bool operator < (const wp<T>& o) const {
2650b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
2660b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
2670b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U>
2680b575de8ed0b628d84d256f5846500b0385979bdTim Murray    inline bool operator < (const wp<U>& o) const {
2690b575de8ed0b628d84d256f5846500b0385979bdTim Murray        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
2700b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
2710b575de8ed0b628d84d256f5846500b0385979bdTim Murray                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
2720b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
2730b575de8ed0b628d84d256f5846500b0385979bdTim Murray                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
2740b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
2750b575de8ed0b628d84d256f5846500b0385979bdTim Murray                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
2760b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
2770b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2780b575de8ed0b628d84d256f5846500b0385979bdTim Murrayprivate:
2790b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename Y> friend class sp;
2800b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename Y> friend class wp;
2810b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2820b575de8ed0b628d84d256f5846500b0385979bdTim Murray    T*              m_ptr;
2830b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type*   m_refs;
2840b575de8ed0b628d84d256f5846500b0385979bdTim Murray};
2850b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2860b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate <typename T>
2870b575de8ed0b628d84d256f5846500b0385979bdTim MurrayTextOutput& operator<<(TextOutput& to, const wp<T>& val);
2880b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2890b575de8ed0b628d84d256f5846500b0385979bdTim Murray#undef COMPARE_WEAK
2900b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2910b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
2920b575de8ed0b628d84d256f5846500b0385979bdTim Murray// No user serviceable parts below here.
2930b575de8ed0b628d84d256f5846500b0385979bdTim Murray
2940b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
2950b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::wp(T* other)
2960b575de8ed0b628d84d256f5846500b0385979bdTim Murray    : m_ptr(other)
2970b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
2980b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (other) m_refs = other->createWeak(this);
2990b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3000b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3010b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
3020b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::wp(const wp<T>& other)
3030b575de8ed0b628d84d256f5846500b0385979bdTim Murray    : m_ptr(other.m_ptr), m_refs(other.m_refs)
3040b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3050b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->incWeak(this);
3060b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3070b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3080b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
3090b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::wp(const sp<T>& other)
3100b575de8ed0b628d84d256f5846500b0385979bdTim Murray    : m_ptr(other.m_ptr)
3110b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3120b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) {
3130b575de8ed0b628d84d256f5846500b0385979bdTim Murray        m_refs = m_ptr->createWeak(this);
3140b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
3150b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3160b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3170b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T> template<typename U>
3180b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::wp(U* other)
3190b575de8ed0b628d84d256f5846500b0385979bdTim Murray    : m_ptr(other)
3200b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3210b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (other) m_refs = other->createWeak(this);
3220b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3230b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3240b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T> template<typename U>
3250b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::wp(const wp<U>& other)
3260b575de8ed0b628d84d256f5846500b0385979bdTim Murray    : m_ptr(other.m_ptr)
3270b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3280b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) {
3290b575de8ed0b628d84d256f5846500b0385979bdTim Murray        m_refs = other.m_refs;
3300b575de8ed0b628d84d256f5846500b0385979bdTim Murray        m_refs->incWeak(this);
3310b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
3320b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3330b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3340b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T> template<typename U>
3350b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::wp(const sp<U>& other)
3360b575de8ed0b628d84d256f5846500b0385979bdTim Murray    : m_ptr(other.m_ptr)
3370b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3380b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) {
3390b575de8ed0b628d84d256f5846500b0385979bdTim Murray        m_refs = m_ptr->createWeak(this);
3400b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
3410b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3420b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3430b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
3440b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>::~wp()
3450b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3460b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
3470b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3480b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3490b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
3500b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>& wp<T>::operator = (T* other)
3510b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3520b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type* newRefs =
35344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        other ? other->createWeak(this) : nullptr;
3540b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
3550b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = other;
3560b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = newRefs;
3570b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return *this;
3580b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3590b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3600b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
3610b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>& wp<T>::operator = (const wp<T>& other)
3620b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3630b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type* otherRefs(other.m_refs);
3640b575de8ed0b628d84d256f5846500b0385979bdTim Murray    T* otherPtr(other.m_ptr);
3650b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (otherPtr) otherRefs->incWeak(this);
3660b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
3670b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = otherPtr;
3680b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = otherRefs;
3690b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return *this;
3700b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3710b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3720b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
3730b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>& wp<T>::operator = (const sp<T>& other)
3740b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3750b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type* newRefs =
37644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        other != nullptr ? other->createWeak(this) : nullptr;
3770b575de8ed0b628d84d256f5846500b0385979bdTim Murray    T* otherPtr(other.m_ptr);
3780b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
3790b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = otherPtr;
3800b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = newRefs;
3810b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return *this;
3820b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3830b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3840b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T> template<typename U>
3850b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>& wp<T>::operator = (U* other)
3860b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3870b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type* newRefs =
38844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        other ? other->createWeak(this) : nullptr;
3890b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
3900b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = other;
3910b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = newRefs;
3920b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return *this;
3930b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
3940b575de8ed0b628d84d256f5846500b0385979bdTim Murray
3950b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T> template<typename U>
3960b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>& wp<T>::operator = (const wp<U>& other)
3970b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
3980b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type* otherRefs(other.m_refs);
3990b575de8ed0b628d84d256f5846500b0385979bdTim Murray    U* otherPtr(other.m_ptr);
4000b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (otherPtr) otherRefs->incWeak(this);
4010b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
4020b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = otherPtr;
4030b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = otherRefs;
4040b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return *this;
4050b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
4060b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4070b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T> template<typename U>
4080b575de8ed0b628d84d256f5846500b0385979bdTim Murraywp<T>& wp<T>::operator = (const sp<U>& other)
4090b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
4100b575de8ed0b628d84d256f5846500b0385979bdTim Murray    weakref_type* newRefs =
41144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        other != nullptr ? other->createWeak(this) : nullptr;
4120b575de8ed0b628d84d256f5846500b0385979bdTim Murray    U* otherPtr(other.m_ptr);
4130b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
4140b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = otherPtr;
4150b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = newRefs;
4160b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return *this;
4170b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
4180b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4190b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
4200b575de8ed0b628d84d256f5846500b0385979bdTim Murrayvoid wp<T>::set_object_and_refs(T* other, weakref_type* refs)
4210b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
4220b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (other) refs->incWeak(this);
4230b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) m_refs->decWeak(this);
4240b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_ptr = other;
4250b575de8ed0b628d84d256f5846500b0385979bdTim Murray    m_refs = refs;
4260b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
4270b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4280b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
4290b575de8ed0b628d84d256f5846500b0385979bdTim Murraysp<T> wp<T>::promote() const
4300b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
4310b575de8ed0b628d84d256f5846500b0385979bdTim Murray    sp<T> result;
4320b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr && m_refs->attemptIncStrong(&result)) {
4330b575de8ed0b628d84d256f5846500b0385979bdTim Murray        result.set_pointer(m_ptr);
4340b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
4350b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return result;
4360b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
4370b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4380b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename T>
4390b575de8ed0b628d84d256f5846500b0385979bdTim Murrayvoid wp<T>::clear()
4400b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
4410b575de8ed0b628d84d256f5846500b0385979bdTim Murray    if (m_ptr) {
4420b575de8ed0b628d84d256f5846500b0385979bdTim Murray        m_refs->decWeak(this);
44344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        m_ptr = nullptr;
4440b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
4450b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
4460b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4470b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate <typename T>
4480b575de8ed0b628d84d256f5846500b0385979bdTim Murrayinline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
4490b575de8ed0b628d84d256f5846500b0385979bdTim Murray{
4500b575de8ed0b628d84d256f5846500b0385979bdTim Murray    return printWeakPointer(to, val.unsafe_get());
4510b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
4520b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4530b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
4540b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4550b575de8ed0b628d84d256f5846500b0385979bdTim Murray// this class just serves as a namespace so TYPE::moveReferences can stay
4560b575de8ed0b628d84d256f5846500b0385979bdTim Murray// private.
4570b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4580b575de8ed0b628d84d256f5846500b0385979bdTim Murrayclass ReferenceMover {
4590b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // StrongReferenceCast and WeakReferenceCast do the impedance matching
4600b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // between the generic (void*) implementation in Refbase and the strongly typed
4610b575de8ed0b628d84d256f5846500b0385979bdTim Murray    // template specializations below.
4620b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4630b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template <typename TYPE>
4640b575de8ed0b628d84d256f5846500b0385979bdTim Murray    struct StrongReferenceCast : public ReferenceConverterBase {
4650b575de8ed0b628d84d256f5846500b0385979bdTim Murray        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
4660b575de8ed0b628d84d256f5846500b0385979bdTim Murray        virtual void* getReferenceBase(void const* p) const {
4670b575de8ed0b628d84d256f5846500b0385979bdTim Murray            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
4680b575de8ed0b628d84d256f5846500b0385979bdTim Murray            return static_cast<typename TYPE::basetype *>(sptr->get());
4690b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
4700b575de8ed0b628d84d256f5846500b0385979bdTim Murray    };
4710b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4720b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template <typename TYPE>
4730b575de8ed0b628d84d256f5846500b0385979bdTim Murray    struct WeakReferenceCast : public ReferenceConverterBase {
4740b575de8ed0b628d84d256f5846500b0385979bdTim Murray        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
4750b575de8ed0b628d84d256f5846500b0385979bdTim Murray        virtual void* getReferenceBase(void const* p) const {
4760b575de8ed0b628d84d256f5846500b0385979bdTim Murray            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
4770b575de8ed0b628d84d256f5846500b0385979bdTim Murray            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
4780b575de8ed0b628d84d256f5846500b0385979bdTim Murray        }
4790b575de8ed0b628d84d256f5846500b0385979bdTim Murray    };
4800b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4810b575de8ed0b628d84d256f5846500b0385979bdTim Murraypublic:
4820b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename TYPE> static inline
4830b575de8ed0b628d84d256f5846500b0385979bdTim Murray    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
4840b575de8ed0b628d84d256f5846500b0385979bdTim Murray        memmove(d, s, n*sizeof(sp<TYPE>));
4850b575de8ed0b628d84d256f5846500b0385979bdTim Murray        StrongReferenceCast<TYPE> caster;
4860b575de8ed0b628d84d256f5846500b0385979bdTim Murray        TYPE::moveReferences(d, s, n, caster);
4870b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
4880b575de8ed0b628d84d256f5846500b0385979bdTim Murray    template<typename TYPE> static inline
4890b575de8ed0b628d84d256f5846500b0385979bdTim Murray    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
4900b575de8ed0b628d84d256f5846500b0385979bdTim Murray        memmove(d, s, n*sizeof(wp<TYPE>));
4910b575de8ed0b628d84d256f5846500b0385979bdTim Murray        WeakReferenceCast<TYPE> caster;
4920b575de8ed0b628d84d256f5846500b0385979bdTim Murray        TYPE::moveReferences(d, s, n, caster);
4930b575de8ed0b628d84d256f5846500b0385979bdTim Murray    }
4940b575de8ed0b628d84d256f5846500b0385979bdTim Murray};
4950b575de8ed0b628d84d256f5846500b0385979bdTim Murray
4960b575de8ed0b628d84d256f5846500b0385979bdTim Murray// specialization for moving sp<> and wp<> types.
4970b575de8ed0b628d84d256f5846500b0385979bdTim Murray// these are used by the [Sorted|Keyed]Vector<> implementations
4980b575de8ed0b628d84d256f5846500b0385979bdTim Murray// sp<> and wp<> need to be handled specially, because they do not
4990b575de8ed0b628d84d256f5846500b0385979bdTim Murray// have trivial copy operation in the general case (see RefBase.cpp
5000b575de8ed0b628d84d256f5846500b0385979bdTim Murray// when DEBUG ops are enabled), but can be implemented very
5010b575de8ed0b628d84d256f5846500b0385979bdTim Murray// efficiently in most cases.
5020b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5030b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename TYPE> inline
5040b575de8ed0b628d84d256f5846500b0385979bdTim Murrayvoid move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
5050b575de8ed0b628d84d256f5846500b0385979bdTim Murray    ReferenceMover::move_references(d, s, n);
5060b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
5070b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5080b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename TYPE> inline
5090b575de8ed0b628d84d256f5846500b0385979bdTim Murrayvoid move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
5100b575de8ed0b628d84d256f5846500b0385979bdTim Murray    ReferenceMover::move_references(d, s, n);
5110b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
5120b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5130b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename TYPE> inline
5140b575de8ed0b628d84d256f5846500b0385979bdTim Murrayvoid move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
5150b575de8ed0b628d84d256f5846500b0385979bdTim Murray    ReferenceMover::move_references(d, s, n);
5160b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
5170b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5180b575de8ed0b628d84d256f5846500b0385979bdTim Murraytemplate<typename TYPE> inline
5190b575de8ed0b628d84d256f5846500b0385979bdTim Murrayvoid move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
5200b575de8ed0b628d84d256f5846500b0385979bdTim Murray    ReferenceMover::move_references(d, s, n);
5210b575de8ed0b628d84d256f5846500b0385979bdTim Murray}
5220b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5230b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5240b575de8ed0b628d84d256f5846500b0385979bdTim Murray}; // namespace android
5250b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5260b575de8ed0b628d84d256f5846500b0385979bdTim Murray// ---------------------------------------------------------------------------
5270b575de8ed0b628d84d256f5846500b0385979bdTim Murray
5280b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif // ANDROID_REF_BASE_H
529