Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
80fe0d0d
Commit
80fe0d0d
authored
Jan 06, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New tests/core/smart_holder_poc_test.cpp, using Catch2.
parent
ebd334bf
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
128 additions
and
9 deletions
+128
-9
include/pybind11/smart_holder_poc.h
+29
-9
tests/core/smart_holder_poc_test.cpp
+99
-0
No files found.
include/pybind11/smart_holder_poc.h
View file @
80fe0d0d
#pragma once
#include <memory>
#include <stdexcept>
#include <string>
#include <typeinfo>
namespace
pybindit
{
...
...
@@ -44,8 +46,10 @@ struct smart_holder {
rtti_uqp_del
{
nullptr
},
vptr_deleter_guard_flag
{
false
}
{}
bool
has_pointee
()
const
{
return
vptr
.
get
()
!=
nullptr
;
}
template
<
typename
T
>
void
ensure_compatible_rtti_held
(
const
char
*
context
)
{
void
ensure_compatible_rtti_held
(
const
char
*
context
)
const
{
const
std
::
type_info
*
rtti_requested
=
&
typeid
(
T
);
if
(
!
(
*
rtti_requested
==
*
rtti_held
))
{
throw
std
::
runtime_error
(
std
::
string
(
"Incompatible RTTI ("
)
+
context
+
...
...
@@ -54,7 +58,7 @@ struct smart_holder {
}
template
<
typename
D
>
void
ensure_compatible_rtti_uqp_del
(
const
char
*
context
)
{
void
ensure_compatible_rtti_uqp_del
(
const
char
*
context
)
const
{
const
std
::
type_info
*
rtti_requested
=
&
typeid
(
D
);
if
(
!
(
*
rtti_requested
==
*
rtti_uqp_del
))
{
throw
std
::
runtime_error
(
...
...
@@ -62,14 +66,21 @@ struct smart_holder {
}
}
void
ensure_vptr_deleter_guard_flag_true
(
const
char
*
context
)
{
void
ensure_has_pointee
(
const
char
*
context
)
const
{
if
(
!
has_pointee
())
{
throw
std
::
runtime_error
(
std
::
string
(
"Disowned holder ("
)
+
context
+
")."
);
}
}
void
ensure_vptr_deleter_guard_flag_true
(
const
char
*
context
)
const
{
if
(
rtti_uqp_del
!=
nullptr
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown this shared_ptr ("
)
+
context
+
")."
);
}
}
void
ensure_use_count_1
(
const
char
*
context
)
{
void
ensure_use_count_1
(
const
char
*
context
)
const
{
if
(
vptr
.
use_count
()
!=
1
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown use_count != 1 ("
)
+
context
+
")."
);
...
...
@@ -77,7 +88,15 @@ struct smart_holder {
}
template
<
typename
T
>
void
from_raw_ptr_owned
(
T
*
raw_ptr
)
{
const
T
&
const_value_ref
()
const
{
static
const
char
*
context
=
"const_value_ref"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_has_pointee
(
context
);
return
*
static_cast
<
T
*>
(
vptr
.
get
());
}
template
<
typename
T
>
void
from_raw_ptr_take_ownership
(
T
*
raw_ptr
)
{
clear
();
rtti_held
=
&
typeid
(
T
);
vptr_deleter_guard_flag
=
true
;
...
...
@@ -93,7 +112,8 @@ struct smart_holder {
}
template
<
typename
T
>
T
*
as_raw_ptr_owned
(
const
char
*
context
=
"as_raw_ptr_owned"
)
{
T
*
as_raw_ptr_release_ownership
(
const
char
*
context
=
"as_raw_ptr_release_ownership"
)
{
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_vptr_deleter_guard_flag_true
(
context
);
ensure_use_count_1
(
context
);
...
...
@@ -104,7 +124,7 @@ struct smart_holder {
}
template
<
typename
T
>
T
*
as_raw_ptr_unowned
()
{
T
*
as_raw_ptr_unowned
()
const
{
static
const
char
*
context
=
"as_raw_ptr_unowned"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
return
static_cast
<
T
*>
(
vptr
.
get
());
...
...
@@ -122,7 +142,7 @@ struct smart_holder {
template
<
typename
T
>
std
::
unique_ptr
<
T
>
as_unique_ptr
()
{
return
std
::
unique_ptr
<
T
>
(
as_raw_ptr_
owned
<
T
>
(
"as_unique_ptr"
));
return
std
::
unique_ptr
<
T
>
(
as_raw_ptr_
release_ownership
<
T
>
(
"as_unique_ptr"
));
}
template
<
typename
T
,
typename
D
>
...
...
@@ -156,7 +176,7 @@ struct smart_holder {
}
template
<
typename
T
>
std
::
shared_ptr
<
T
>
as_shared_ptr
()
{
std
::
shared_ptr
<
T
>
as_shared_ptr
()
const
{
static
const
char
*
context
=
"as_shared_ptr"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
return
std
::
static_pointer_cast
<
T
>
(
vptr
);
...
...
tests/core/smart_holder_poc_test.cpp
0 → 100644
View file @
80fe0d0d
#include "pybind11/smart_holder_poc.h"
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
using
pybindit
::
memory
::
smart_holder
;
namespace
helpers
{
template
<
typename
T
>
struct
functor_builtin_delete
{
void
operator
()(
T
*
ptr
)
{
delete
ptr
;
}
};
}
// namespace helpers
TEST_CASE
(
"from_raw_ptr_take_ownership=const_value_ref"
)
{
smart_holder
hld
;
REQUIRE
(
!
hld
.
has_pointee
());
hld
.
from_raw_ptr_take_ownership
(
new
int
(
19
));
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
hld
.
const_value_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_raw_ptr_unowned=const_value_ref"
)
{
static
int
value
=
19
;
smart_holder
hld
;
hld
.
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
hld
.
const_value_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"as_raw_ptr_release_ownership"
)
{
smart_holder
hld
;
hld
.
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
new_owner
=
std
::
unique_ptr
<
int
>
(
hld
.
as_raw_ptr_release_ownership
<
int
>
());
REQUIRE
(
!
hld
.
has_pointee
());
}
TEST_CASE
(
"as_raw_ptr_unowned"
)
{
smart_holder
hld
;
hld
.
from_raw_ptr_take_ownership
(
new
int
(
19
));
int
*
raw_ptr
=
hld
.
as_raw_ptr_unowned
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
raw_ptr
==
19
);
}
TEST_CASE
(
"from_unique_ptr=const_value_ref"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
smart_holder
hld
;
hld
.
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE
(
hld
.
const_value_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"as_unique_ptr"
)
{
smart_holder
hld
;
hld
.
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
new_owner
=
hld
.
as_unique_ptr
<
int
>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_unique_ptr_with_deleter=const_value_ref"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
smart_holder
hld
;
hld
.
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE
(
hld
.
const_value_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"as_unique_ptr_with_deleter"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
smart_holder
hld
;
hld
.
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
auto
new_owner
=
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_shared_ptr=const_value_ref"
)
{
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
smart_holder
hld
;
hld
.
from_shared_ptr
(
orig_owner
);
REQUIRE
(
orig_owner
.
get
()
!=
nullptr
);
REQUIRE
(
hld
.
const_value_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"as_shared_ptr"
)
{
smart_holder
hld
;
hld
.
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
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