/**
 * @file
 * @brief Dynamic memory management header
 * @date 25.06.12
 * @author Vladimir Sokolov
 * @author Ilia Vaprol
 */

#ifndef STANDALONE_NEW_
#define STANDALONE_NEW_

#if defined(__EXCEPTIONS) && __EXCEPTIONS==1
#error Exceptions must be disabled
#endif

#include <exception>
#include <c_compat/cstdlib>

extern "C++" {

namespace std {

	struct nothrow_t { };

	extern const struct nothrow_t nothrow;

	typedef void (*new_handler)();

	new_handler set_new_handler(new_handler) throw();

} // namespace std

#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
#endif
#endif

// Single new and delete operators
void* operator new(std::size_t) throw();
void* operator new(std::size_t, const std::nothrow_t&) throw();
void operator delete(void*) throw();
void operator delete(void*, const std::nothrow_t&) throw();

// Array new and delete operators (same)
void* operator new[](std::size_t) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete[](void*) throw();
void operator delete[](void*, const std::nothrow_t&) throw();

// Default placement versions of new and delete operators
inline void* operator new(std::size_t, void* ptr) throw() { return ptr; }
inline void* operator new[](std::size_t, void* ptr) throw() { return ptr; }
inline void operator delete(void*, void*) throw() { }
inline void operator delete[](void*, void*) throw() { }

#ifdef __GNUC__
#if __GNUC__ > 6
#pragma GCC diagnostic pop
#endif
#endif

} // extern "C++"

#endif // STANDALONE_NEW_
