// new standard header -*-c++-*-
// Copyright 2003-2017 IAR Systems AB.
#ifndef _NEW_
#define _NEW_

#ifndef _SYSTEM_BUILD
#pragma system_include
#endif

#include <exception>

namespace std {

#ifndef _NO_BAD_XXX
  // CLASS bad_alloc
  class bad_alloc : public ::std::exception
  {
  public:
    bad_alloc() _THROW0();
    bad_alloc(const bad_alloc&) _THROW0();
    bad_alloc& operator=(const bad_alloc&) _THROW0();
    virtual ~bad_alloc() _NOEXCEPT;
    virtual const char* what() const _THROW0();
  };

  // CLASS bad_array_new_length
  class bad_array_new_length
    : public bad_alloc
  {       // bad array new exception
  public:
    bad_array_new_length() _THROW0()
    : bad_alloc()
    {       // default construct
    }
  };
#endif /* _NO_BAD_XXX */

// SUPPORT TYPES
typedef void (*new_handler)();  // handler for operator new failures

struct nothrow_t
{       // placement new tag type to suppress exceptions
};

// constant for placement new tag
_DLIB_CONST_ATTR extern const nothrow_t nothrow;

// FUNCTION AND OBJECT DECLARATIONS
__ATTRIBUTES new_handler get_new_handler() _NOEXCEPT;   // get new handler
__ATTRIBUTES new_handler set_new_handler(new_handler) _THROW0();
                                          // establish alternate new handler

_DLIB_DATA_ATTR extern new_handler __iar_New_hand;  // pointer to current
                                                    // new handler


constexpr size_t hardware_destructive_interference_size = alignof(max_align_t);

constexpr size_t hardware_constructive_interference_size = alignof(max_align_t);

} /* namespace std */


// new AND delete DECLARATIONS (NB: NOT IN std)
void operator delete(void *) _THROW0(); // delete allocated storage

void *operator new(::size_t);           // allocate or throw exception

#include <xmemnew>

void operator delete[](void *) _THROW0();       // delete allocated array

void *operator new[](::size_t);            // allocate array or throw exception

#pragma language = save
#pragma language = extended

// Do the stuff needed for overaligned allocation
namespace std
{
  enum class align_val_t : size_t { };

  #define __HEAPND_MEM_HELPER1__(_Mem, _I)                                  \
    enum class _GLUE(_Mem, _align_val_t) :                                  \
                                  _GLUE3(__DATA_MEM, _I, _SIZE_TYPE__) { };
  __HEAPND_MEMORY_LIST1__()
  #undef __HEAPND_MEM_HELPER1__
} // namespace std

void * operator new(std::size_t,
                    std::align_val_t,
                    std::nothrow_t const &) _THROW0();
void * operator new [](std::size_t,
                       std::align_val_t,
                       std::nothrow_t const &) _THROW0();

#define __HEAPND_MEM_HELPER1__(_Mem, _I)                                    \
  void _Mem *operator new _Mem(_GLUE3(__DATA_MEM, _I, _SIZE_TYPE__),        \
                               std::_GLUE(_Mem, _align_val_t),              \
                               const std::nothrow_t&) _THROW0();            \
  void _Mem *operator new [] _Mem(_GLUE3(__DATA_MEM, _I, _SIZE_TYPE__),     \
                                  std::_GLUE(_Mem, _align_val_t),           \
                                  const std::nothrow_t&) _THROW0();
__HEAPND_MEMORY_LIST1__()
#undef __HEAPND_MEM_HELPER1__

#if 0
// Define sized deallocation functions
#define __HEAP_MEM_HELPER1__(_Mem, _I)                                      \
  inline void operator delete(void _Mem * _P,                               \
                              _GLUE3(__DATA_MEM, _I, _SIZE_TYPE__))         \
              _THROW0()                                                     \
  {                                                                         \
    ::operator delete(_P);                                                  \
  }                                                                         \
  inline void operator delete [](void _Mem * _P,                            \
                                 _GLUE3(__DATA_MEM, _I, _SIZE_TYPE__))      \
              _THROW0()                                                     \
  {                                                                         \
    ::operator delete [](_P);                                               \
  }
__HEAP_MEMORY_LIST1__()
#undef __HEAP_MEM_HELPER1__
#endif

#if _HAS_EXCEPTIONS
  // Declare a nothrow delete for each heap memory
  #define __HEAP_MEM_HELPER1__(_Mem, _I)                                    \
    void operator delete(void _Mem *, const std::nothrow_t&)                \
      _THROW0();      // delete if nothrow new fails -- REPLACEABLE
  __HEAP_MEMORY_LIST1__()
  #undef __HEAP_MEM_HELPER1__

  // Declare a nothrow array delete for each heap memory
  #define __HEAP_MEM_HELPER1__(_Mem, _I)                                    \
    void operator delete[](void _Mem *, const std::nothrow_t&)              \
      _THROW0();      // delete if nothrow array new fails -- REPLACEABLE
  __HEAP_MEMORY_LIST1__()
  #undef __HEAP_MEM_HELPER1__

  // Define a placement delete for each heap memory
  #define __HEAP_MEM_HELPER1__(_Mem, _I)                                    \
    inline void operator delete(void _Mem *, void _Mem *) _THROW0()         \
    {       /* delete if placement new fails */                             \
    }
  __HEAP_MEMORY_LIST1__()
  #undef __HEAP_MEM_HELPER1__

  // Define a placement array new for each heap memory
  #define __HEAP_MEM_HELPER1__(_Mem, _I)                                    \
    inline void operator delete[](void _Mem *, void _Mem *) _THROW0()       \
    {       /* delete if placement array new fails */                       \
    }
  __HEAP_MEMORY_LIST1__()
  #undef __HEAP_MEM_HELPER1__

  // Declare the align nothrow deletes
  void operator delete  (void *, std::align_val_t, std::nothrow_t const &);
  void operator delete[](void *, std::align_val_t, std::nothrow_t const &);
  #define __HEAPND_MEM_HELPER1__(_Mem, _I)                                  \
  void operator delete  (void _Mem *,                                       \
                         std::_GLUE(_Mem, _align_val_t),                    \
                         const std::nothrow_t&) _THROW0();                  \
  void operator delete[](void _Mem *,                                       \
                         std::_GLUE(_Mem, _align_val_t),                    \
                         const std::nothrow_t&) _THROW0();
  __HEAPND_MEMORY_LIST1__()
  #undef __HEAPND_MEM_HELPER1__

#endif /* _HAS_EXCEPTIONS */

#pragma language = restore

#endif /* _NEW_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0576 */
