/* scoped_restore, a simple class for saving and restoring a value

   Copyright (C) 2016-2024 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 GDBSUPPORT_SCOPED_RESTORE_H
#define GDBSUPPORT_SCOPED_RESTORE_H

/* Base class for scoped_restore_tmpl.  */
class scoped_restore_base
{
public:
  /* This informs the (scoped_restore_tmpl<T>) dtor that you no longer
     want the original value restored.  */
  void release () const
  { m_saved_var = NULL; }

protected:
  scoped_restore_base (void *saved_var)
    : m_saved_var (saved_var)
  {}

  /* The type-erased saved variable.  This is here so that clients can
     call release() on a "scoped_restore" local, which is a typedef to
     a scoped_restore_base.  See below.  */
  mutable void *m_saved_var;
};

/* A convenience typedef.  Users of make_scoped_restore declare the
   local RAII object as having this type.  */
typedef const scoped_restore_base &scoped_restore;

/* An RAII-based object that saves a variable's value, and then
   restores it again when this object is destroyed. */
template<typename T>
class scoped_restore_tmpl : public scoped_restore_base
{
 public:

  /* Create a new scoped_restore object that saves the current value
     of *VAR.  *VAR will be restored when this scoped_restore object
     is destroyed.  */
  scoped_restore_tmpl (T *var)
    : scoped_restore_base (var),
      m_saved_value (*var)
  {
  }

  /* Create a new scoped_restore object that saves the current value
     of *VAR, and sets *VAR to VALUE.  *VAR will be restored when this
     scoped_restore object is destroyed.  This is templated on T2 to
     allow passing VALUEs of types convertible to T.
     E.g.: T='base'; T2='derived'.  */
  template <typename T2>
  scoped_restore_tmpl (T *var, T2 value)
    : scoped_restore_base (var),
      m_saved_value (*var)
  {
    *var = value;
  }

  scoped_restore_tmpl (const scoped_restore_tmpl<T> &other)
    : scoped_restore_base {other.m_saved_var},
      m_saved_value (other.m_saved_value)
  {
    other.m_saved_var = NULL;
  }

  ~scoped_restore_tmpl ()
  {
    if (saved_var () != NULL)
      *saved_var () = m_saved_value;
  }

private:
  /* Return a pointer to the saved variable with its type
     restored.  */
  T *saved_var ()
  { return static_cast<T *> (m_saved_var); }

  /* No need for this.  It is intentionally not defined anywhere.  */
  scoped_restore_tmpl &operator= (const scoped_restore_tmpl &);

  /* The saved value.  */
  const T m_saved_value;
};

/* Make a scoped_restore.  This is useful because it lets template
   argument deduction work.  */
template<typename T>
scoped_restore_tmpl<T> make_scoped_restore (T *var)
{
  return scoped_restore_tmpl<T> (var);
}

/* Make a scoped_restore.  This is useful because it lets template
   argument deduction work.  */
template<typename T, typename T2>
scoped_restore_tmpl<T> make_scoped_restore (T *var, T2 value)
{
  return scoped_restore_tmpl<T> (var, value);
}

#endif /* GDBSUPPORT_SCOPED_RESTORE_H */
