
/******************************************************************************
* MODULE     : basic.gen.cc
* DESCRIPTION: fast global new and delete
*              'rep_struct'    is a base class for representations
*                              of complex data structures,
*                              with reference counting
*              'indirect'      is a module which is used in combination
*                              with rep_struct's.
*              'null_indirect' is a variant of 'indirect'
*              'fatal_error'   raises a fatal error
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
*******************************************************************************
* This software falls under the GNU general public license and comes WITHOUT
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
* If you don't have this file, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/

#include <fast_alloc.gen.h>
#include <basic.gen.h>

#module code_basic
#import fast_alloc
#import basic

extern int large_uses;

void*
operator new (register size_t s)
{
  register void* ptr;
  s= (s+ WORD_LENGTH+ WORD_LENGTH_INC)&WORD_MASK;
  if (s<MAX_FAST) {
    ptr= alloc_ptr(s);
    if (ptr==NULL) ptr= enlarge_malloc (s);
    else alloc_ptr(s)= ind(ptr);
  }
  else {
    ptr= safe_malloc (s);
    large_uses += s;
  }
  *((size_t *) ptr)=s;
  return (void*) (((char*) ptr)+ WORD_LENGTH);
}

void
operator delete (register void* ptr)
{
  ptr= (void*) (((char*) ptr)- WORD_LENGTH);
  register size_t s= *((size_t *) ptr);
  if (s<MAX_FAST) {
    ind(ptr)    = alloc_ptr(s);
    alloc_ptr(s)= ptr;
  }
  else {
    free (ptr);
    large_uses -= s;
  }
}

void*
operator new[] (register size_t s)
{
  register void* ptr;
  s= (s+ WORD_LENGTH+ WORD_LENGTH_INC)&WORD_MASK;
  if (s<MAX_FAST) {
    ptr= alloc_ptr(s);
    if (ptr==NULL) ptr= enlarge_malloc (s);
    else alloc_ptr(s)= ind(ptr);
  }
  else {
    ptr= safe_malloc (s);
    large_uses += s;
  }
  *((size_t *) ptr)=s;
  return (void*) (((char*) ptr)+ WORD_LENGTH);
}

void
operator delete[] (register void* ptr)
{
  ptr= (void*) (((char*) ptr)- WORD_LENGTH);
  register size_t s= *((size_t *) ptr);
  if (s<MAX_FAST) {
    ind(ptr)    = alloc_ptr(s);
    alloc_ptr(s)= ptr;
  }
  else {
    free (ptr);
    large_uses -= s;
  }
}

bool
debug (int which, bool write_flag) {
  static int debug_status= 0;
  if (write_flag) {
    debug_status= debug_status | (1 << which);
    return 0;
  }
  else return (debug_status & (1 << which)) > 0;
}

static int current_indent= 0;

ostream&
operator << (ostream& out, display_control ctrl) {
  int i;
  switch (ctrl) {
  case INDENT:
    out << "  ";
    current_indent += 2;
    break;
  case UNINDENT:
    out << "\b\b";
    current_indent -= 2;
    break;
  case HRULE:
    for (i=current_indent; i<78; i++) out << "-";
  case LF:
    out << "\n";
    for (i=0; i<current_indent; i++) out << " ";
    break;    
  }
  return out;
}

#endmodule // code_basic
