73 #include <unordered_map> 75 class ConstructorStats {
100 default_constructions++;
106 if (--_instances[inst] < 0) {
107 throw std::runtime_error(
"cstats.destroyed() called with unknown " 108 "instance; potential double-destruction " 109 "or a missing cstats.created()");
115 #if defined(PYPY_VERSION) 116 PyObject *
globals = PyEval_GetGlobals();
117 PyObject *
result = PyRun_String(
"import gc\n" 123 if (result ==
nullptr)
124 throw py::error_already_set();
127 py::module_::import(
"gc").attr(
"collect")();
134 for (
const auto &
p : _instances) {
144 template <
typename T,
typename... Tmore>
146 std::ostringstream oss;
148 _values.push_back(oss.str());
155 for (
const auto &
v : _values) {
163 static ConstructorStats &
get(std::type_index
type) {
164 static std::unordered_map<std::type_index, ConstructorStats> all_cstats;
165 return all_cstats[
type];
169 template <
typename T>
170 static ConstructorStats &
get() {
171 #if defined(PYPY_VERSION) 174 return get(
typeid(
T));
178 static ConstructorStats &
get(py::object class_) {
180 const std::type_index *t1 =
nullptr, *t2 =
nullptr;
193 }
catch (
const std::out_of_range &) {
196 throw std::runtime_error(
"Unknown class passed to ConstructorStats::get()");
198 auto &cs1 =
get(*t1);
202 auto &cs2 =
get(*t2);
203 int cs1_total = cs1.default_constructions + cs1.copy_constructions
204 + cs1.move_constructions + (
int) cs1._values.size();
205 int cs2_total = cs2.default_constructions + cs2.copy_constructions
206 + cs2.move_constructions + (
int) cs2._values.size();
207 if (cs2_total > cs1_total) {
226 template <
class T,
typename...
Values>
228 auto &cst = ConstructorStats::get<T>();
229 cst.copy_assignments++;
230 cst.value(std::forward<Values>(
values)...);
232 template <
class T,
typename...
Values>
234 auto &cst = ConstructorStats::get<T>();
235 cst.move_assignments++;
236 cst.value(std::forward<Values>(
values)...);
238 template <
class T,
typename...
Values>
240 auto &cst = ConstructorStats::get<T>();
241 cst.default_created(inst);
242 cst.value(std::forward<Values>(
values)...);
244 template <
class T,
typename...
Values>
246 auto &cst = ConstructorStats::get<T>();
248 cst.value(std::forward<Values>(
values)...);
250 template <
class T,
typename...
Values>
252 ConstructorStats::get<T>().
destroyed(inst);
254 template <
class T,
typename...
Values>
256 ConstructorStats::get<T>().
value(std::forward<Values>(
values)...);
261 template <
typename T>
263 return "{:#x}"_s.format(reinterpret_cast<std::uintptr_t>(p));
265 template <
typename T>
267 return std::forward<T>(
x);
270 template <
class T,
typename... Output>
281 template <
class T,
typename...
Values>
287 template <
class T,
typename...
Values>
293 template <
class T,
typename...
Values>
298 template <
class T,
typename...
Values>
303 template <
class T,
typename...
Values>
308 template <
class T,
typename...
Values>
313 template <
class T,
typename...
Values>
318 template <
class T,
typename...
Values>
int default_constructions
void value(const T &v, Tmore &&...args)
void track_copy_assigned(T *, Values &&...values)
PYBIND11_NOINLINE internals & get_internals()
Return a reference to the current internals data.
type_map< type_info * > registered_types_cpp
void print_destroyed(T *inst, Values &&...values)
void print_copy_assigned(T *inst, Values &&...values)
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
const char * format_ptrs(const char *p)
Don't cast pointers to Python, print them as strings.
void print_copy_created(T *inst, Values &&...values)
void move_created(void *inst)
void default_created(void *inst)
void track_move_created(T *inst)
static const Line3 l(Rot3(), 1, 1)
std::unordered_map< void *, int > _instances
void print_default_created(T *inst, Values &&...values)
std::list< std::string > _values
void print_values(T *inst, Values &&...values)
void print_move_assigned(T *inst, Values &&...values)
void copy_created(void *inst)
Array< int, Dynamic, 1 > v
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Eigen::Triplet< double > T
void track_copy_created(T *inst)
void track_destroyed(T *inst)
void track_move_assigned(T *, Values &&...values)
void print_created(T *inst, Values &&...values)
void print_constr_details(T *inst, const std::string &action, Output &&...output)
void destroyed(void *inst)
void print_move_created(T *inst, Values &&...values)
std::unordered_map< PyTypeObject *, std::vector< type_info * > > registered_types_py
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
void track_created(T *inst, Values &&...values)
void track_default_created(T *inst, Values &&...values)
void track_values(T *, Values &&...values)