//! \~\file piintrospection_containers.h //! \~\ingroup Introspection //! \~\brief //! \~english Container introspection helpers //! \~russian Вспомогательные средства интроспекции контейнеров /* PIP - Platform Independent Primitives Introspection module - interface for containers Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIINTROSPECTION_CONTAINERS_H #define PIINTROSPECTION_CONTAINERS_H #include "pibase.h" //! \~\ingroup Introspection //! \~\brief //! \~english Metadata describing one tracked container element type. //! \~russian Метаданные, описывающие один отслеживаемый тип элементов контейнера. struct PIP_EXPORT PIIntrospectionContainersType { //! \~english Destroys the type descriptor. //! \~russian Уничтожает дескриптор типа. ~PIIntrospectionContainersType(); //! \~english Finalizes type information, including generated identifiers and names. //! \~russian Завершает подготовку информации о типе, включая сгенерированные идентификаторы и имена. void finish(); //! \~english Stable identifier of the tracked type. //! \~russian Стабильный идентификатор отслеживаемого типа. uint id = 0; //! \~english Compiler-provided type name. //! \~russian Имя типа, предоставленное компилятором. const char * name = nullptr; //! \~english Demangled type name when available. //! \~russian Деманглированное имя типа, если доступно. const char * demangled = "?"; //! \~english True after \a finish() prepares the descriptor. //! \~russian Истина после того, как \a finish() подготовит дескриптор. bool inited = false; //! \~english True when demangled name was resolved successfully. //! \~russian Истина, если деманглированное имя успешно получено. bool has_demangled = false; }; #if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION) # include "piintrospection_base.h" class PIIntrospectionContainers; //! \~\ingroup Introspection //! \~\brief //! \~english Lazily builds and caches type metadata for container introspection macros. //! \~russian Лениво создает и кеширует метаданные типа для макросов интроспекции контейнеров. template class PIIntrospectionContainersTypeInfo { public: //! \~english Returns cached metadata for type `T`. //! \~russian Возвращает кешированные метаданные для типа `T`. static const PIIntrospectionContainersType & get() { static PIIntrospectionContainersType ret = create(); return ret; } private: static PIIntrospectionContainersType create() { PIIntrospectionContainersType ret; ret.name = __PIP_TYPENAME__(T); ret.finish(); return ret; } }; # define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance()) # ifdef DOXYGEN //! \~\ingroup Introspection //! \relatesalso PIIntrospectionContainersInterface //! \~\brief //! \~english Registers construction of a container storing elements of type `t`. //! \~russian Регистрирует создание контейнера, хранящего элементы типа `t`. # define PIINTROSPECTION_CONTAINER_NEW(t, isz) //! \~\ingroup Introspection //! \relatesalso PIIntrospectionContainersInterface //! \~\brief //! \~english Registers destruction of a container storing elements of type `t`. //! \~russian Регистрирует уничтожение контейнера, хранящего элементы типа `t`. # define PIINTROSPECTION_CONTAINER_DELETE(t) //! \~\ingroup Introspection //! \relatesalso PIIntrospectionContainersInterface //! \~\brief //! \~english Adds `cnt` allocated element slots for containers of type `t`. //! \~russian Добавляет `cnt` выделенных слотов элементов для контейнеров типа `t`. # define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) //! \~\ingroup Introspection //! \relatesalso PIIntrospectionContainersInterface //! \~\brief //! \~english Removes `cnt` allocated element slots for containers of type `t`. //! \~russian Убирает `cnt` выделенных слотов элементов для контейнеров типа `t`. # define PIINTROSPECTION_CONTAINER_FREE(t, cnt) //! \~\ingroup Introspection //! \relatesalso PIIntrospectionContainersInterface //! \~\brief //! \~english Adds `cnt` used element slots for containers of type `t`. //! \~russian Добавляет `cnt` занятых слотов элементов для контейнеров типа `t`. # define PIINTROSPECTION_CONTAINER_USED(t, cnt) //! \~\ingroup Introspection //! \relatesalso PIIntrospectionContainersInterface //! \~\brief //! \~english Removes `cnt` used element slots for containers of type `t`. //! \~russian Убирает `cnt` занятых слотов элементов для контейнеров типа `t`. # define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) # else // clang-format off # define PIINTROSPECTION_CONTAINER_NEW(t, isz) PIINTROSPECTION_CONTAINERS->containerNew (PIIntrospectionContainersTypeInfo::get(), isz); # define PIINTROSPECTION_CONTAINER_DELETE(t) PIINTROSPECTION_CONTAINERS->containerDelete(PIIntrospectionContainersTypeInfo::get() ); # define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) PIINTROSPECTION_CONTAINERS->containerAlloc (PIIntrospectionContainersTypeInfo::get(), cnt); # define PIINTROSPECTION_CONTAINER_FREE(t, cnt) PIINTROSPECTION_CONTAINERS->containerFree (PIIntrospectionContainersTypeInfo::get(), cnt); # define PIINTROSPECTION_CONTAINER_USED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUsed (PIIntrospectionContainersTypeInfo::get(), cnt); # define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUnused(PIIntrospectionContainersTypeInfo::get(), cnt); // clang-format on # endif //! \~\ingroup Introspection //! \~\brief //! \~english Entry point for collecting container allocation and usage statistics. //! \~russian Точка входа для сбора статистики выделения и использования контейнеров. class PIP_EXPORT PIIntrospectionContainersInterface { friend class PIIntrospection; friend class PIIntrospectionServer; public: __PIINTROSPECTION_SINGLETON_H__(Containers) //! \~english Registers construction of a container instance with element size `isz`. //! \~russian Регистрирует создание экземпляра контейнера с размером элемента `isz`. void containerNew(const PIIntrospectionContainersType & ti, uint isz); //! \~english Registers destruction of a container instance. //! \~russian Регистрирует уничтожение экземпляра контейнера. void containerDelete(const PIIntrospectionContainersType & ti); //! \~english Adds `cnt` allocated element slots for tracked type `ti`. //! \~russian Добавляет `cnt` выделенных слотов элементов для отслеживаемого типа `ti`. void containerAlloc(const PIIntrospectionContainersType & ti, ullong cnt); //! \~english Removes `cnt` allocated element slots for tracked type `ti`. //! \~russian Убирает `cnt` выделенных слотов элементов для отслеживаемого типа `ti`. void containerFree(const PIIntrospectionContainersType & ti, ullong cnt); //! \~english Adds `cnt` used element slots for tracked type `ti`. //! \~russian Добавляет `cnt` занятых слотов элементов для отслеживаемого типа `ti`. void containerUsed(const PIIntrospectionContainersType & ti, ullong cnt); //! \~english Removes `cnt` used element slots for tracked type `ti`. //! \~russian Убирает `cnt` занятых слотов элементов для отслеживаемого типа `ti`. void containerUnused(const PIIntrospectionContainersType & ti, ullong cnt); //! \~english Private implementation pointer with collected statistics. //! \~russian Указатель на приватную реализацию с накопленной статистикой. PIIntrospectionContainers * p; private: PIIntrospectionContainersInterface(); ~PIIntrospectionContainersInterface(); }; #else # define PIINTROSPECTION_CONTAINER_NEW(t, isz) # define PIINTROSPECTION_CONTAINER_DELETE(t) # define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) # define PIINTROSPECTION_CONTAINER_FREE(t, cnt) # define PIINTROSPECTION_CONTAINER_USED(t, cnt) # define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) #endif #endif // PIINTROSPECTION_CONTAINERS_H