/* Reference-counted smart pointer class

   Copyright (C) 2016-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef COMMON_GDB_REF_PTR_H
#define COMMON_GDB_REF_PTR_H

#include <cstddef>

namespace gdb
{

/* An instance of this class either holds a reference to a
   reference-counted object or is "NULL".  Reference counting is
   handled externally by a policy class.  If the object holds a
   reference, then when the object is destroyed, the reference is
   decref'd.

   Normally an instance is constructed using a pointer.  This sort of
   initialization lets this class manage the lifetime of that
   reference.

   Assignment and copy construction will make a new reference as
   appropriate.  Assignment from a plain pointer is disallowed to
   avoid confusion about whether this acquires a new reference;
   instead use the "reset" method -- which, like the pointer
   constructor, transfers ownership.

   The policy class must provide two static methods:
   void incref (T *);
   void decref (T *);
*/
template<typename T, typename Policy>
class ref_ptr
{
 public:

  /* Create a new NULL instance.  */
  ref_ptr ()
    : m_obj (NULL)
  {
  }

  /* Create a new NULL instance.  Note that this is not explicit.  */
  ref_ptr (const std::nullptr_t)
    : m_obj (NULL)
  {
  }

  /* Create a new instance.  OBJ is a reference, management of which
     is now transferred to this class.  */
  explicit ref_ptr (T *obj)
    : m_obj (obj)
  {
  }

  /* Copy another instance.  */
  ref_ptr (const ref_ptr &other)
    : m_obj (other.m_obj)
  {
    if (m_obj != NULL)
      Policy::incref (m_obj);
  }

  /* Transfer ownership from OTHER.  */
  ref_ptr (ref_ptr &&other) noexcept
    : m_obj (other.m_obj)
  {
    other.m_obj = NULL;
  }

  /* Destroy this instance.  */
  ~ref_ptr ()
  {
    if (m_obj != NULL)
      Policy::decref (m_obj);
  }

  /* Copy another instance.  */
  ref_ptr &operator= (const ref_ptr &other)
  {
    /* Do nothing on self-assignment.  */
    if (this != &other)
      {
	reset (other.m_obj);
	if (m_obj != NULL)
	  Policy::incref (m_obj);
      }
    return *this;
  }

  /* Transfer ownership from OTHER.  */
  ref_ptr &operator= (ref_ptr &&other)
  {
    /* Do nothing on self-assignment.  */
    if (this != &other)
      {
	reset (other.m_obj);
	other.m_obj = NULL;
      }
    return *this;
  }

  /* Change this instance's referent.  OBJ is a reference, management
     of which is now transferred to this class.  */
  void reset (T *obj)
  {
    if (m_obj != NULL)
      Policy::decref (m_obj);
    m_obj = obj;
  }

  /* Return this instance's referent without changing the state of
     this class.  */
  T *get () const
  {
    return m_obj;
  }

  /* Return this instance's referent, and stop managing this
     reference.  The caller is now responsible for the ownership of
     the reference.  */
  ATTRIBUTE_UNUSED_RESULT T *release ()
  {
    T *result = m_obj;

    m_obj = NULL;
    return result;
  }

  /* Let users refer to members of the underlying pointer.  */
  T *operator-> () const
  {
    return m_obj;
  }

  /* Acquire a new reference and return a ref_ptr that owns it.  */
  static ref_ptr<T, Policy> new_reference (T *obj)
  {
    Policy::incref (obj);
    return ref_ptr<T, Policy> (obj);
  }

 private:

  T *m_obj;
};

template<typename T, typename Policy>
inline bool operator== (const ref_ptr<T, Policy> &lhs,
			const ref_ptr<T, Policy> &rhs)
{
  return lhs.get () == rhs.get ();
}

template<typename T, typename Policy>
inline bool operator== (const ref_ptr<T, Policy> &lhs, const T *rhs)
{
  return lhs.get () == rhs;
}

template<typename T, typename Policy>
inline bool operator== (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
{
  return lhs.get () == nullptr;
}

template<typename T, typename Policy>
inline bool operator== (const T *lhs, const ref_ptr<T, Policy> &rhs)
{
  return lhs == rhs.get ();
}

template<typename T, typename Policy>
inline bool operator== (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
{
  return nullptr == rhs.get ();
}

template<typename T, typename Policy>
inline bool operator!= (const ref_ptr<T, Policy> &lhs,
			const ref_ptr<T, Policy> &rhs)
{
  return lhs.get () != rhs.get ();
}

template<typename T, typename Policy>
inline bool operator!= (const ref_ptr<T, Policy> &lhs, const T *rhs)
{
  return lhs.get () != rhs;
}

template<typename T, typename Policy>
inline bool operator!= (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
{
  return lhs.get () != nullptr;
}

template<typename T, typename Policy>
inline bool operator!= (const T *lhs, const ref_ptr<T, Policy> &rhs)
{
  return lhs != rhs.get ();
}

template<typename T, typename Policy>
inline bool operator!= (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
{
  return nullptr != rhs.get ();
}

}

#endif /* COMMON_GDB_REF_PTR_H */
