Newer
Older
project / modules / libscpp / bkup / scpp_memory.hpp
Nomura Kei on 26 Sep 2022 4 KB UPDATE
/**
 * @file      scpp_memory.hpp
 * @bried     メモリ管理モジュールヘッダーファイル
 * @author    Nomura Kei
 * @copyright 2003 - 2022  Nomura Kei
 */
#ifndef SCPP_MEMORY_HPP
#define SCPP_MEMORY_HPP

#include <new>
#include <string>

#include <scpp_compiler.h>

namespace scpp
{


	/**
	 * メモリの確保/解放/エラー発生時に呼び出されるリスナインタフェース。
	 * ユーザーは、本リスナを実装し、MemoryManager::setHandler メソッドにて登録することで、
	 * メモリの確保/解放/エラー発生時の通知を受信することが可能です。
	 *
	 * 本リスナは、MemoryManager で管理しているメモリに対してのみ有効です。
	 * (MemoryManager::malloc, MemoryManager::calloc, MemoryManager::realloc)
	 * 
	 * new, malloc, calloc などを対象とする場合、
	 * ENABLED_MEMORY_MANAGE を定義してください。
	 */
	class MemoryListener
	{
		public:
			virtual void notifyAlloc(const MemoryInfo& info) = 0;
			virtual void notifyFree(const MemoryInfo& info) = 0;
			virtual void notifyError(const MemoryInfo& info, const std::string& msg) = 0;
			virtual ~MemoryListener() = 0;
	};


	/**
	 * メモリ確保/解放/エラー発生時のデフォルト通知インタフェースです。
	 */
	class DefaultMemoryListener : public MemoryListener
	{
		public:
			DefaultMemoryListener();
			DefaultMemoryListener(const DefaultMemoryListener&) = delete;
			void operator=(const DefaultMemoryListener&) = delete;
			virtual ~DefaultMemoryListener();
			virtual void notifyAlloc(const MemoryInfo& info);
			virtual void notifyFree(const MemoryInfo& info);
			virtual void notifyError(const MemoryInfo& info, const std::string& msg);
	};


	/**
	 * メモリ管理。
	 * メモリの確保、解放を行います。
	 * ハンドラを登録することで、メモリの確保/解放/エラー時の通知を受信することができます。
	 */
	namespace MemoryManager
	{
		extern thread_local const char* fileName;
		extern thread_local int			lineNumber;
		extern thread_local const char* functionName;

		void  setListener(MemoryListener* handler);
		void  entries(void (*handler)(const MemoryInfo& info));
		void  cleanup(bool (*isCleanup)(const MemoryInfo& info));
		void  printMemoryInfo(const MemoryInfo& info);
		void* malloc(                   std::size_t size, const char* file, int line, const char* func);
		void* calloc(std::size_t nmemb, std::size_t size, const char* file, int line, const char* func);
		void* realloc(void* ptr,        std::size_t size, const char* file, int line, const char* func);
		void  free(void* ptr);
	}

}


#if (ENABLED_MEMORY_MANAGE)
#if IS_SUPPORTED_CPP20
#define SCPP_NODISCARD [[nodiscard]]
#else
#define SCPP_NODISCARD
#endif

SCPP_NODISCARD void* operator new(std::size_t size);
SCPP_NODISCARD void* operator new[](std::size_t size);

SCPP_NODISCARD void* operator new(std::size_t size, const std::nothrow_t& t) noexcept;
SCPP_NODISCARD void* operator new[](std::size_t size, const std::nothrow_t& t) noexcept;

// void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, std::size_t size) noexcept;

void operator delete(void* ptr, const std::nothrow_t& t) noexcept;
void operator delete[](void* ptr, const std::nothrow_t& t) noexcept;

// 実質メモリ管理しないので除外
// SCPP_NODISCARD void* operator new(std::size_t size, void* ptr) noexcept;
// SCPP_NODISCARD void* operator new[](std::size_t size, void* ptr) noexcept;

#if IS_SUPPORTED_CPP17
// 以下、未サポート
// SCPP_NODISCARD void* operator new(std::size_t size, std::align_val_t alignment);
// SCPP_NODISCARD void* operator new[](std::size_t size, std::align_val_t alignment);
// SCPP_NODISCARD void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;   
// SCPP_NODISCARD void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;   
//
// void operator delete(void* ptr, std::align_val_t alignment) noexcept;
// void operator delete(void* ptr, size_t size,  std::align_val_t alignment) noexcept;
// void operator delete(void* ptr, size_t size,  std::align_val_t alignment, const std::nothrow_t& t) noexcept;
//
#endif

#define new \
	((scpp::MemoryManager::fileName = __FILE__, \
	  scpp::MemoryManager::lineNumber = __LINE__, \
	  scpp::MemoryManager::functionName = __func__, \
	  0) && 0) ? 0 : new

#define malloc(size)        scpp::MemoryManager::malloc(       size, __FILE__, __LINE__, __func__)
#define calloc(nmemb, size) scpp::MemoryManager::calloc(nmemb, size, __FILE__, __LINE__, __func__)
#define realloc(ptr, size)  scpp::MemoryManager::realloc(ptr , size, __FILE__, __LINE__, __func__)
#define free(ptr)           scpp::MemoryManager::free(ptr)

#endif	// (ENABLED_MEMORY_MANAGE)

#endif	// SCPP_MEMORY_HPP