/*
 * xcam_SmartPtr.h - start pointer
 *
 *  Copyright (c) 2014 Intel Corporation
 *
 * 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.
 *
 * Author: Wind Yuan <feng.yuan@intel.com>
 */
#ifndef XCAM_SMARTPTR_H
#define XCAM_SMARTPTR_H

#include <stdint.h>
#include <atomic>
#include "xcam_defs.h"

namespace XCam {

class RefCount {
public:
    RefCount (): _ref_count(1) {}
    void ref() {
        ++_ref_count;
    }
    uint32_t unref() {
        return --_ref_count;
    }
private:
    mutable std::atomic<uint32_t> _ref_count;
};


template <typename Obj>
class SmartPtr {
private:
    template<typename ObjDerive> friend class SmartPtr;
public:
    SmartPtr (Obj *obj = NULL) : _ptr (obj), _ref(NULL) {
        if (_ptr)
            _ref = new RefCount();
    }
    template <typename ObjDerive>
    SmartPtr (ObjDerive *obj) : _ptr (obj), _ref(NULL) {
        if (_ptr)
            _ref = new RefCount();
    }

    // copy from pointer
    SmartPtr (const SmartPtr<Obj> &obj)
        : _ptr(obj._ptr), _ref(obj._ref)  {
        if (_ptr)
            _ref->ref();
    }
    template <typename ObjDerive>
    SmartPtr (const SmartPtr<ObjDerive> &obj)
        : _ptr(obj._ptr), _ref(obj._ref)  {
        if (_ptr)
            _ref->ref();
    }
    ~SmartPtr () {
        release();
    }

    /* operator = */
    SmartPtr<Obj> & operator = (Obj *obj) {
        release ();
        new_pointer (obj, NULL);
        return *this;
    }
    template <typename ObjDerive>
    SmartPtr<Obj> & operator = (ObjDerive *obj) {
        release ();
        new_pointer (obj, NULL);
        return *this;
    }
    SmartPtr<Obj> & operator = (const SmartPtr<Obj> &obj) {
        release ();
        new_pointer (obj._ptr, obj._ref);
        return *this;
    }
    template <typename ObjDerive>
    SmartPtr<Obj> & operator = (const SmartPtr<ObjDerive> &obj) {
        release ();
        new_pointer (obj._ptr, obj._ref);
    }

    Obj *operator -> () const {
        return _ptr;
    }

    Obj *ptr() const {
        return _ptr;
    }

    void release() {
        if (!_ptr)
            return;
        XCAM_ASSERT (_ref);
        if (!_ref->unref()) {
            delete _ref;
            delete _ptr;
        }
        _ptr = NULL;
        _ref = NULL;
    }
private:
    void new_pointer (Obj *obj, RefCount *ref) {
        if (!obj) {
            _ptr = NULL;
            _ref = NULL;
        }
        _ptr = obj;
        if (ref) {
            _ref = ref;
            _ref->ref();
        } else
            _ref = new RefCount();
    }

private:

    Obj      *_ptr;
    RefCount *_ref;
};

}; // end namespace
#endif //XCAM_SMARTPTR_H