(root)/
gcc-13.2.0/
gcc/
rust/
util/
rust-stacked-contexts.h
       1  // Copyright (C) 2020-2023 Free Software Foundation, Inc.
       2  
       3  // This file is part of GCC.
       4  
       5  // GCC is free software; you can redistribute it and/or modify it under
       6  // the terms of the GNU General Public License as published by the Free
       7  // Software Foundation; either version 3, or (at your option) any later
       8  // version.
       9  
      10  // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11  // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13  // for more details.
      14  
      15  // You should have received a copy of the GNU General Public License
      16  // along with GCC; see the file COPYING3.  If not see
      17  // <http://www.gnu.org/licenses/>.
      18  
      19  #ifndef RUST_CONTEXT_STACK_H
      20  #define RUST_CONTEXT_STACK_H
      21  
      22  #include "rust-system.h"
      23  
      24  namespace Rust {
      25  
      26  /**
      27   * Context stack util class. This class is useful for situations where you can
      28   * enter the same kind of context multiple times. For example, when dealing with
      29   * unsafe contexts, you might be tempted to simply keep a boolean value.
      30   *
      31   * ```rust
      32   * let a = 15;
      33   * unsafe { // we set the boolean to true
      34   *     // Now unsafe operations are allowed!
      35   *     let b = *(&a as *const i32);
      36   *     let c = std::mem::transmute<i32, f32>(b); // Urgh!
      37   * } // we set it to false
      38   * ```
      39   *
      40   * However, since the language allows nested unsafe blocks, you may run into
      41   * this situation:
      42   *
      43   * ```rust
      44   * unsafe { // we set the boolean to true
      45   *     unsafe { // we set the boolean to true
      46   *     } // we set it to false
      47   *
      48   *     // Now unsafe operations are forbidden again, the boolean is false
      49   *     let f = std::mem::transmute<i32, f32>(15); // Error!
      50   * } // we set it to false
      51   * ```
      52   */
      53  template <typename T> class StackedContexts
      54  {
      55  public:
      56    /**
      57     * Enter a special context
      58     */
      59    void enter (T value) { stack.emplace_back (value); }
      60  
      61    /**
      62     * Exit a special context
      63     */
      64    T exit ()
      65    {
      66      rust_assert (!stack.empty ());
      67  
      68      auto last = stack.back ();
      69      stack.pop_back ();
      70  
      71      return last;
      72    }
      73  
      74    /**
      75     * Are we currently inside of a special context?
      76     */
      77    bool is_in_context () const { return !stack.empty (); }
      78  
      79  private:
      80    /* Actual data */
      81    std::vector<T> stack;
      82  };
      83  
      84  } // namespace Rust
      85  
      86  #endif /* !RUST_CONTEXT_STACK_H */