Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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__)
...
@@ -65,3 +65,10 @@ print("__name__(example.ExamplePythonTypes) = %s" % ExamplePythonTypes.__name__)
print
(
"__module__(example.ExamplePythonTypes) = %s"
%
ExamplePythonTypes
.
__module__
)
print
(
"__module__(example.ExamplePythonTypes) = %s"
%
ExamplePythonTypes
.
__module__
)
print
(
"__name__(example.ExamplePythonTypes.get_set) = %s"
%
ExamplePythonTypes
.
get_set
.
__name__
)
print
(
"__name__(example.ExamplePythonTypes.get_set) = %s"
%
ExamplePythonTypes
.
get_set
.
__name__
)
print
(
"__module__(example.ExamplePythonTypes.get_set) = %s"
%
ExamplePythonTypes
.
get_set
.
__module__
)
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 @@
...
@@ -2,6 +2,7 @@
5
5
example.ExamplePythonTypes: No constructor defined!
example.ExamplePythonTypes: No constructor defined!
can't set attribute
can't set attribute
### ExamplePythonTypes @ 0x1045b80 created via new_instance
key: key2, value=value2
key: key2, value=value2
key: key, value=value
key: key, value=value
key: key, value=value
key: key, value=value
...
@@ -134,4 +135,6 @@ __name__(example.ExamplePythonTypes) = ExamplePythonTypes
...
@@ -134,4 +135,6 @@ __name__(example.ExamplePythonTypes) = ExamplePythonTypes
__module__(example.ExamplePythonTypes) = example
__module__(example.ExamplePythonTypes) = example
__name__(example.ExamplePythonTypes.get_set) = get_set
__name__(example.ExamplePythonTypes.get_set) = get_set
__module__(example.ExamplePythonTypes.get_set) = example
__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 @@
...
@@ -9,51 +9,55 @@
*/
*/
#include "example.h"
#include "example.h"
#include "constructor-stats.h"
#include <pybind11/operators.h>
#include <pybind11/operators.h>
#include <pybind11/stl.h>
#include <pybind11/stl.h>
class
Sequence
{
class
Sequence
{
public:
public:
Sequence
(
size_t
size
)
:
m_size
(
size
)
{
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
];
m_data
=
new
float
[
size
];
memset
(
m_data
,
0
,
sizeof
(
float
)
*
size
);
memset
(
m_data
,
0
,
sizeof
(
float
)
*
size
);
}
}
Sequence
(
const
std
::
vector
<
float
>
&
value
)
:
m_size
(
value
.
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
];
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
&
value
[
0
],
sizeof
(
float
)
*
m_size
);
memcpy
(
m_data
,
&
value
[
0
],
sizeof
(
float
)
*
m_size
);
}
}
Sequence
(
const
Sequence
&
s
)
:
m_size
(
s
.
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
];
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
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
)
{
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_size
=
0
;
s
.
m_data
=
nullptr
;
s
.
m_data
=
nullptr
;
}
}
~
Sequence
()
{
~
Sequence
()
{
std
::
cout
<<
"Freeing a sequence with "
<<
m_size
<<
" entries"
<<
std
::
endl
;
print_destroyed
(
this
)
;
delete
[]
m_data
;
delete
[]
m_data
;
}
}
Sequence
&
operator
=
(
const
Sequence
&
s
)
{
Sequence
&
operator
=
(
const
Sequence
&
s
)
{
std
::
cout
<<
"Assignment operator: Creating a sequence with "
<<
s
.
m_size
<<
" entries"
<<
std
::
endl
;
if
(
&
s
!=
this
)
{
delete
[]
m_data
;
delete
[]
m_data
;
m_size
=
s
.
m_size
;
m_size
=
s
.
m_size
;
m_data
=
new
float
[
m_size
];
m_data
=
new
float
[
m_size
];
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_size
);
memcpy
(
m_data
,
s
.
m_data
,
sizeof
(
float
)
*
m_size
);
}
print_copy_assigned
(
this
);
return
*
this
;
return
*
this
;
}
}
Sequence
&
operator
=
(
Sequence
&&
s
)
{
Sequence
&
operator
=
(
Sequence
&&
s
)
{
std
::
cout
<<
"Move assignment operator: Creating a sequence with "
<<
s
.
m_size
<<
" entries"
<<
std
::
endl
;
if
(
&
s
!=
this
)
{
if
(
&
s
!=
this
)
{
delete
[]
m_data
;
delete
[]
m_data
;
m_size
=
s
.
m_size
;
m_size
=
s
.
m_size
;
...
@@ -61,6 +65,9 @@ public:
...
@@ -61,6 +65,9 @@ public:
s
.
m_size
=
0
;
s
.
m_size
=
0
;
s
.
m_data
=
nullptr
;
s
.
m_data
=
nullptr
;
}
}
print_move_assigned
(
this
);
return
*
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])
...
@@ -28,3 +28,19 @@ rev[0::2] = Sequence([2.0, 2.0, 2.0])
for
i
in
rev
:
for
i
in
rev
:
print
(
i
,
end
=
' '
)
print
(
i
,
end
=
' '
)
print
(
''
)
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
### Sequence @ 0x1535b00 created of size 5
s = <example.Sequence object at 0x
10c786c7
0>
s = <example.Sequence object at 0x
7efc73cfa4e
0>
len(s) = 5
len(s) = 5
s[0], s[3] = 0.000000 0.000000
s[0], s[3] = 0.000000 0.000000
12.34 in s: False
12.34 in s: False
12.34 in s: True
12.34 in s: True
s[0], s[3] = 12.340000 56.779999
s[0], s[3] = 12.340000 56.779999
Value constructor: Creating a sequence with 5 entries
### Sequence @ 0x7fff22a45068 created of size 5
Move constructor: Creating a sequence with 5 entries
### Sequence @ 0x1538b90 created via move constructor
Freeing a sequence with 0 entries
### Sequence @ 0x7fff22a45068 destroyed
Value constructor: Creating a sequence with 5 entries
### 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
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
296875
0.0 0.0 12.340000152
58789
0.0 56.779998779
3
0.0 0.0 12.340000152
6
0.0 56.779998779
296875
0.0 0.0 12.340000152
58789
True
True
Value constructor: Creating a sequence with 3 entries
### Sequence @ 0x153c4b0 created of size 3 from std::vector
Freeing a sequence with 3 entries
### Sequence @ 0x153c4b0 destroyed
2.0 56.7799987793 2.0 0.0 2.0
2.0 56.779998779296875 2.0 0.0 2.0
Freeing a sequence with 5 entries
Instances not destroyed: 3
Freeing a sequence with 5 entries
### Sequence @ 0x1535b00 destroyed
Freeing a sequence with 5 entries
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 @@
...
@@ -15,7 +15,7 @@
class
MyObject1
:
public
Object
{
class
MyObject1
:
public
Object
{
public:
public:
MyObject1
(
int
value
)
:
value
(
value
)
{
MyObject1
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
print_created
(
this
,
toString
())
;
}
}
std
::
string
toString
()
const
{
std
::
string
toString
()
const
{
...
@@ -24,7 +24,7 @@ public:
...
@@ -24,7 +24,7 @@ public:
protected:
protected:
virtual
~
MyObject1
()
{
virtual
~
MyObject1
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
print_destroyed
(
this
)
;
}
}
private:
private:
...
@@ -35,7 +35,7 @@ private:
...
@@ -35,7 +35,7 @@ private:
class
MyObject2
{
class
MyObject2
{
public:
public:
MyObject2
(
int
value
)
:
value
(
value
)
{
MyObject2
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
print_created
(
this
,
toString
())
;
}
}
std
::
string
toString
()
const
{
std
::
string
toString
()
const
{
...
@@ -43,7 +43,7 @@ public:
...
@@ -43,7 +43,7 @@ public:
}
}
virtual
~
MyObject2
()
{
virtual
~
MyObject2
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
print_destroyed
(
this
)
;
}
}
private:
private:
...
@@ -54,7 +54,7 @@ private:
...
@@ -54,7 +54,7 @@ private:
class
MyObject3
:
public
std
::
enable_shared_from_this
<
MyObject3
>
{
class
MyObject3
:
public
std
::
enable_shared_from_this
<
MyObject3
>
{
public:
public:
MyObject3
(
int
value
)
:
value
(
value
)
{
MyObject3
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
print_created
(
this
,
toString
())
;
}
}
std
::
string
toString
()
const
{
std
::
string
toString
()
const
{
...
@@ -62,7 +62,7 @@ public:
...
@@ -62,7 +62,7 @@ public:
}
}
virtual
~
MyObject3
()
{
virtual
~
MyObject3
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
print_destroyed
(
this
)
;
}
}
private:
private:
...
@@ -144,4 +144,7 @@ void init_ex_smart_ptr(py::module &m) {
...
@@ -144,4 +144,7 @@ void init_ex_smart_ptr(py::module &m) {
m
.
def
(
"print_myobject3_4"
,
&
print_myobject3_4
);
m
.
def
(
"print_myobject3_4"
,
&
print_myobject3_4
);
py
::
implicitly_convertible
<
py
::
int_
,
MyObject1
>
();
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()]:
...
@@ -68,3 +68,18 @@ for o in [MyObject3(9), make_myobject3_1(), make_myobject3_2()]:
print_myobject3_2
(
o
)
print_myobject3_2
(
o
)
print_myobject3_3
(
o
)
print_myobject3_3
(
o
)
print_myobject3_4
(
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
### Object @ 0xdeffd0 created via default constructor
Initialized ref from pointer 0x1347ba0
### MyObject1 @ 0xdeffd0 created MyObject1[1]
MyObject1[2] constructor
### ref<MyObject1> @ 0x7f6a2e03c4a8 created from pointer 0xdeffd0
Initialized ref from pointer 0x12b9270
### Object @ 0xe43f50 created via default constructor
Initialized ref from ref 0x12b9270
### MyObject1 @ 0xe43f50 created MyObject1[2]
Destructing ref 0x12b9270
### ref<Object> @ 0x7fff136845d0 created from pointer 0xe43f50
MyObject1[3] constructor
### ref<MyObject1> @ 0x7f6a2c32aad8 created via copy constructor with pointer 0xe43f50
Initialized ref from pointer 0x12a2a90
### 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]
MyObject1[1]
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd
0
Initialized ref from ref 0x1347ba
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xdeffd
0
MyObject1[1]
MyObject1[1]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845a8 destroyed
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd
0
MyObject1[1]
MyObject1[1]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xdeffd
0
MyObject1[1]
MyObject1[1]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
Reference count = 1
MyObject1[2]
MyObject1[2]
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x12b927
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f5
0
Initialized ref from ref 0x12b927
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xe43f5
0
MyObject1[2]
MyObject1[2]
Destructing ref 0x12b9270
### ref<Object> @ 0x7fff136845a8 destroyed
Destructing ref 0x12b9270
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x12b927
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f5
0
MyObject1[2]
MyObject1[2]
Destructing ref 0x12b9270
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x12b927
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xe43f5
0
MyObject1[2]
MyObject1[2]
Destructing ref 0x12b9270
### ref<Object> @ 0x7fff136845c8 destroyed
Reference count = 1
MyObject1[3]
MyObject1[3]
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf
0
Initialized ref from ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee8cf
0
MyObject1[3]
MyObject1[3]
Destructing ref 0x12a2a90
### ref<Object> @ 0x7fff136845a8 destroyed
Destructing ref 0x12a2a90
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf
0
MyObject1[3]
MyObject1[3]
Destructing ref 0x12a2a90
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x12a2a9
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee8cf
0
MyObject1[3]
MyObject1[3]
Destructing ref 0x12a2a90
### ref<Object> @ 0x7fff136845c8 destroyed
Destructing ref 0x12b9270
### MyObject1 @ 0xe43f50 destroyed
MyObject1[2] destructor
### Object @ 0xe43f50 destroyed
Destructing ref 0x1347ba0
### ref<MyObject1> @ 0x7f6a2c32aad8 destroyed
MyObject1[1] destructor
### MyObject1 @ 0xdeffd0 destroyed
MyObject1[4] constructor
### Object @ 0xdeffd0 destroyed
Initialized ref from pointer 0x1347ba0
### ref<MyObject1> @ 0x7f6a2e03c4a8 destroyed
MyObject1[5] constructor
### Object @ 0xee8310 created via default constructor
Initialized ref from pointer 0x1299190
### MyObject1 @ 0xee8310 created MyObject1[4]
Initialized ref from ref 0x1299190
### ref<MyObject1> @ 0x7f6a2e03c4a8 created from pointer 0xee8310
Destructing ref 0x1299190
### Object @ 0xee8470 created via default constructor
MyObject1[6] constructor
### MyObject1 @ 0xee8470 created MyObject1[5]
Initialized ref from pointer 0x133e2f0
### ref<MyObject1> @ 0x7fff136845d0 created from pointer 0xee8470
Destructing ref 0x12a2a90
### ref<MyObject1> @ 0x7f6a2c32aad8 created via copy constructor with pointer 0xee8470
MyObject1[3] destructor
### 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]
MyObject1[4]
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
Initialized ref from ref 0x1347ba
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee831
0
MyObject1[4]
MyObject1[4]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845a8 destroyed
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
MyObject1[4]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
MyObject1[4]
Destructing ref 0x1347ba0
### ref<Object> @ 0x7fff136845c8 destroyed
MyObject1[4]
MyObject1[4]
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
Initialized ref from ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee831
0
MyObject1[4]
MyObject1[4]
Destructing ref 0x1347ba0
### ref<MyObject1> @ 0x7fff136845a8 destroyed
Destructing ref 0x1347ba0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
MyObject1[4]
Destructing ref 0x1347ba0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x1347ba
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee831
0
MyObject1[4]
MyObject1[4]
Destructing ref 0x1347ba0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
<example.MyObject1 object at 0x7f6a2c32aab0>
MyObject1[5]
MyObject1[5]
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x129919
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
Initialized ref from ref 0x129919
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee847
0
MyObject1[5]
MyObject1[5]
Destructing ref 0x1299190
### ref<Object> @ 0x7fff136845a8 destroyed
Destructing ref 0x1299190
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x129919
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
MyObject1[5]
Destructing ref 0x1299190
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x129919
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
MyObject1[5]
Destructing ref 0x1299190
### ref<Object> @ 0x7fff136845c8 destroyed
MyObject1[5]
MyObject1[5]
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
Initialized ref from ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee847
0
MyObject1[5]
MyObject1[5]
Destructing ref 0x1299190
### ref<MyObject1> @ 0x7fff136845a8 destroyed
Destructing ref 0x1299190
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
MyObject1[5]
Destructing ref 0x1299190
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x129919
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee847
0
MyObject1[5]
MyObject1[5]
Destructing ref 0x1299190
### ref<MyObject1> @ 0x7fff136845c8 destroyed
<example.MyObject1 object at 0x7f6a2c32ab10>
MyObject1[6]
MyObject1[6]
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x133e2f
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
Initialized ref from ref 0x133e2f
0
### ref<Object> @ 0x7fff136845a8 created via copy constructor with pointer 0xee95a
0
MyObject1[6]
MyObject1[6]
Destructing ref 0x133e2f0
### ref<Object> @ 0x7fff136845a8 destroyed
Destructing ref 0x133e2f0
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x133e2f
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
MyObject1[6]
Destructing ref 0x133e2f0
### ref<Object> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<Object> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x133e2f
0
### ref<Object> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
MyObject1[6]
Destructing ref 0x133e2f0
### ref<Object> @ 0x7fff136845c8 destroyed
MyObject1[6]
MyObject1[6]
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
Initialized ref from ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845a8 created via copy constructor with pointer 0xee95a
0
MyObject1[6]
MyObject1[6]
Destructing ref 0x133e2f0
### ref<MyObject1> @ 0x7fff136845a8 destroyed
Destructing ref 0x133e2f0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
MyObject1[6]
Destructing ref 0x133e2f0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Created empty ref
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Assigning ref 0x133e2f
0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee95a
0
MyObject1[6]
MyObject1[6]
Destructing ref 0x133e2f0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
MyObject1[7] constructor
7
Initialized ref from pointer 0x133f3a0
### Object @ 0xee97f0 created via default constructor
### MyObject1 @ 0xee97f0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee97f0
MyObject1[7]
MyObject1[7]
Destructing ref 0x133f3a0
### MyObject1 @ 0xee97f0 destroyed
MyObject1[7] destructor
### Object @ 0xee97f0 destroyed
Created empty ref
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
MyObject1[7] constructor
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Initialized ref from pointer 0x12a2a90
### Object @ 0xee99e0 created via default constructor
Assigning ref 0x12a2a90
### MyObject1 @ 0xee99e0 created MyObject1[7]
Initialized ref from ref 0x12a2a90
### 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]
MyObject1[7]
Destructing ref 0x12a2a90
### ref<MyObject1> @ 0x7fff136845a8 destroyed
Destructing ref 0x12a2a90
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Destructing ref 0x12a2a90
### MyObject1 @ 0xee99e0 destroyed
MyObject1[7] destructor
### Object @ 0xee99e0 destroyed
Created empty ref
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
MyObject1[7] constructor
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Initialized ref from pointer 0x133f3a0
### Object @ 0xee97f0 created via default constructor
Assigning ref 0x133f3a0
### MyObject1 @ 0xee97f0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee97f0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee97f0
MyObject1[7]
MyObject1[7]
Destructing ref 0x133f3a0
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Destructing ref 0x133f3a0
### MyObject1 @ 0xee97f0 destroyed
MyObject1[7] destructor
### Object @ 0xee97f0 destroyed
Created empty ref
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
MyObject1[7] constructor
### ref<MyObject1> @ 0x7fff136845c8 created via default constructor
Initialized ref from pointer 0x12a2a90
### Object @ 0xee99e0 created via default constructor
Assigning ref 0x12a2a90
### MyObject1 @ 0xee99e0 created MyObject1[7]
### ref<MyObject1> @ 0x7f6a2c32ab08 created from pointer 0xee99e0
### ref<MyObject1> @ 0x7fff136845c8 assigned via copy assignment pointer 0xee99e0
MyObject1[7]
MyObject1[7]
Destructing ref 0x12a2a90
### ref<MyObject1> @ 0x7fff136845c8 destroyed
Destructing ref 0x12a2a90
### MyObject1 @ 0xee99e0 destroyed
MyObject1[7] destructor
### Object @ 0xee99e0 destroyed
Destructing ref 0x133e2f0
### ref<MyObject1> @ 0x7f6a2c32ab08 destroyed
MyObject1[6] destructor
### MyObject1 @ 0xee95a0 destroyed
Destructing ref 0x1299190
### Object @ 0xee95a0 destroyed
MyObject1[5] destructor
### ref<MyObject1> @ 0x7f6a2c32ab38 destroyed
Destructing ref 0x1347ba0
### MyObject1 @ 0xee8470 destroyed
MyObject1[4] destructor
### Object @ 0xee8470 destroyed
MyObject2[8] constructor
### ref<MyObject1> @ 0x7f6a2c32aad8 destroyed
MyObject2[6] constructor
### MyObject1 @ 0xee8310 destroyed
MyObject2[7] constructor
### 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]
MyObject2[8]
MyObject2[8]
MyObject2[8]
MyObject2[8]
<example.MyObject2 object at 0x7f6a2dfc86c0>
MyObject2[6]
MyObject2[6]
MyObject2[6]
MyObject2[6]
MyObject2[6]
MyObject2[6]
MyObject2[6]
MyObject2[6]
<example.MyObject2 object at 0x7f6a2c32d030>
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[7]
MyObject2[6] destructor
### MyObject2 @ 0xee95a0 destroyed
MyObject2[8] destructor
### MyObject2 @ 0xe43f50 destroyed
MyObject3[9] constructor
### MyObject3 @ 0xee9ac0 created MyObject3[9]
MyObject3[8] constructor
### MyObject3 @ 0xe43f90 created MyObject3[8]
MyObject3[9] constructor
### MyObject3 @ 0xeea7d0 created MyObject3[9]
MyObject2[7] destructor
### MyObject2 @ 0xee95d0 destroyed
<example.MyObject3 object at 0x7f6a2dfc8768>
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
<example.MyObject3 object at 0x7f6a2dfc86c0>
MyObject3[8]
MyObject3[8]
MyObject3[8]
MyObject3[8]
MyObject3[8]
MyObject3[8]
MyObject3[8]
MyObject3[8]
<example.MyObject3 object at 0x7f6a2c32d068>
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[9]
MyObject3[8] destructor
### MyObject3 @ 0xe43f90 destroyed
MyObject3[9] destructor
### MyObject3 @ 0xee9ac0 destroyed
Reference count = 1
Instances not destroyed: [0, 0, 0, 1, 0]
Reference count = 1
### MyObject3 @ 0xeea7d0 destroyed
Reference count = 1
Instances not destroyed: [0, 0, 0, 0, 0]
<example.MyObject1 object at 0x7f830b500e68>
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']]
<example.MyObject1 object at 0x7f830b4fc688>
Default constructions: [10, 0, 0, 0, 30]
<example.MyObject1 object at 0x7f830b4fc5a8>
Copy constructions: [0, 0, 0, 0, 12]
7
Copy assignments: [0, 0, 0, 0, 30]
<example.MyObject2 object at 0x7f830b50b330>
Move assignments: [0, 0, 0, 0, 0]
<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
example/example-virtual-functions.cpp
View file @
f4f2afb6
...
@@ -8,18 +8,16 @@
...
@@ -8,18 +8,16 @@
*/
*/
#include "example.h"
#include "example.h"
#include "constructor-stats.h"
#include <pybind11/functional.h>
#include <pybind11/functional.h>
/* This is an example class that we'll want to be able to extend from Python */
/* This is an example class that we'll want to be able to extend from Python */
class
ExampleVirt
{
class
ExampleVirt
{
public:
public:
ExampleVirt
(
int
state
)
:
state
(
state
)
{
ExampleVirt
(
int
state
)
:
state
(
state
)
{
print_created
(
this
,
state
);
}
cout
<<
"Constructing ExampleVirt.."
<<
endl
;
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
);
}
~
ExampleVirt
()
{
cout
<<
"Destructing ExampleVirt.."
<<
endl
;
}
virtual
int
run
(
int
value
)
{
virtual
int
run
(
int
value
)
{
std
::
cout
<<
"Original implementation of ExampleVirt::run(state="
<<
state
std
::
cout
<<
"Original implementation of ExampleVirt::run(state="
<<
state
...
@@ -71,8 +69,8 @@ public:
...
@@ -71,8 +69,8 @@ public:
class
NonCopyable
{
class
NonCopyable
{
public:
public:
NonCopyable
(
int
a
,
int
b
)
:
value
{
new
int
(
a
*
b
)}
{}
NonCopyable
(
int
a
,
int
b
)
:
value
{
new
int
(
a
*
b
)}
{
print_created
(
this
,
a
,
b
);
}
NonCopyable
(
NonCopyable
&&
)
=
default
;
NonCopyable
(
NonCopyable
&&
o
)
{
value
=
std
::
move
(
o
.
value
);
print_move_created
(
this
);
}
NonCopyable
(
const
NonCopyable
&
)
=
delete
;
NonCopyable
(
const
NonCopyable
&
)
=
delete
;
NonCopyable
()
=
delete
;
NonCopyable
()
=
delete
;
void
operator
=
(
const
NonCopyable
&
)
=
delete
;
void
operator
=
(
const
NonCopyable
&
)
=
delete
;
...
@@ -80,7 +78,7 @@ public:
...
@@ -80,7 +78,7 @@ public:
std
::
string
get_value
()
const
{
std
::
string
get_value
()
const
{
if
(
value
)
return
std
::
to_string
(
*
value
);
else
return
"(null)"
;
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:
private:
std
::
unique_ptr
<
int
>
value
;
std
::
unique_ptr
<
int
>
value
;
...
@@ -90,11 +88,11 @@ private:
...
@@ -90,11 +88,11 @@ private:
// when it is not referenced elsewhere, but copied if it is still referenced.
// when it is not referenced elsewhere, but copied if it is still referenced.
class
Movable
{
class
Movable
{
public:
public:
Movable
(
int
a
,
int
b
)
:
value
{
a
+
b
}
{}
Movable
(
int
a
,
int
b
)
:
value
{
a
+
b
}
{
print_created
(
this
,
a
,
b
);
}
Movable
(
const
Movable
&
m
)
{
value
=
m
.
value
;
std
::
cout
<<
"Movable @ "
<<
this
<<
" copy constructor"
<<
std
::
endl
;
}
Movable
(
const
Movable
&
m
)
{
value
=
m
.
value
;
print_copy_created
(
this
)
;
}
Movable
(
Movable
&&
m
)
{
value
=
std
::
move
(
m
.
value
);
std
::
cout
<<
"Movable @ "
<<
this
<<
" move constructor"
<<
std
::
endl
;
}
Movable
(
Movable
&&
m
)
{
value
=
std
::
move
(
m
.
value
);
print_move_created
(
this
)
;
}
int
get_value
()
const
{
return
value
;
}
int
get_value
()
const
{
return
value
;
}
~
Movable
()
{
std
::
cout
<<
"Movable destructor @ "
<<
this
<<
"; value = "
<<
get_value
()
<<
std
::
endl
;
}
~
Movable
()
{
print_destroyed
(
this
)
;
}
private:
private:
int
value
;
int
value
;
};
};
...
@@ -305,5 +303,6 @@ void init_ex_virtual_functions(py::module &m) {
...
@@ -305,5 +303,6 @@ void init_ex_virtual_functions(py::module &m) {
m
.
def
(
"runExampleVirtBool"
,
&
runExampleVirtBool
);
m
.
def
(
"runExampleVirtBool"
,
&
runExampleVirtBool
);
m
.
def
(
"runExampleVirtVirtual"
,
&
runExampleVirtVirtual
);
m
.
def
(
"runExampleVirtVirtual"
,
&
runExampleVirtVirtual
);
m
.
def
(
"cstats_debug"
,
&
ConstructorStats
::
get
<
ExampleVirt
>
);
initialize_inherited_virtuals
(
m
);
initialize_inherited_virtuals
(
m
);
}
}
example/example-virtual-functions.py
View file @
f4f2afb6
...
@@ -37,8 +37,6 @@ print(runExampleVirt(ex12p, 20))
...
@@ -37,8 +37,6 @@ print(runExampleVirt(ex12p, 20))
print
(
runExampleVirtBool
(
ex12p
))
print
(
runExampleVirtBool
(
ex12p
))
runExampleVirtVirtual
(
ex12p
)
runExampleVirtVirtual
(
ex12p
)
sys
.
stdout
.
flush
()
class
VI_AR
(
A_Repeat
):
class
VI_AR
(
A_Repeat
):
def
unlucky_number
(
self
):
def
unlucky_number
(
self
):
return
99
return
99
...
@@ -122,3 +120,16 @@ try:
...
@@ -122,3 +120,16 @@ try:
except
RuntimeError
as
e
:
except
RuntimeError
as
e
:
# Don't print the exception message here because it differs under debug/non-debug mode
# Don't print the exception message here because it differs under debug/non-debug mode
print
(
"Caught expected exception"
)
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)
Original implementation of ExampleVirt::run(state=10, value=20)
30
30
Caught expected exception: Tried to call pure virtual function "ExampleVirt::pure_virtual"
Caught expected exception: Tried to call pure virtual function "ExampleVirt::pure_virtual"
Constructing ExampleVirt..
### ExampleVirt @ 0x2076a00 created 11
ExtendedExampleVirt::run(20), calling parent..
ExtendedExampleVirt::run(20), calling parent..
Original implementation of ExampleVirt::run(state=11, value=21)
Original implementation of ExampleVirt::run(state=11, value=21)
32
32
...
@@ -78,20 +78,29 @@ VI_DT says: quack quack quack
...
@@ -78,20 +78,29 @@ VI_DT says: quack quack quack
Unlucky = 1234
Unlucky = 1234
Lucky = -4.25
Lucky = -4.25
2^2 * 3^2 =
2^2 * 3^2 =
NonCopyable destructor @ 0x1a6c3f0; value = (null)
### NonCopyable @ 0x207df10 created 4 9
### NonCopyable @ 0x7ffcfe866228 created via move constructor
### NonCopyable @ 0x207df10 destroyed
36
36
NonCopyable
destructor @ 0x7ffc6d1fbaa8; value = 36
###
NonCopyable
@ 0x7ffcfe866228 destroyed
4 + 5 =
4 + 5 =
Movable @ 0x7ffc6d1fbacc copy constructor
### Movable @ 0x207e230 created 4 5
### Movable @ 0x7ffcfe86624c created via copy constructor
9
9
Movable
destructor @ 0x7ffc6d1fbacc; value = 9
###
Movable
@ 0x7ffcfe86624c destroyed
7 + 7 =
7 + 7 =
Movable @ 0x7ffc6d1fbacc move constructor
### Movable @ 0x20259e0 created 7 7
Movable destructor @ 0x1a6c4d0; value = 14
### Movable @ 0x7ffcfe86624c created via move constructor
### Movable @ 0x20259e0 destroyed
14
14
Movable destructor @ 0x7ffc6d1fbacc; value = 14
### Movable @ 0x7ffcfe86624c destroyed
### NonCopyable @ 0x2025a00 created 9 9
Caught expected exception
Caught expected exception
NonCopyable destructor @ 0x29a64b0; value = 81
### ExampleVirt @ 0x2073a90 destroyed
Movable destructor @ 0x1a6c410; value = 9
### ExampleVirt @ 0x2076a00 destroyed
Destructing ExampleVirt..
### Movable @ 0x207e230 destroyed
Destructing ExampleVirt..
### 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 @@
...
@@ -8,6 +8,7 @@
*/
*/
#include "example.h"
#include "example.h"
#include "constructor-stats.h"
void
init_ex_methods_and_attributes
(
py
::
module
&
);
void
init_ex_methods_and_attributes
(
py
::
module
&
);
void
init_ex_python_types
(
py
::
module
&
);
void
init_ex_python_types
(
py
::
module
&
);
...
@@ -34,9 +35,24 @@ void init_issues(py::module &);
...
@@ -34,9 +35,24 @@ void init_issues(py::module &);
void
init_eigen
(
py
::
module
&
);
void
init_eigen
(
py
::
module
&
);
#endif
#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
)
{
PYBIND11_PLUGIN
(
example
)
{
py
::
module
m
(
"example"
,
"pybind example plugin"
);
py
::
module
m
(
"example"
,
"pybind example plugin"
);
bind_ConstructorStats
(
m
);
init_ex_methods_and_attributes
(
m
);
init_ex_methods_and_attributes
(
m
);
init_ex_python_types
(
m
);
init_ex_python_types
(
m
);
init_ex_operator_overloading
(
m
);
init_ex_operator_overloading
(
m
);
...
...
example/issues.cpp
View file @
f4f2afb6
...
@@ -8,11 +8,18 @@
...
@@ -8,11 +8,18 @@
*/
*/
#include "example.h"
#include "example.h"
#include "constructor-stats.h"
#include <pybind11/stl.h>
#include <pybind11/stl.h>
#include <pybind11/operators.h>
#include <pybind11/operators.h>
PYBIND11_DECLARE_HOLDER_TYPE
(
T
,
std
::
shared_ptr
<
T
>
);
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
)
{
void
init_issues
(
py
::
module
&
m
)
{
py
::
module
m2
=
m
.
def_submodule
(
"issues"
);
py
::
module
m2
=
m
.
def_submodule
(
"issues"
);
...
@@ -159,12 +166,6 @@ void init_issues(py::module &m) {
...
@@ -159,12 +166,6 @@ void init_issues(py::module &m) {
;
;
// Issue #328: first member in a class can't be used in operators
// 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_
<
NestABase
>
(
m2
,
"NestABase"
).
def
(
py
::
init
<>
()).
def_readwrite
(
"value"
,
&
NestABase
::
value
);
py
::
class_
<
NestA
>
(
m2
,
"NestA"
).
def
(
py
::
init
<>
()).
def
(
py
::
self
+=
int
())
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
);
.
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
...
@@ -24,15 +24,15 @@ Failed as expected: Incompatible constructor arguments. The following argument t
1. example.issues.StrIssue(arg0: int)
1. example.issues.StrIssue(arg0: int)
2. example.issues.StrIssue()
2. example.issues.StrIssue()
Invoked with: no, such, constructor
Invoked with: no, such, constructor
NestABase
@
0x1
1
5
2940
constructor
###
NestABase
@
0x15
eb630 created via default
constructor
NestA
@
0x1
1
5
2940
constructor
###
NestA
@
0x15
eb630 created via default
constructor
NestABase
@0x11f9350
constructor
###
NestABase
@ 0x1704000 created via default
constructor
NestA
@0x11f9350
constructor
###
NestA
@ 0x1704000 created via default
constructor
NestB
@0x11f9350
constructor
###
NestB
@ 0x1704000 created via default
constructor
NestABase
@0x112d0d0
constructor
###
NestABase
@ 0x1633110 created via default
constructor
NestA
@0x112d0d0
constructor
###
NestA
@ 0x1633110 created via default
constructor
NestB
@0x112d0d0
constructor
###
NestB
@ 0x1633110 created via default
constructor
NestC
@0x112d0d0
constructor
###
NestC
@ 0x1633110 created via default
constructor
13
13
103
103
1003
1003
...
@@ -43,13 +43,13 @@ NestC@0x112d0d0 constructor
...
@@ -43,13 +43,13 @@ NestC@0x112d0d0 constructor
42
42
-2
-2
42
42
NestC
@0x112d0d
0 destr
uctor
###
NestC
@ 0x163311
0 destr
oyed
NestB
@0x112d0d
0 destr
uctor
###
NestB
@ 0x163311
0 destr
oyed
NestA
@0x112d0d
0 destr
uctor
###
NestA
@ 0x163311
0 destr
oyed
NestABase
@0x112d0d
0 destr
uctor
###
NestABase
@ 0x163311
0 destr
oyed
42
42
NestA
@0x115294
0 destr
uctor
###
NestA
@ 0x15eb63
0 destr
oyed
NestABase
@0x115294
0 destr
uctor
###
NestABase
@ 0x15eb63
0 destr
oyed
NestB
@0x11f935
0 destr
uctor
###
NestB
@ 0x170400
0 destr
oyed
NestA
@0x11f935
0 destr
uctor
###
NestA
@ 0x170400
0 destr
oyed
NestABase
@0x11f935
0 destr
uctor
###
NestABase
@ 0x170400
0 destr
oyed
example/object.h
View file @
f4f2afb6
...
@@ -2,15 +2,16 @@
...
@@ -2,15 +2,16 @@
#define __OBJECT_H
#define __OBJECT_H
#include <atomic>
#include <atomic>
#include "constructor-stats.h"
/// Reference counted object base class
/// Reference counted object base class
class
Object
{
class
Object
{
public:
public:
/// Default constructor
/// Default constructor
Object
()
{
}
Object
()
{
print_default_created
(
this
);
}
/// Copy constructor
/// Copy constructor
Object
(
const
Object
&
)
:
m_refCount
(
0
)
{}
Object
(
const
Object
&
)
:
m_refCount
(
0
)
{
print_copy_created
(
this
);
}
/// Return the current reference count
/// Return the current reference count
int
getRefCount
()
const
{
return
m_refCount
;
};
int
getRefCount
()
const
{
return
m_refCount
;
};
...
@@ -37,11 +38,17 @@ protected:
...
@@ -37,11 +38,17 @@ protected:
/** \brief Virtual protected deconstructor.
/** \brief Virtual protected deconstructor.
* (Will only be called by \ref ref)
* (Will only be called by \ref ref)
*/
*/
virtual
~
Object
()
{
}
virtual
~
Object
()
{
print_destroyed
(
this
);
}
private:
private:
mutable
std
::
atomic
<
int
>
m_refCount
{
0
};
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
* \brief Reference counting helper
*
*
...
@@ -55,37 +62,43 @@ private:
...
@@ -55,37 +62,43 @@ private:
template
<
typename
T
>
class
ref
{
template
<
typename
T
>
class
ref
{
public:
public:
/// Create a nullptr reference
/// 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
/// Construct a reference from a pointer
ref
(
T
*
ptr
)
:
m_ptr
(
ptr
)
{
ref
(
T
*
ptr
)
:
m_ptr
(
ptr
)
{
std
::
cout
<<
"Initialized ref from pointer "
<<
ptr
<<
std
::
endl
;
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
incRef
();
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
incRef
();
print_created
(
this
,
"from pointer"
,
m_ptr
);
track_created
((
ref_tag
*
)
this
,
"from pointer"
);
}
}
/// Copy constructor
/// Copy constructor
ref
(
const
ref
&
r
)
:
m_ptr
(
r
.
m_ptr
)
{
ref
(
const
ref
&
r
)
:
m_ptr
(
r
.
m_ptr
)
{
std
::
cout
<<
"Initialized ref from ref "
<<
r
.
m_ptr
<<
std
::
endl
;
if
(
m_ptr
)
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
incRef
();
((
Object
*
)
m_ptr
)
->
incRef
();
print_copy_created
(
this
,
"with pointer"
,
m_ptr
);
track_copy_created
((
ref_tag
*
)
this
);
}
}
/// Move constructor
/// Move constructor
ref
(
ref
&&
r
)
:
m_ptr
(
r
.
m_ptr
)
{
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
;
r
.
m_ptr
=
nullptr
;
print_move_created
(
this
,
"with pointer"
,
m_ptr
);
track_move_created
((
ref_tag
*
)
this
);
}
}
/// Destroy this reference
/// Destroy this reference
~
ref
()
{
~
ref
()
{
std
::
cout
<<
"Destructing ref "
<<
m_ptr
<<
std
::
endl
;
if
(
m_ptr
)
if
(
m_ptr
)
((
Object
*
)
m_ptr
)
->
decRef
();
((
Object
*
)
m_ptr
)
->
decRef
();
print_destroyed
(
this
);
track_destroyed
((
ref_tag
*
)
this
);
}
}
/// Move another reference into the current one
/// Move another reference into the current one
ref
&
operator
=
(
ref
&&
r
)
{
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
)
if
(
*
this
==
r
)
return
*
this
;
return
*
this
;
if
(
m_ptr
)
if
(
m_ptr
)
...
@@ -97,7 +110,8 @@ public:
...
@@ -97,7 +110,8 @@ public:
/// Overwrite this reference with another reference
/// Overwrite this reference with another reference
ref
&
operator
=
(
const
ref
&
r
)
{
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
)
if
(
m_ptr
==
r
.
m_ptr
)
return
*
this
;
return
*
this
;
if
(
m_ptr
)
if
(
m_ptr
)
...
@@ -110,7 +124,8 @@ public:
...
@@ -110,7 +124,8 @@ public:
/// Overwrite this reference with a pointer to another object
/// Overwrite this reference with a pointer to another object
ref
&
operator
=
(
T
*
ptr
)
{
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
)
if
(
m_ptr
==
ptr
)
return
*
this
;
return
*
this
;
if
(
m_ptr
)
if
(
m_ptr
)
...
...
example/run_test.py
View file @
f4f2afb6
...
@@ -9,14 +9,16 @@ remove_long_marker = re.compile(r'([0-9])L')
...
@@ -9,14 +9,16 @@ remove_long_marker = re.compile(r'([0-9])L')
remove_hex
=
re
.
compile
(
r
'0x[0-9a-fA-F]+'
)
remove_hex
=
re
.
compile
(
r
'0x[0-9a-fA-F]+'
)
shorten_floats
=
re
.
compile
(
r
'([1-9][0-9]*\.[0-9]{4})[0-9]*'
)
shorten_floats
=
re
.
compile
(
r
'([1-9][0-9]*\.[0-9]{4})[0-9]*'
)
relaxed
=
False
def
sanitize
(
lines
):
def
sanitize
(
lines
):
lines
=
lines
.
split
(
'
\n
'
)
lines
=
lines
.
split
(
'
\n
'
)
for
i
in
range
(
len
(
lines
)):
for
i
in
range
(
len
(
lines
)):
line
=
lines
[
i
]
line
=
lines
[
i
]
if
line
.
startswith
(
" |"
):
if
line
.
startswith
(
" |"
):
line
=
""
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_unicode_marker
.
sub
(
r
'\1'
,
line
)
line
=
remove_long_marker
.
sub
(
r
'\1'
,
line
)
line
=
remove_long_marker
.
sub
(
r
'\1'
,
line
)
line
=
remove_hex
.
sub
(
r
'0'
,
line
)
line
=
remove_hex
.
sub
(
r
'0'
,
line
)
...
@@ -28,13 +30,6 @@ def sanitize(lines):
...
@@ -28,13 +30,6 @@ def sanitize(lines):
line
=
line
.
replace
(
'example.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'example.EMode'
,
'EMode'
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
replace
(
'method of builtins.PyCapsule instance'
,
''
)
line
=
line
.
strip
()
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
lines
[
i
]
=
line
return
'
\n
'
.
join
(
sorted
([
l
for
l
in
lines
if
l
!=
""
]))
return
'
\n
'
.
join
(
sorted
([
l
for
l
in
lines
if
l
!=
""
]))
...
@@ -44,16 +39,12 @@ if path != '':
...
@@ -44,16 +39,12 @@ if path != '':
os
.
chdir
(
path
)
os
.
chdir
(
path
)
if
len
(
sys
.
argv
)
<
2
:
if
len
(
sys
.
argv
)
<
2
:
print
(
"Syntax: %s
[--relaxed]
<test name>"
%
sys
.
argv
[
0
])
print
(
"Syntax: %s <test name>"
%
sys
.
argv
[
0
])
exit
(
0
)
exit
(
0
)
if
len
(
sys
.
argv
)
==
3
and
sys
.
argv
[
1
]
==
'--relaxed'
:
del
sys
.
argv
[
1
]
relaxed
=
True
name
=
sys
.
argv
[
1
]
name
=
sys
.
argv
[
1
]
try
:
try
:
output_bytes
=
subprocess
.
check_output
([
sys
.
executable
,
name
+
".py"
],
output_bytes
=
subprocess
.
check_output
([
sys
.
executable
,
"-u"
,
name
+
".py"
],
stderr
=
subprocess
.
STDOUT
)
stderr
=
subprocess
.
STDOUT
)
except
subprocess
.
CalledProcessError
as
e
:
except
subprocess
.
CalledProcessError
as
e
:
if
e
.
returncode
==
99
:
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