text: /*
   * (c) 2021 Henrich Lauko <xlauko@mail.muni.cz>
   * (c) 2019 Petr Ročkai <code@fixp.eu>
   *
   * Permission to use, copy, modify, and distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
   * copyright notice and this permission notice appear in all copies.
   *
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  
  #pragma once
  
  namespace sc
  {
      template< typename deleter >
      struct deferred_erase
      {
          using instruction = llvm::Instruction *;
          
          deferred_erase(deleter d, instruction i) : del(d), inst(i) {}
          ~deferred_erase()
          { 
              if (inst->getParent())
                  inst->eraseFromParent();
              del(inst);
          }
  
      private:
          deleter del;
          instruction inst;
      };
  
      template< typename deleter >
      struct deferred_erase_vector
      {
          using instruction = llvm::Instruction *;
          
          deferred_erase_vector(deleter d) : del(d) {}
  
          void push(instruction i) { data.emplace_back(del, i); }
  
      private:
          deleter del;
          std::vector< deferred_erase< deleter > > data;
      };
  
  } // namespace sc