/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed 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.
*/
#ifndef __SMART_PTR_H
#define __SMART_PTR_H

#include <PortableMutex.h>

#include <cutils/atomic.h>

template <class T, bool threadSafe = false>
class SmartPtr
{
public:
    explicit SmartPtr(T* ptr = (T*)NULL) {
        if (threadSafe) {
            m_lock = new mutex_t;
            mutex_init(m_lock);
        }
        else m_lock = NULL;

        m_ptr = ptr;
        if (ptr)
           m_pRefCount = new int32_t(1);
        else
           m_pRefCount = NULL;
    }

    SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) {
        if (threadSafe) {
            m_lock = new mutex_t;
            mutex_init(m_lock);
        }
        else m_lock = NULL;

        m_pRefCount = rhs.m_pRefCount;
        m_ptr       = rhs.m_ptr;
        use();
    }

    SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) {
        if (threadSafe) {
            m_lock = new mutex_t;
            mutex_init(m_lock);
        }
        else m_lock = NULL;

        if (rhs.m_lock) mutex_lock(rhs.m_lock);
        m_pRefCount = rhs.m_pRefCount;
        m_ptr       = rhs.m_ptr;
        use();
        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
    }

    ~SmartPtr() {
        if (m_lock) mutex_lock(m_lock);
        release();
        if (m_lock)
        {
            mutex_unlock(m_lock);
            mutex_destroy(m_lock);
            delete m_lock;
        }
    }

    T* Ptr() const {
        return m_ptr;
    }

    const T* constPtr() const
    {
        return m_ptr;
    }

    T* operator->() const {
        return m_ptr;
    }

    T& operator*() const {
        return *m_ptr;
    }

    operator void*() const {
        return (void *)m_ptr;
    }

    // This gives STL lists something to compare.
    bool operator <(const SmartPtr<T>& t1) const {
        return m_ptr < t1.m_ptr;
    }

    SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs)
    {
        if (m_ptr == rhs.m_ptr)
            return *this;

        if (m_lock) mutex_lock(m_lock);
        release();
        m_pRefCount = rhs.m_pRefCount;
        m_ptr       = rhs.m_ptr;
        use();
        if (m_lock) mutex_unlock(m_lock);

        return *this;
    }

    SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs)
    {
        if (m_ptr == rhs.m_ptr)
            return *this;

        if (m_lock) mutex_lock(m_lock);
        release();
        if (rhs.m_lock) mutex_lock(rhs.m_lock);
        m_pRefCount = rhs.m_pRefCount;
        m_ptr       = rhs.m_ptr;
        use();
        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
        if (m_lock) mutex_unlock(m_lock);

        return *this;
    }

private:
    int32_t  *m_pRefCount;
    mutex_t  *m_lock;
    T* m_ptr;

    // Increment the reference count on this pointer by 1.
    int use() {
        if (!m_pRefCount) return 0;
        return android_atomic_inc(m_pRefCount) + 1;
    }

    // Decrement the reference count on the pointer by 1.
    // If the reference count goes to (or below) 0, the pointer is deleted.
    int release() {
        if (!m_pRefCount) return 0;

        int iVal = android_atomic_dec(m_pRefCount);
        if (iVal > 1)
            return iVal - 1;

        delete m_pRefCount;
        m_pRefCount = NULL;

        if (m_ptr) {
            delete m_ptr;
            m_ptr = NULL;
        }
        return 0;
    }

};

#endif // of  __SMART_PTR_H
