Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
f4f2afb6
Commit
f4f2afb6
authored
Aug 12, 2016
by
Wenzel Jakob
Committed by
GitHub
Aug 12, 2016
Browse files
Merge pull request #324 from jagerman/example-constructor-tracking
Improve constructor/destructor tracking
parents
85557b1d
3f589379
Changes
36
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
420 additions
and
290 deletions
+420
-290
example/example-python-types.py
example/example-python-types.py
+7
-0
example/example-python-types.ref
example/example-python-types.ref
+4
-1
example/example-sequences-and-iterators.cpp
example/example-sequences-and-iterators.cpp
+18
-11
example/example-sequences-and-iterators.py
example/example-sequences-and-iterators.py
+16
-0
example/example-sequences-and-iterators.ref
example/example-sequences-and-iterators.ref
+24
-14
example/example-smart-ptr.cpp
example/example-smart-ptr.cpp
+9
-6
example/example-smart-ptr.py
example/example-smart-ptr.py
+15
-0
example/example-smart-ptr.ref
example/example-smart-ptr.ref
+206
-179
example/example-virtual-functions.cpp
example/example-virtual-functions.cpp
+13
-14
example/example-virtual-functions.py
example/example-virtual-functions.py
+13
-2
example/example-virtual-functions.ref
example/example-virtual-functions.ref
+22
-13
example/example.cpp
example/example.cpp
+16
-0
example/issues.cpp
example/issues.cpp
+7
-6
example/issues.ref
example/issues.ref
+18
-18
example/object.h
example/object.h
+26
-11
example/run_test.py
example/run_test.py
+6
-15
No files found.
example/example-python-types.py
View file @
f4f2afb6
...
...
@@ -65,3 +65,10 @@ print("__name__(example.ExamplePythonTypes) = %s" % ExamplePythonTypes.__name__)
print
(
"__module__(example.ExamplePythonTypes) = %s"
%
ExamplePythonTypes
.
__module__
)
print
(
"__name__(example.ExamplePythonTypes.get_set) = %s"
%
ExamplePythonTypes
.
get_set
.
__name__
)
print
(
"__module__(example.ExamplePythonTypes.get_set) = %s"
%
ExamplePythonTypes
.
get_set
.
__module__
)
from
example
import
ConstructorStats
cstats
=
ConstructorStats
.
get
(
ExamplePythonTypes
)
print
(
"Instances not destroyed:"
,
cstats
.
alive
())
instance
=
None
print
(
"Instances not destroyed:"
,
cstats
.
alive
())
example/example-python-types.ref
View file @
f4f2afb6
...
...
@@ -2,6 +2,7 @@
5
example.ExamplePythonTypes: No constructor defined!
can't set attribute
### ExamplePythonTypes @ 0x1045b80 created via new_instance
key: key2, value=value2
key: key, value=value
key: key, value=value
...
...
@@ -134,4 +135,6 @@ __name__(example.ExamplePythonTypes) = ExamplePythonTypes
__module__(example.ExamplePythonTypes) = example
__name__(example.ExamplePythonTypes.get_set) = get_set
__module__(example.ExamplePythonTypes.get_set) = example
Destructing ExamplePythonTypes
Instances not destroyed: 1
### ExamplePythonTypes @ 0x1045b80 destroyed
Instances not destroyed: 0
example/example-sequences-and-iterators.cpp
View file @
f4f2afb6
...
...
@@ -9,51 +9,55 @@
*/
#include "example.h"
#include "constructor-stats.h"
#include <pybind11/operators.h>
#include <pybind11/stl.h>
class
Sequence
{
public:
Sequence
(
size_t
size
)
:
m_size
(
size
)
{
std
::
cout
<<
"Value constructor: Creating a sequence with "
<<
m_size
<<
" entries"
<<
std
::
endl
;
print_created
(
this
,
"of size"
,
m_size
)
;
m_data
=
new
float
[
size
];
memset
(
m_data
,
0
,
sizeof
(
float
)
*
size
);
}
Sequence
(
const
std
::
vector
<
float
>
&
value
)
:
m_size
(
value
.
size
())
{
std
::
cout
<<
"Value constructor: Creating a sequence with "
<<
m_size
<<
" entries"
<<
std
::
endl
;
print_created
(
this
,
"of size"
,
m_size
,
"from std::vector"
)
;
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
&
value
[
0
],
sizeof
(
float
)
*
m_size
);
}
Sequence
(
const
Sequence
&
s
)
:
m_size
(
s
.
m_size
)
{
std
::
cout
<<
"Copy constructor: Creating a sequence with "
<<
m_size
<<
" entries"
<<
std
::
endl
;
print_copy_created
(
this
)
;
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_size
);
}
Sequence
(
Sequence
&&
s
)
:
m_size
(
s
.
m_size
),
m_data
(
s
.
m_data
)
{
std
::
cout
<<
"Move constructor: Creating a sequence with "
<<
m_size
<<
" entries"
<<
std
::
endl
;
print_move_created
(
this
)
;
s
.
m_size
=
0
;
s
.
m_data
=
nullptr
;
}
~
Sequence
()
{
std
::
cout
<<
"Freeing a sequence with "
<<
m_size
<<
" entries"
<<
std
::
endl
;
print_destroyed
(
this
)
;
delete
[]
m_data
;
}
Sequence
&
operator
=
(
const
Sequence
&
s
)
{
std
::
cout
<<
"Assignment operator: Creating a sequence with "
<<
s
.
m_size
<<
" entries"
<<
std
::
endl
;
delete
[]
m_data
;
m_size
=
s
.
m_size
;
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_size
);
if
(
&
s
!=
this
)
{
delete
[]
m_data
;
m_size
=
s
.
m_size
;
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_size
);
}
print_copy_assigned
(
this
);
return
*
this
;
}
Sequence
&
operator
=
(
Sequence
&&
s
)
{
std
::
cout
<<
"Move assignment operator: Creating a sequence with "
<<
s
.
m_size
<<
" entries"
<<
std
::
endl
;
if
(
&
s
!=
this
)
{
delete
[]
m_data
;
m_size
=
s
.
m_size
;
...
...
@@ -61,6 +65,9 @@ public:
s
.
m_size
=
0
;
s
.
m_data
=
nullptr
;
}
print_move_assigned
(
this
);
return
*
this
;
}
...
...
example/example-sequences-and-iterators.py
View file @
f4f2afb6
...
...
@@ -28,3 +28,19 @@ rev[0::2] = Sequence([2.0, 2.0, 2.0])
for
i
in
rev
:
print
(
i
,
end
=
' '
)
print
(
''
)
from
example
import
ConstructorStats
cstats
=
ConstructorStats
.
get
(
Sequence
)
print
(
"Instances not destroyed:"
,
cstats
.
alive
())
s
=
None
print
(
"Instances not destroyed:"
,
cstats
.
alive
())
rev
=
None
print
(
"Instances not destroyed:"
,
cstats
.
alive
())
rev2
=
None
print
(
"Instances not destroyed:"
,
cstats
.
alive
())
print
(
"Constructor values:"
,
cstats
.
values
())
print
(
"Default constructions:"
,
cstats
.
default_constructions
)
print
(
"Copy constructions:"
,
cstats
.
copy_constructions
)
print
(
"Move constructions:"
,
cstats
.
move_constructions
>=
1
)
print
(
"Copy assignments:"
,
cstats
.
copy_assignments
)
print
(
"Move assignments:"
,
cstats
.
move_assignments
)
example/example-sequences-and-iterators.ref
View file @
f4f2afb6
Value constructor: Creating a sequence with 5 entries
s = <example.Sequence object at 0x
10c786c7
0>
### Sequence @ 0x1535b00 created of size 5
s = <example.Sequence object at 0x
7efc73cfa4e
0>
len(s) = 5
s[0], s[3] = 0.000000 0.000000
12.34 in s: False
12.34 in s: True
s[0], s[3] = 12.340000 56.779999
Value constructor: Creating a sequence with 5 entries
Move constructor: Creating a sequence with 5 entries
Freeing a sequence with 0 entries
Value constructor: Creating a sequence with 5 entries
### Sequence @ 0x7fff22a45068 created of size 5
### Sequence @ 0x1538b90 created via move constructor
### Sequence @ 0x7fff22a45068 destroyed
### Sequence @ 0x1538bf0 created of size 5
rev[0], rev[1], rev[2], rev[3], rev[4] = 0.000000 56.779999 0.000000 0.000000 12.340000
0.0 56.779998779
3
0.0 0.0 12.340000152
6
0.0 56.779998779
3
0.0 0.0 12.340000152
6
0.0 56.779998779
296875
0.0 0.0 12.340000152
58789
0.0 56.779998779
296875
0.0 0.0 12.340000152
58789
True
Value constructor: Creating a sequence with 3 entries
Freeing a sequence with 3 entries
2.0 56.7799987793 2.0 0.0 2.0
Freeing a sequence with 5 entries
Freeing a sequence with 5 entries
Freeing a sequence with 5 entries
### Sequence @ 0x153c4b0 created of size 3 from std::vector
### Sequence @ 0x153c4b0 destroyed
2.0 56.779998779296875 2.0 0.0 2.0
Instances not destroyed: 3
### Sequence @ 0x1535b00 destroyed
Instances not destroyed: 2
### Sequence @ 0x1538b90 destroyed
Instances not destroyed: 1
### Sequence @ 0x1538bf0 destroyed
Instances not destroyed: 0
Constructor values: ['of size', '5', 'of size', '5', 'of size', '5', 'of size', '3', 'from std::vector']
Default constructions: 0
Copy constructions: 0
Move constructions: True
Copy assignments: 0
Move assignments: 0
example/example-smart-ptr.cpp
View file @
f4f2afb6
...
...
@@ -15,7 +15,7 @@
class
MyObject1
:
public
Object
{
public:
MyObject1
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
print_created
(
this
,
toString
())
;
}
std
::
string
toString
()
const
{
...
...
@@ -24,7 +24,7 @@ public:
protected:
virtual
~
MyObject1
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
print_destroyed
(
this
)
;
}
private:
...
...
@@ -35,7 +35,7 @@ private:
class
MyObject2
{
public:
MyObject2
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
print_created
(
this
,
toString
())
;
}
std
::
string
toString
()
const
{
...
...
@@ -43,7 +43,7 @@ public:
}
virtual
~
MyObject2
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
print_destroyed
(
this
)
;
}
private:
...
...
@@ -54,7 +54,7 @@ private:
class
MyObject3
:
public
std
::
enable_shared_from_this
<
MyObject3
>
{
public:
MyObject3
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
print_created
(
this
,
toString
())
;
}
std
::
string
toString
()
const
{
...
...
@@ -62,7 +62,7 @@ public:
}
virtual
~
MyObject3
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
print_destroyed
(
this
)
;
}
private:
...
...
@@ -144,4 +144,7 @@ void init_ex_smart_ptr(py::module &m) {
m
.
def
(
"print_myobject3_4"
,
&
print_myobject3_4
);
py
::
implicitly_convertible
<
py
::
int_
,
MyObject1
>
();
// Expose constructor stats for the ref type
m
.
def
(
"cstats_ref"
,
&
ConstructorStats
::
get
<
ref_tag
>
);
}
example/example-smart-ptr.py
View file @
f4f2afb6
...
...
@@ -68,3 +68,18 @@ for o in [MyObject3(9), make_myobject3_1(), make_myobject3_2()]:
print_myobject3_2
(
o
)
print_myobject3_3
(
o
)
print_myobject3_4
(
o
)
from
example
import
ConstructorStats
,
cstats_ref
,
Object
cstats
=
[
ConstructorStats
.
get
(
Object
),
ConstructorStats
.
get
(
MyObject1
),
ConstructorStats
.
get
(
MyObject2
),
ConstructorStats
.
get
(
MyObject3
),
cstats_ref
()]
print
(
"Instances not destroyed:"
,
[
x
.
alive
()
for
x
in
cstats
])
o
=
None
print
(
"Instances not destroyed:"
,
[
x
.
alive
()
for
x
in
cstats
])
print
(
"Object value constructions:"
,
[
x
.
values
()
for
x
in
cstats
])
print
(
"Default constructions:"
,
[
x
.
default_constructions
for
x
in
cstats
])
print
(
"Copy constructions:"
,
[
x
.
copy_constructions
for
x
in
cstats
])
#print("Move constructions:", [x.move_constructions >= 0 for x in cstats]) # Doesn't invoke any
print
(
"Copy assignments:"
,
[
x
.
copy_assignments
for
x
in
cstats
])
print
(
"Move assignments:"
,
[
x
.
move_assignments
for
x
in
cstats
])
example/example-smart-ptr.ref
View file @
f4f2afb6
MyObject1[1] constructor
Initialized ref from pointer 0x1347ba0
MyObject1[2] constructor
Initialized ref from pointer 0x12b9270
Initialized ref from ref 0x12b9270
Destructing ref 0x12b9270
MyObject1[3] constructor
Initialized ref from pointer 0x12a2a90
### Object @ 0xdeffd0 created via default constructor
### MyObject1 @ 0xdeffd0 created MyObject1[1]
### ref<MyObject1> @ 0x7f6a2e03c4a8 created from pointer 0xdeffd0
### Object @ 0xe43f50 created via default constructor
### MyObject1 @ 0xe43f50 created MyObject1[2]
### ref<Object> @ 0x7fff136845d0 created from pointer 0xe43f50
### ref<MyObject1> @ 0x7f6a2c32aad8 created via copy constructor with pointer 0xe43f50
### ref<Object> @ 0x7fff136845d0 destroyed
### Object @ 0xee8cf0 created via default constructor
### MyObject1 @ 0xee8cf0 created MyObject1[3]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee8cf0
Reference count = 1
MyObject1[1]
Created empty ref
Assigning ref 0x1347ba
0
Initialized ref from ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xdeffd
0
MyObject1[1]
Destructing ref 0x1347ba0
Destructing ref 0x1347ba0
Created empty ref
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845a8 destroyed
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd
0
MyObject1[1]
Destructing ref 0x1347ba0
Created empty ref
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd
0
MyObject1[1]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
Reference count = 1
MyObject1[2]
Created empty ref
Assigning ref 0x12b927
0
Initialized ref from ref 0x12b927
0
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f5
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xe43f5
0
MyObject1[2]
Destructing ref 0x12b9270
Destructing ref 0x12b9270
Created empty ref
Assigning ref 0x12b927
0
### ref<Object> @ 0x7fff136845a8 destroyed
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f5
0
MyObject1[2]
Destructing ref 0x12b9270
Created empty ref
Assigning ref 0x12b927
0
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f5
0
MyObject1[2]
Destructing ref 0x12b9270
### ref<Object> @ 0x7fff136845c8 destroyed
Reference count = 1
MyObject1[3]
Created empty ref
Assigning ref 0x12a2a9
0
Initialized ref from ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8cf
0
MyObject1[3]
Destructing ref 0x12a2a90
Destructing ref 0x12a2a90
Created empty ref
Assigning ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845a8 destroyed
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf
0
MyObject1[3]
Destructing ref 0x12a2a90
Created empty ref
Assigning ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf
0
MyObject1[3]
Destructing ref 0x12a2a90
Destructing ref 0x12b9270
MyObject1[2] destructor
Destructing ref 0x1347ba0
MyObject1[1] destructor
MyObject1[4] constructor
Initialized ref from pointer 0x1347ba0
MyObject1[5] constructor
Initialized ref from pointer 0x1299190
Initialized ref from ref 0x1299190
Destructing ref 0x1299190
MyObject1[6] constructor
Initialized ref from pointer 0x133e2f0
Destructing ref 0x12a2a90
MyObject1[3] destructor
### ref<Object> @ 0x7fff136845c8 destroyed
### MyObject1 @ 0xe43f50 destroyed
### Object @ 0xe43f50 destroyed
### ref<MyObject1> @ 0x7f6a2c32aad8 destroyed
### MyObject1 @ 0xdeffd0 destroyed
### Object @ 0xdeffd0 destroyed
### ref<MyObject1> @ 0x7f6a2e03c4a8 destroyed
### Object @ 0xee8310 created via default constructor
### MyObject1 @ 0xee8310 created MyObject1[4]
### ref<MyObject1> @ 0x7f6a2e03c4a8 created from pointer 0xee8310
### Object @ 0xee8470 created via default constructor
### MyObject1 @ 0xee8470 created MyObject1[5]
### ref<MyObject1> @ 0x7fff136845d0 created from pointer 0xee8470
### ref<MyObject1> @ 0x7f6a2c32aad8 created via copy constructor with pointer 0xee8470
### ref<MyObject1> @ 0x7fff136845d0 destroyed
### Object @ 0xee95a0 created via default constructor
### MyObject1 @ 0xee95a0 created MyObject1[6]
### ref<MyObject1> @ 0x7f6a2c32ab38 created from pointer 0xee95a0
### MyObject1 @ 0xee8cf0 destroyed
### Object @ 0xee8cf0 destroyed
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
<example.MyObject1 object at 0x7f6a2e03c480>
MyObject1[4]
Created empty ref
Assigning ref 0x1347ba
0
Initialized ref from ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee831
0
MyObject1[4]
Destructing ref 0x1347ba0
Destructing ref 0x1347ba0
Created empty ref
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845a8 destroyed
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
Destructing ref 0x1347ba0
Created empty ref
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
MyObject1[4]
Created empty ref
Assigning ref 0x1347ba
0
Initialized ref from ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee831
0
MyObject1[4]
Destructing ref 0x1347ba0
Destructing ref 0x1347ba0
Created empty ref
Assigning ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845a8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
Destructing ref 0x1347ba0
Created empty ref
Assigning ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
Destructing ref 0x1347ba0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
<example.MyObject1 object at 0x7f6a2c32aab0>
MyObject1[5]
Created empty ref
Assigning ref 0x129919
0
Initialized ref from ref 0x129919
0
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee847
0
MyObject1[5]
Destructing ref 0x1299190
Destructing ref 0x1299190
Created empty ref
Assigning ref 0x129919
0
### ref<Object> @ 0x7fff136845a8 destroyed
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
Destructing ref 0x1299190
Created empty ref
Assigning ref 0x129919
0
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
Destructing ref 0x1299190
### ref<Object> @ 0x7fff136845c8 destroyed
MyObject1[5]
Created empty ref
Assigning ref 0x129919
0
Initialized ref from ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee847
0
MyObject1[5]
Destructing ref 0x1299190
Destructing ref 0x1299190
Created empty ref
Assigning ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845a8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
Destructing ref 0x1299190
Created empty ref
Assigning ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
Destructing ref 0x1299190
### ref<MyObject1> @ 0x7fff136845c8 destroyed
<example.MyObject1 object at 0x7f6a2c32ab10>
MyObject1[6]
Created empty ref
Assigning ref 0x133e2f
0
Initialized ref from ref 0x133e2f
0
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee95a
0
MyObject1[6]
Destructing ref 0x133e2f0
Destructing ref 0x133e2f0
Created empty ref
Assigning ref 0x133e2f
0
### ref<Object> @ 0x7fff136845a8 destroyed
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
Destructing ref 0x133e2f0
Created empty ref
Assigning ref 0x133e2f
0
### ref<Object> @ 0x7fff136845c8 destroyed
### ref<Object> @ 0x7fff136845c8 created via default constructor
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
Destructing ref 0x133e2f0
### ref<Object> @ 0x7fff136845c8 destroyed
MyObject1[6]
Created empty ref
Assigning ref 0x133e2f
0
Initialized ref from ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee95a
0
MyObject1[6]
Destructing ref 0x133e2f0
Destructing ref 0x133e2f0
Created empty ref
Assigning ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845a8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
Destructing ref 0x133e2f0
Created empty ref
Assigning ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
Destructing ref 0x133e2f0
MyObject1[7] constructor
Initialized ref from pointer 0x133f3a0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
7
### Object @ 0xee97f0 created via default constructor
### MyObject1 @ 0xee97f0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee97f0
MyObject1[7]
Destructing ref 0x133f3a0
MyObject1[7] destructor
Created empty ref
MyObject1[7] constructor
Initialized ref from pointer 0x12a2a90
Assigning ref 0x12a2a90
Initialized ref from ref 0x12a2a90
### MyObject1 @ 0xee97f0 destroyed
### Object @ 0xee97f0 destroyed
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### Object @ 0xee99e0 created via default constructor
### MyObject1 @ 0xee99e0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee99e0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee99e0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee99e0
MyObject1[7]
Destructing ref 0x12a2a90
Destructing ref 0x12a2a90
Destructing ref 0x12a2a90
MyObject1[7] destructor
Created empty ref
MyObject1[7] constructor
Initialized ref from pointer 0x133f3a0
Assigning ref 0x133f3a0
### ref<MyObject1> @ 0x7fff136845a8 destroyed
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### MyObject1 @ 0xee99e0 destroyed
### Object @ 0xee99e0 destroyed
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### Object @ 0xee97f0 created via default constructor
### MyObject1 @ 0xee97f0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee97f0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee97f0
MyObject1[7]
Destructing ref 0x133f3a0
Destructing ref 0x133f3a0
MyObject1[7] destructor
Created empty ref
MyObject1[7] constructor
Initialized ref from pointer 0x12a2a90
Assigning ref 0x12a2a90
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### MyObject1 @ 0xee97f0 destroyed
### Object @ 0xee97f0 destroyed
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
### Object @ 0xee99e0 created via default constructor
### MyObject1 @ 0xee99e0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee99e0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee99e0
MyObject1[7]
Destructing ref 0x12a2a90
Destructing ref 0x12a2a90
MyObject1[7] destructor
Destructing ref 0x133e2f0
MyObject1[6] destructor
Destructing ref 0x1299190
MyObject1[5] destructor
Destructing ref 0x1347ba0
MyObject1[4] destructor
MyObject2[8] constructor
MyObject2[6] constructor
MyObject2[7] constructor
### ref<MyObject1> @ 0x7fff136845c8 destroyed
### MyObject1 @ 0xee99e0 destroyed
### Object @ 0xee99e0 destroyed
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
### MyObject1 @ 0xee95a0 destroyed
### Object @ 0xee95a0 destroyed
### ref<MyObject1> @ 0x7f6a2c32ab38 destroyed
### MyObject1 @ 0xee8470 destroyed
### Object @ 0xee8470 destroyed
### ref<MyObject1> @ 0x7f6a2c32aad8 destroyed
### MyObject1 @ 0xee8310 destroyed
### Object @ 0xee8310 destroyed
### ref<MyObject1> @ 0x7f6a2e03c4a8 destroyed
### MyObject2 @ 0xe43f50 created MyObject2[8]
### MyObject2 @ 0xee95a0 created MyObject2[6]
### MyObject2 @ 0xee95d0 created MyObject2[7]
<example.MyObject2 object at 0x7f6a2dfc8768>
MyObject2[8]
MyObject2[8]
MyObject2[8]
MyObject2[8]
<example.MyObject2 object at 0x7f6a2dfc86c0>
MyObject2[6]
MyObject2[6]
MyObject2[6]
MyObject2[6]
<example.MyObject2 object at 0x7f6a2c32d030>
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[6] destructor
MyObject2[8] destructor
MyObject3[9] constructor
MyObject3[8] constructor
MyObject3[9] constructor
MyObject2[7] destructor
### MyObject2 @ 0xee95a0 destroyed
### MyObject2 @ 0xe43f50 destroyed
### MyObject3 @ 0xee9ac0 created MyObject3[9]
### MyObject3 @ 0xe43f90 created MyObject3[8]
### MyObject3 @ 0xeea7d0 created MyObject3[9]
### MyObject2 @ 0xee95d0 destroyed
<example.MyObject3 object at 0x7f6a2dfc8768>
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
<example.MyObject3 object at 0x7f6a2dfc86c0>
MyObject3[8]
MyObject3[8]
MyObject3[8]
MyObject3[8]
<example.MyObject3 object at 0x7f6a2c32d068>
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[8] destructor
MyObject3[9] destructor
Reference count = 1
Reference count = 1
Reference count = 1
<example.MyObject1 object at 0x7f830b500e68>
<example.MyObject1 object at 0x7f830b4fc688>
<example.MyObject1 object at 0x7f830b4fc5a8>
7
<example.MyObject2 object at 0x7f830b50b330>
<example.MyObject2 object at 0x7f830b50bdb0>
<example.MyObject2 object at 0x7f83098f6330>
<example.MyObject3 object at 0x7f830b50b330>
<example.MyObject3 object at 0x7f830b50bdb0>
<example.MyObject3 object at 0x7f83098f6370>
MyObject3[9] destructor
### MyObject3 @ 0xe43f90 destroyed
### MyObject3 @ 0xee9ac0 destroyed
Instances not destroyed: [0, 0, 0, 1, 0]
### MyObject3 @ 0xeea7d0 destroyed
Instances not destroyed: [0, 0, 0, 0, 0]
Object value constructions: [[], ['MyObject1[1]', 'MyObject1[2]', 'MyObject1[3]', 'MyObject1[4]', 'MyObject1[5]', 'MyObject1[6]', 'MyObject1[7]', 'MyObject1[7]', 'MyObject1[7]', 'MyObject1[7]'], ['MyObject2[8]', 'MyObject2[6]', 'MyObject2[7]'], ['MyObject3[9]', 'MyObject3[8]', 'MyObject3[9]'], ['from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer', 'from pointer']]
Default constructions: [10, 0, 0, 0, 30]
Copy constructions: [0, 0, 0, 0, 12]
Copy assignments: [0, 0, 0, 0, 30]
Move assignments: [0, 0, 0, 0, 0]
example/example-virtual-functions.cpp
View file @
f4f2afb6
...
...
@@ -8,18 +8,16 @@
*/
#include "example.h"
#include "constructor-stats.h"
#include <pybind11/functional.h>
/* This is an example class that we'll want to be able to extend from Python */
class
ExampleVirt
{
public:
ExampleVirt
(
int
state
)
:
state
(
state
)
{
cout
<<
"Constructing ExampleVirt.."
<<
endl
;
}
~
ExampleVirt
()
{
cout
<<
"Destructing ExampleVirt.."
<<
endl
;
}
ExampleVirt
(
int
state
)
:
state
(
state
)
{
print_created
(
this
,
state
);
}
ExampleVirt
(
const
ExampleVirt
&
e
)
:
state
(
e
.
state
)
{
print_copy_created
(
this
);
}
ExampleVirt
(
ExampleVirt
&&
e
)
:
state
(
e
.
state
)
{
print_move_created
(
this
);
e
.
state
=
0
;
}
~
ExampleVirt
()
{
print_destroyed
(
this
);
}
virtual
int
run
(
int
value
)
{
std
::
cout
<<
"Original implementation of ExampleVirt::run(state="
<<
state
...
...
@@ -71,8 +69,8 @@ public:
class
NonCopyable
{
public:
NonCopyable
(
int
a
,
int
b
)
:
value
{
new
int
(
a
*
b
)}
{}
NonCopyable
(
NonCopyable
&&
)
=
default
;
NonCopyable
(
int
a
,
int
b
)
:
value
{
new
int
(
a
*
b
)}
{
print_created
(
this
,
a
,
b
);
}
NonCopyable
(
NonCopyable
&&
o
)
{
value
=
std
::
move
(
o
.
value
);
print_move_created
(
this
);
}
NonCopyable
(
const
NonCopyable
&
)
=
delete
;
NonCopyable
()
=
delete
;
void
operator
=
(
const
NonCopyable
&
)
=
delete
;
...
...
@@ -80,7 +78,7 @@ public:
std
::
string
get_value
()
const
{
if
(
value
)
return
std
::
to_string
(
*
value
);
else
return
"(null)"
;
}
~
NonCopyable
()
{
std
::
cout
<<
"NonCopyable destructor @ "
<<
this
<<
"; value = "
<<
get_value
()
<<
std
::
endl
;
}
~
NonCopyable
()
{
print_destroyed
(
this
)
;
}
private:
std
::
unique_ptr
<
int
>
value
;
...
...
@@ -90,11 +88,11 @@ private:
// when it is not referenced elsewhere, but copied if it is still referenced.
class
Movable
{
public:
Movable
(
int
a
,
int
b
)
:
value
{
a
+
b
}
{}
Movable
(
const
Movable
&
m
)
{
value
=
m
.
value
;
std
::
cout
<<
"Movable @ "
<<
this
<<
" copy constructor"
<<
std
::
endl
;
}
Movable
(
Movable
&&
m
)
{
value
=
std
::
move
(
m
.
value
);
std
::
cout
<<
"Movable @ "
<<
this
<<
" move constructor"
<<
std
::
endl
;
}
Movable
(
int
a
,
int
b
)
:
value
{
a
+
b
}
{
print_created
(
this
,
a
,
b
);
}
Movable
(
const
Movable
&
m
)
{
value
=
m
.
value
;
print_copy_created
(
this
)
;
}
Movable
(
Movable
&&
m
)
{
value
=
std
::
move
(
m
.
value
);
print_move_created
(
this
)
;
}
int
get_value
()
const
{
return
value
;
}
~
Movable
()
{
std
::
cout
<<
"Movable destructor @ "
<<
this
<<
"; value = "
<<
get_value
()
<<
std
::
endl
;
}
~
Movable
()
{
print_destroyed
(
this
)
;
}
private:
int
value
;
};
...
...
@@ -305,5 +303,6 @@ void init_ex_virtual_functions(py::module &m) {
m
.
def
(
"runExampleVirtBool"
,
&
runExampleVirtBool
);
m
.
def
(
"runExampleVirtVirtual"
,
&
runExampleVirtVirtual
);
m
.
def
(
"cstats_debug"
,
&
ConstructorStats
::
get
<
ExampleVirt
>
);
initialize_inherited_virtuals
(
m
);
}
example/example-virtual-functions.py
View file @
f4f2afb6
...
...
@@ -37,8 +37,6 @@ print(runExampleVirt(ex12p, 20))
print
(
runExampleVirtBool
(
ex12p
))
runExampleVirtVirtual
(
ex12p
)
sys
.
stdout
.
flush
()
class
VI_AR
(
A_Repeat
):
def
unlucky_number
(
self
):
return
99
...
...
@@ -122,3 +120,16 @@ try:
except
RuntimeError
as
e
:
# Don't print the exception message here because it differs under debug/non-debug mode
print
(
"Caught expected exception"
)
from
example
import
ConstructorStats
del
ex12
del
ex12p
del
obj
del
ncv1
del
ncv2
cstats
=
[
ConstructorStats
.
get
(
ExampleVirt
),
ConstructorStats
.
get
(
NonCopyable
),
ConstructorStats
.
get
(
Movable
)]
print
(
"Instances not destroyed:"
,
[
x
.
alive
()
for
x
in
cstats
])
print
(
"Constructor values:"
,
[
x
.
values
()
for
x
in
cstats
])
print
(
"Copy constructions:"
,
[
x
.
copy_constructions
for
x
in
cstats
])
print
(
"Move constructions:"
,
[
cstats
[
i
].
move_constructions
>=
1
for
i
in
range
(
1
,
len
(
cstats
))])
example/example-virtual-functions.ref
View file @
f4f2afb6
Constructing ExampleVirt..
### ExampleVirt @ 0x2073a90 created 10
Original implementation of ExampleVirt::run(state=10, value=20)
30
Caught expected exception: Tried to call pure virtual function "ExampleVirt::pure_virtual"
Constructing ExampleVirt..
### ExampleVirt @ 0x2076a00 created 11
ExtendedExampleVirt::run(20), calling parent..
Original implementation of ExampleVirt::run(state=11, value=21)
32
...
...
@@ -78,20 +78,29 @@ VI_DT says: quack quack quack
Unlucky = 1234
Lucky = -4.25
2^2 * 3^2 =
NonCopyable destructor @ 0x1a6c3f0; value = (null)
### NonCopyable @ 0x207df10 created 4 9
### NonCopyable @ 0x7ffcfe866228 created via move constructor
### NonCopyable @ 0x207df10 destroyed
36
NonCopyable
destructor @ 0x7ffc6d1fbaa8; value = 36
###
NonCopyable
@ 0x7ffcfe866228 destroyed
4 + 5 =
Movable @ 0x7ffc6d1fbacc copy constructor
### Movable @ 0x207e230 created 4 5
### Movable @ 0x7ffcfe86624c created via copy constructor
9
Movable
destructor @ 0x7ffc6d1fbacc; value = 9
###
Movable
@ 0x7ffcfe86624c destroyed
7 + 7 =
Movable @ 0x7ffc6d1fbacc move constructor
Movable destructor @ 0x1a6c4d0; value = 14
### Movable @ 0x20259e0 created 7 7
### Movable @ 0x7ffcfe86624c created via move constructor
### Movable @ 0x20259e0 destroyed
14
Movable destructor @ 0x7ffc6d1fbacc; value = 14
### Movable @ 0x7ffcfe86624c destroyed
### NonCopyable @ 0x2025a00 created 9 9
Caught expected exception
NonCopyable destructor @ 0x29a64b0; value = 81
Movable destructor @ 0x1a6c410; value = 9
Destructing ExampleVirt..
Destructing ExampleVirt..
### ExampleVirt @ 0x2073a90 destroyed
### ExampleVirt @ 0x2076a00 destroyed
### Movable @ 0x207e230 destroyed
### NonCopyable @ 0x2025a00 destroyed
Instances not destroyed: [0, 0, 0]
Constructor values: [['10', '11'], ['4', '9', '9', '9'], ['4', '5', '7', '7']]
Copy constructions: [0, 0, 1]
Move constructions: [True, True]
example/example.cpp
View file @
f4f2afb6
...
...
@@ -8,6 +8,7 @@
*/
#include "example.h"
#include "constructor-stats.h"
void
init_ex_methods_and_attributes
(
py
::
module
&
);
void
init_ex_python_types
(
py
::
module
&
);
...
...
@@ -34,9 +35,24 @@ void init_issues(py::module &);
void
init_eigen
(
py
::
module
&
);
#endif
void
bind_ConstructorStats
(
py
::
module
&
m
)
{
py
::
class_
<
ConstructorStats
>
(
m
,
"ConstructorStats"
)
.
def
(
"alive"
,
&
ConstructorStats
::
alive
)
.
def
(
"values"
,
&
ConstructorStats
::
values
)
.
def_readwrite
(
"default_constructions"
,
&
ConstructorStats
::
default_constructions
)
.
def_readwrite
(
"copy_assignments"
,
&
ConstructorStats
::
copy_assignments
)
.
def_readwrite
(
"move_assignments"
,
&
ConstructorStats
::
move_assignments
)
.
def_readwrite
(
"copy_constructions"
,
&
ConstructorStats
::
copy_constructions
)
.
def_readwrite
(
"move_constructions"
,
&
ConstructorStats
::
move_constructions
)
.
def_static
(
"get"
,
(
ConstructorStats
&
(
*
)(
py
::
object
))
&
ConstructorStats
::
get
,
py
::
return_value_policy
::
reference_internal
)
;
}
PYBIND11_PLUGIN
(
example
)
{
py
::
module
m
(
"example"
,
"pybind example plugin"
);
bind_ConstructorStats
(
m
);
init_ex_methods_and_attributes
(
m
);
init_ex_python_types
(
m
);
init_ex_operator_overloading
(
m
);
...
...
example/issues.cpp
View file @
f4f2afb6
...
...
@@ -8,11 +8,18 @@
*/
#include "example.h"
#include "constructor-stats.h"
#include <pybind11/stl.h>
#include <pybind11/operators.h>
PYBIND11_DECLARE_HOLDER_TYPE
(
T
,
std
::
shared_ptr
<
T
>
);
#define TRACKERS(CLASS) CLASS() { print_default_created(this); } ~CLASS() { print_destroyed(this); }
struct
NestABase
{
int
value
=
-
2
;
TRACKERS
(
NestABase
)
};
struct
NestA
:
NestABase
{
int
value
=
3
;
NestA
&
operator
+=
(
int
i
)
{
value
+=
i
;
return
*
this
;
}
TRACKERS
(
NestA
)
};
struct
NestB
{
NestA
a
;
int
value
=
4
;
NestB
&
operator
-=
(
int
i
)
{
value
-=
i
;
return
*
this
;
}
TRACKERS
(
NestB
)
};
struct
NestC
{
NestB
b
;
int
value
=
5
;
NestC
&
operator
*=
(
int
i
)
{
value
*=
i
;
return
*
this
;
}
TRACKERS
(
NestC
)
};
void
init_issues
(
py
::
module
&
m
)
{
py
::
module
m2
=
m
.
def_submodule
(
"issues"
);
...
...
@@ -159,12 +166,6 @@ void init_issues(py::module &m) {
;
// Issue #328: first member in a class can't be used in operators
#define TRACKERS(CLASS) CLASS() { std::cout << #CLASS "@" << this << " constructor\n"; } \
~CLASS() { std::cout << #CLASS "@" << this << " destructor\n"; }
struct
NestABase
{
int
value
=
-
2
;
TRACKERS
(
NestABase
)
};
struct
NestA
:
NestABase
{
int
value
=
3
;
NestA
&
operator
+=
(
int
i
)
{
value
+=
i
;
return
*
this
;
}
TRACKERS
(
NestA
)
};
struct
NestB
{
NestA
a
;
int
value
=
4
;
NestB
&
operator
-=
(
int
i
)
{
value
-=
i
;
return
*
this
;
}
TRACKERS
(
NestB
)
};
struct
NestC
{
NestB
b
;
int
value
=
5
;
NestC
&
operator
*=
(
int
i
)
{
value
*=
i
;
return
*
this
;
}
TRACKERS
(
NestC
)
};
py
::
class_
<
NestABase
>
(
m2
,
"NestABase"
).
def
(
py
::
init
<>
()).
def_readwrite
(
"value"
,
&
NestABase
::
value
);
py
::
class_
<
NestA
>
(
m2
,
"NestA"
).
def
(
py
::
init
<>
()).
def
(
py
::
self
+=
int
())
.
def
(
"as_base"
,
[](
NestA
&
a
)
->
NestABase
&
{
return
(
NestABase
&
)
a
;
},
py
::
return_value_policy
::
reference_internal
);
...
...
example/issues.ref
View file @
f4f2afb6
...
...
@@ -24,15 +24,15 @@ Failed as expected: Incompatible constructor arguments. The following argument t
1. example.issues.StrIssue(arg0: int)
2. example.issues.StrIssue()
Invoked with: no, such, constructor
NestABase
@
0x1
1
5
2940
constructor
NestA
@
0x1
1
5
2940
constructor
NestABase
@0x11f9350
constructor
NestA
@0x11f9350
constructor
NestB
@0x11f9350
constructor
NestABase
@0x112d0d0
constructor
NestA
@0x112d0d0
constructor
NestB
@0x112d0d0
constructor
NestC
@0x112d0d0
constructor
###
NestABase
@
0x15
eb630 created via default
constructor
###
NestA
@
0x15
eb630 created via default
constructor
###
NestABase
@ 0x1704000 created via default
constructor
###
NestA
@ 0x1704000 created via default
constructor
###
NestB
@ 0x1704000 created via default
constructor
###
NestABase
@ 0x1633110 created via default
constructor
###
NestA
@ 0x1633110 created via default
constructor
###
NestB
@ 0x1633110 created via default
constructor
###
NestC
@ 0x1633110 created via default
constructor
13
103
1003
...
...
@@ -43,13 +43,13 @@ NestC@0x112d0d0 constructor
42
-2
42
NestC
@0x112d0d
0 destr
uctor
NestB
@0x112d0d
0 destr
uctor
NestA
@0x112d0d
0 destr
uctor
NestABase
@0x112d0d
0 destr
uctor
###
NestC
@ 0x163311
0 destr
oyed
###
NestB
@ 0x163311
0 destr
oyed
###
NestA
@ 0x163311
0 destr
oyed
###
NestABase
@ 0x163311
0 destr
oyed
42
NestA
@0x115294
0 destr
uctor
NestABase
@0x115294
0 destr
uctor
NestB
@0x11f935
0 destr
uctor
NestA
@0x11f935
0 destr
uctor
NestABase
@0x11f935
0 destr
uctor
###
NestA
@ 0x15eb63
0 destr
oyed
###
NestABase
@ 0x15eb63
0 destr
oyed
###
NestB
@ 0x170400
0 destr
oyed
###
NestA
@ 0x170400
0 destr
oyed
###
NestABase
@ 0x170400
0 destr
oyed
example/object.h
View file @
f4f2afb6
...
...
@@ -2,15 +2,16 @@
#define __OBJECT_H
#include <atomic>
#include "constructor-stats.h"
/// Reference counted object base class
class
Object
{
public:
/// Default constructor
Object
()
{
}
Object
()
{
print_default_created
(
this
);
}
/// Copy constructor
Object
(
const
Object
&
)
:
m_refCount
(
0
)
{}
Object
(
const
Object
&
)
:
m_refCount
(
0
)
{
print_copy_created
(
this
);
}
/// Return the current reference count
int
getRefCount
()
const
{
return
m_refCount
;
};
...
...
@@ -37,11 +38,17 @@ protected:
/** \brief Virtual protected deconstructor.
* (Will only be called by \ref ref)
*/
virtual
~
Object
()
{
}
virtual
~
Object
()
{
print_destroyed
(
this
);
}
private:
mutable
std
::
atomic
<
int
>
m_refCount
{
0
};
};
// Tag class used to track constructions of ref objects. When we track constructors, below, we
// track and print out the actual class (e.g. ref<MyObject>), and *also* add a fake tracker for
// ref_tag. This lets us check that the total number of ref<Anything> constructors/destructors is
// correct without having to check each individual ref<Whatever> type individually.
class
ref_tag
{};
/**
* \brief Reference counting helper
*
...
...
@@ -55,37 +62,43 @@ private:
template
<
typename
T
>
class
ref
{
public:
/// Create a nullptr reference
ref
()
:
m_ptr
(
nullptr
)
{
std
::
cout
<<
"Created empty ref"
<<
std
::
endl
;
}
ref
()
:
m_ptr
(
nullptr
)
{
print_default_created
(
this
);
track_default_created
((
ref_tag
*
)
this
)
;
}
/// Construct a reference from a pointer
ref
(
T
*
ptr
)
:
m_ptr
(
ptr
)
{
std
::
cout
<<
"Initialized ref from pointer "
<<
ptr
<<
std
::
endl
;
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
incRef
();
print_created
(
this
,
"from pointer"
,
m_ptr
);
track_created
((
ref_tag
*
)
this
,
"from pointer"
);
}
/// Copy constructor
ref
(
const
ref
&
r
)
:
m_ptr
(
r
.
m_ptr
)
{
std
::
cout
<<
"Initialized ref from ref "
<<
r
.
m_ptr
<<
std
::
endl
;
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
incRef
();
print_copy_created
(
this
,
"with pointer"
,
m_ptr
);
track_copy_created
((
ref_tag
*
)
this
);
}
/// Move constructor
ref
(
ref
&&
r
)
:
m_ptr
(
r
.
m_ptr
)
{
std
::
cout
<<
"Initialized ref with move from ref "
<<
r
.
m_ptr
<<
std
::
endl
;
r
.
m_ptr
=
nullptr
;
print_move_created
(
this
,
"with pointer"
,
m_ptr
);
track_move_created
((
ref_tag
*
)
this
);
}
/// Destroy this reference
~
ref
()
{
std
::
cout
<<
"Destructing ref "
<<
m_ptr
<<
std
::
endl
;
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
decRef
();
print_destroyed
(
this
);
track_destroyed
((
ref_tag
*
)
this
);
}
/// Move another reference into the current one
ref
&
operator
=
(
ref
&&
r
)
{
std
::
cout
<<
"Move-assigning ref "
<<
r
.
m_ptr
<<
std
::
endl
;
print_move_assigned
(
this
,
"pointer"
,
r
.
m_ptr
);
track_move_assigned
((
ref_tag
*
)
this
);
if
(
*
this
==
r
)
return
*
this
;
if
(
m_ptr
)
...
...
@@ -97,7 +110,8 @@ public:
/// Overwrite this reference with another reference
ref
&
operator
=
(
const
ref
&
r
)
{
std
::
cout
<<
"Assigning ref "
<<
r
.
m_ptr
<<
std
::
endl
;
print_copy_assigned
(
this
,
"pointer"
,
r
.
m_ptr
);
track_copy_assigned
((
ref_tag
*
)
this
);
if
(
m_ptr
==
r
.
m_ptr
)
return
*
this
;
if
(
m_ptr
)
...
...
@@ -110,7 +124,8 @@ public:
/// Overwrite this reference with a pointer to another object
ref
&
operator
=
(
T
*
ptr
)
{
std
::
cout
<<
"Assigning ptr "
<<
ptr
<<
" to ref"
<<
std
::
endl
;
print_values
(
this
,
"assigned pointer"
);
track_values
((
ref_tag
*
)
this
,
"assigned pointer"
);
if
(
m_ptr
==
ptr
)
return
*
this
;
if
(
m_ptr
)
...
...
example/run_test.py
View file @
f4f2afb6
...
...
@@ -9,14 +9,16 @@ remove_long_marker = re.compile(r'([0-9])L')
remove_hex
=
re
.
compile
(
r
'0x[0-9a-fA-F]+'
)
shorten_floats
=
re
.
compile
(
r
'([1-9][0-9]*\.[0-9]{4})[0-9]*'
)
relaxed
=
False
def
sanitize
(
lines
):
lines
=
lines
.
split
(
'
\n
'
)
for
i
in
range
(
len
(
lines
)):
line
=
lines
[
i
]
if
line
.
startswith
(
" |"
):
line
=
""
if
line
.
startswith
(
"### "
):
# Constructor/destructor output. Useful for example, but unreliable across compilers;
# testing of proper construction/destruction occurs with ConstructorStats mechanism instead
line
=
""
line
=
remove_unicode_marker
.
sub
(
r
'\1'
,
line
)
line
=
remove_long_marker
.
sub
(
r
'\1'
,
line
)
line
=
remove_hex
.
sub
(
r
'0'
,
line
)
...
...
@@ -28,13 +30,6 @@ def sanitize(lines):
line
=
line
.
replace
(
'example.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
strip
()
if
relaxed
:
lower
=
line
.
lower
()
# The precise pattern of allocations and deallocations is dependent on the compiler
# and optimization level, so we unfortunately can't reliably check it in this kind of test case
if
'constructor'
in
lower
or
'destructor'
in
lower
\
or
'ref'
in
lower
or
'freeing'
in
lower
:
line
=
""
lines
[
i
]
=
line
return
'
\n
'
.
join
(
sorted
([
l
for
l
in
lines
if
l
!=
""
]))
...
...
@@ -44,16 +39,12 @@ if path != '':
os
.
chdir
(
path
)
if
len
(
sys
.
argv
)
<
2
:
print
(
"Syntax: %s
[--relaxed]
<test name>"
%
sys
.
argv
[
0
])
print
(
"Syntax: %s <test name>"
%
sys
.
argv
[
0
])
exit
(
0
)
if
len
(
sys
.
argv
)
==
3
and
sys
.
argv
[
1
]
==
'--relaxed'
:
del
sys
.
argv
[
1
]
relaxed
=
True
name
=
sys
.
argv
[
1
]
try
:
output_bytes
=
subprocess
.
check_output
([
sys
.
executable
,
name
+
".py"
],
output_bytes
=
subprocess
.
check_output
([
sys
.
executable
,
"-u"
,
name
+
".py"
],
stderr
=
subprocess
.
STDOUT
)
except
subprocess
.
CalledProcessError
as
e
:
if
e
.
returncode
==
99
:
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment