// File:       new.c++
// Version:    1.00
// Author:     (c) Miles Sabin, 1996
// Purpose:    dynamic storage allocation

// Change log:
//  11/10/96   v. 1.00
//  25/10/96   Fixed bug: attempt to copy bad_alloc caused exception in exception handler.
//  15/01/97   Moved allocator registration stuff to rts.
//  31/01/97   Added default ctor to nothrow to work around CFront problem.

#include "new.h"

#include <stdlib.h>          // for malloc(), free()
#include "bool.h"
#include "exception.h"


// Implementation of new handler

static void default_new_handler()
{
  throw(bad_alloc());
}

static new_handler current_new_handler = default_new_handler;

new_handler set_new_handler(new_handler new_p)
{
  new_handler old_handler = current_new_handler;
  current_new_handler = new_p;
  return old_handler;
}


// Implementation of new and delete

void* operator new(size_t size)
{
  do
  {
    void* p = malloc(size);

    if(p != 0)
      return p;
    else
      current_new_handler();
  }
  while(true);
}

void* operator new(size_t size, nothrow const&)
{
  do
  {
    void* ptr = malloc(size);

    if(ptr != 0)
      return ptr;
    else
    {
      try
      {
        current_new_handler();
      }
      BEGIN_HANDLERS
      catch(bad_alloc, ex)
      {
        return 0;
      }
      END_HANDLERS
    }
  }
  while(true);
}

void  operator delete(void* ptr)
{
  if(ptr != 0)
    free(ptr);
}


// Implementation of bad_alloc

static struct
{
  char block[sizeof(bad_alloc)];
  bool in_use;
} bad_alloc_buffer;

bad_alloc::bad_alloc()
  {}

bad_alloc::~bad_alloc()
  {}

void* bad_alloc::operator new(size_t size)
  { return (bad_alloc_buffer.in_use || size != sizeof(bad_alloc) ? ::operator new(size) : (bad_alloc_buffer.in_use = true, bad_alloc_buffer.block)); }

void bad_alloc::operator delete(void* p, size_t)
  {
    if(p == bad_alloc_buffer.block)
      bad_alloc_buffer.in_use = false;
    else
      ::operator delete(p);
  }

char const* bad_alloc::what() const
  { return "bad_alloc"; }

RTTI_SCAFFOLDING_DEFN_1(bad_alloc, exception)


