//  (C) Porkolab 2003
//
//  A.5.2.
//   
//  The family of new and delete operators


class bad_alloc : public exception { /* ... */ };



// indicator for allocation that doesn't throw exceptions
struct nothrow_t {};
extern const nothrow_t nothrow;



// what to do, when error occurs on allocation 
typedef void (*new_handler)();
new_handler set_new_handler(new_handler new_p) throw();



// normal new and delete throws bad_alloc
void* operator new(size_t)    throw(bad_alloc);
void  operator delete(void *) throw();

// nothrow version
void* operator new(size_t, const nothrow_t&)  throw();
void  operator delete(void*, const nothrow_t&) throw();

// the same for arrays
void* operator new[](size_t)   throw(bad_alloc);
void  operator delete[](void*) throw();

void* operator new[](size_t, const nothrow_t&)   throw();
void  operator delete[](void*, const nothrow_t&) throw();



// placement new and delete
void* operator new(size_t, void* p)   throw() { return p; }
void  operator delete(void* p, void*) throw() { }

void* operator new[](size_t, void* p)  throw()  { return p; }
void  operator delete[](void* p, void*) throw() { }



//
//  use of nothrow
//
int* p = new int[100000];   // may throw bad_alloc

if (int* q = new(nothrow) int[100000]) {  // will not throw exception
    // allocation succeeded
}
else {
    // allocation failed
}


//
//      test
//

#include <iostream>
#include "date.h"

using namespace std;

int main()
{
    for( long i = 0; i < 10000; ++i)
    {
        for ( long j = 0; j < 10000; ++j)
        {
            date *dp = new date(2001,1,1);
            // ...
            delete dp;
        }
    }
    return 0;
}

real    0m31.519s
user    0m31.510s
sys     0m0.000s



#include <iostream>
#include "date.h"

using namespace std;

int main()
{
    char *cp = new char[sizeof(date)];
    for( long i = 0; i < 10000; ++i)
    {
        for ( long j = 0; j < 10000; ++j)
        {
            date *dp = new(cp) date(2001,1,1);
            // ...
            dp->~date();
        }
    }
    delete [] cp;
    return 0;
}

real    0m8.765s
user    0m8.760s
sys     0m0.000s



//
//      C-style functions
//  

void* malloc(size_t s);          // allocate s bytes
void* calloc(size_t n, size_t s);// allocate n times s bytes initialized to 0
void  free(void* p);             // free space allocated by malloc() or calloc()
void* realloc(void* p, size_t s);// change the size of the array to s;
                    // if that cannot be done, allocate s bytes, copy
                    // the array pointed to by p to it, and free p


void* memcpy(void* p, const void* q, size_t n);  // copy non-overlapping areas
void* memmove(void* p, const void* q, size_t n); // copy pot. overlapping areas


void* memchr(const void* p, int b, size_t n);   // find b in p[0]..p[n-1]                   
int   memcmp(const void* p, const void* q, size_t n); // compare byte sequences
void* memset(void* p, int b, size_t n);     // set n bytes to b, return p



// this is correct!!
int *ip = new int[0];