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

#ifndef THIRD_PARTY_LIB_LIBSUPCXX_TOOLCHAIN_NEW_
#define THIRD_PARTY_LIB_LIBSUPCXX_TOOLCHAIN_NEW_

#include <cstdlib>
#include <exception>

extern "C++" {

namespace std {
	class bad_alloc : public exception {
	public:
		bad_alloc() throw() { }
		virtual ~bad_alloc() throw() { }
		virtual const char* what() const throw() { return "std::bad_alloc"; }
	};

	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(std::bad_alloc);
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(std::bad_alloc);
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 // THIRD_PARTY_LIB_LIBSUPCXX_TOOLCHAIN_NEW_
