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

   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_SCOPED_RESTORE_H
#define COMMON_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 /* COMMON_SCOPED_RESTORE_H */
