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
e7aea026
Commit
e7aea026
authored
Jan 12, 2021
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pure `clang-format --style=file -i` change.
parent
cfc848a1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
350 additions
and
389 deletions
+350
-389
include/pybind11/smart_holder_poc.h
+176
-190
tests/core/smart_holder_poc_test.cpp
+174
-199
No files found.
include/pybind11/smart_holder_poc.h
View file @
e7aea026
...
...
@@ -48,216 +48,202 @@ namespace memory {
template
<
typename
T
>
struct
guarded_builtin_delete
{
bool
*
flag_ptr
;
explicit
guarded_builtin_delete
(
bool
*
guard_flag_ptr
)
:
flag_ptr
{
guard_flag_ptr
}
{}
void
operator
()(
T
*
raw_ptr
)
{
if
(
*
flag_ptr
)
delete
raw_ptr
;
}
bool
*
flag_ptr
;
explicit
guarded_builtin_delete
(
bool
*
guard_flag_ptr
)
:
flag_ptr
{
guard_flag_ptr
}
{}
void
operator
()(
T
*
raw_ptr
)
{
if
(
*
flag_ptr
)
delete
raw_ptr
;
}
};
template
<
typename
T
,
typename
D
>
struct
guarded_custom_deleter
{
bool
*
flag_ptr
;
explicit
guarded_custom_deleter
(
bool
*
guard_flag_ptr
)
:
flag_ptr
{
guard_flag_ptr
}
{}
void
operator
()(
T
*
raw_ptr
)
{
if
(
*
flag_ptr
)
D
()(
raw_ptr
);
}
bool
*
flag_ptr
;
explicit
guarded_custom_deleter
(
bool
*
guard_flag_ptr
)
:
flag_ptr
{
guard_flag_ptr
}
{}
void
operator
()(
T
*
raw_ptr
)
{
if
(
*
flag_ptr
)
D
()(
raw_ptr
);
}
};
struct
smart_holder
{
const
std
::
type_info
*
rtti_held
;
const
std
::
type_info
*
rtti_uqp_del
;
std
::
shared_ptr
<
void
>
vptr
;
bool
vptr_deleter_guard_flag
;
bool
vptr_is_using_noop_deleter
:
1
;
bool
vptr_is_using_builtin_delete
:
1
;
bool
vptr_is_external_shared_ptr
:
1
;
smart_holder
()
:
rtti_held
{
nullptr
},
rtti_uqp_del
{
nullptr
},
vptr_deleter_guard_flag
{
false
},
vptr_is_using_noop_deleter
{
false
},
vptr_is_using_builtin_delete
{
false
},
vptr_is_external_shared_ptr
{
false
}
{}
bool
has_pointee
()
const
{
return
vptr
.
get
()
!=
nullptr
;
}
template
<
typename
T
>
void
ensure_compatible_rtti_held
(
const
char
*
context
)
const
{
if
(
!
rtti_held
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Unpopulated holder ("
)
+
context
+
")."
);
const
std
::
type_info
*
rtti_held
;
const
std
::
type_info
*
rtti_uqp_del
;
std
::
shared_ptr
<
void
>
vptr
;
bool
vptr_deleter_guard_flag
;
bool
vptr_is_using_noop_deleter
:
1
;
bool
vptr_is_using_builtin_delete
:
1
;
bool
vptr_is_external_shared_ptr
:
1
;
smart_holder
()
:
rtti_held
{
nullptr
},
rtti_uqp_del
{
nullptr
},
vptr_deleter_guard_flag
{
false
},
vptr_is_using_noop_deleter
{
false
},
vptr_is_using_builtin_delete
{
false
},
vptr_is_external_shared_ptr
{
false
}
{}
bool
has_pointee
()
const
{
return
vptr
.
get
()
!=
nullptr
;
}
template
<
typename
T
>
void
ensure_compatible_rtti_held
(
const
char
*
context
)
const
{
if
(
!
rtti_held
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Unpopulated holder ("
)
+
context
+
")."
);
}
const
std
::
type_info
*
rtti_requested
=
&
typeid
(
T
);
if
(
!
(
*
rtti_requested
==
*
rtti_held
))
{
throw
std
::
runtime_error
(
std
::
string
(
"Incompatible type ("
)
+
context
+
")."
);
}
}
const
std
::
type_info
*
rtti_requested
=
&
typeid
(
T
);
if
(
!
(
*
rtti_requested
==
*
rtti_held
))
{
throw
std
::
runtime_error
(
std
::
string
(
"Incompatible type ("
)
+
context
+
")."
);
template
<
typename
D
>
void
ensure_compatible_rtti_uqp_del
(
const
char
*
context
)
const
{
if
(
!
rtti_uqp_del
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Missing unique_ptr deleter ("
)
+
context
+
")."
);
}
const
std
::
type_info
*
rtti_requested
=
&
typeid
(
D
);
if
(
!
(
*
rtti_requested
==
*
rtti_uqp_del
))
{
throw
std
::
runtime_error
(
std
::
string
(
"Incompatible unique_ptr deleter ("
)
+
context
+
")."
);
}
}
}
template
<
typename
D
>
void
ensure_compatible_rtti_uqp_del
(
const
char
*
context
)
const
{
if
(
!
rtti_uqp_del
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Missing unique_ptr deleter ("
)
+
context
+
")."
);
void
ensure_has_pointee
(
const
char
*
context
)
const
{
if
(
!
has_pointee
())
{
throw
std
::
runtime_error
(
std
::
string
(
"Disowned holder ("
)
+
context
+
")."
);
}
}
const
std
::
type_info
*
rtti_requested
=
&
typeid
(
D
);
if
(
!
(
*
rtti_requested
==
*
rtti_uqp_del
))
{
throw
std
::
runtime_error
(
std
::
string
(
"Incompatible unique_ptr deleter ("
)
+
context
+
")."
);
void
ensure_vptr_is_using_builtin_delete
(
const
char
*
context
)
const
{
if
(
vptr_is_external_shared_ptr
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown external shared_ptr ("
)
+
context
+
")."
);
}
if
(
vptr_is_using_noop_deleter
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown non-owning holder ("
)
+
context
+
")."
);
}
if
(
!
vptr_is_using_builtin_delete
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown custom deleter ("
)
+
context
+
")."
);
}
}
}
void
ensure_has_pointee
(
const
char
*
context
)
const
{
if
(
!
has_pointee
())
{
throw
std
::
runtime_error
(
std
::
string
(
"Disowned holder ("
)
+
context
+
")."
);
void
ensure_use_count_1
(
const
char
*
context
)
const
{
if
(
vptr
.
get
()
==
nullptr
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown nullptr ("
)
+
context
+
")."
);
}
if
(
vptr
.
use_count
()
!=
1
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown use_count != 1 ("
)
+
context
+
")."
);
}
}
}
void
ensure_vptr_is_using_builtin_delete
(
const
char
*
context
)
const
{
if
(
vptr_is_external_shared_ptr
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown external shared_ptr ("
)
+
context
+
")."
);
template
<
typename
T
>
static
smart_holder
from_raw_ptr_unowned
(
T
*
raw_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_is_using_noop_deleter
=
true
;
hld
.
vptr
.
reset
(
raw_ptr
,
guarded_builtin_delete
<
T
>
(
&
hld
.
vptr_deleter_guard_flag
));
return
hld
;
}
if
(
vptr_is_using_noop_deleter
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown non-owning holder ("
)
+
context
+
")."
);
template
<
typename
T
>
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
());
}
if
(
!
vptr_is_using_builtin_delete
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown custom deleter ("
)
+
context
+
")."
);
template
<
typename
T
>
T
&
lvalue_ref
()
const
{
static
const
char
*
context
=
"lvalue_ref"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_has_pointee
(
context
);
return
*
static_cast
<
T
*>
(
vptr
.
get
());
}
}
void
ensure_use_count_1
(
const
char
*
context
)
const
{
if
(
vptr
.
get
()
==
nullptr
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown nullptr ("
)
+
context
+
")."
);
template
<
typename
T
>
T
&&
rvalue_ref
()
const
{
static
const
char
*
context
=
"rvalue_ref"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_has_pointee
(
context
);
return
std
::
move
(
*
static_cast
<
T
*>
(
vptr
.
get
()));
}
if
(
vptr
.
use_count
()
!=
1
)
{
throw
std
::
runtime_error
(
std
::
string
(
"Cannot disown use_count != 1 ("
)
+
context
+
")."
);
template
<
typename
T
>
static
smart_holder
from_raw_ptr_take_ownership
(
T
*
raw_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_deleter_guard_flag
=
true
;
hld
.
vptr_is_using_builtin_delete
=
true
;
hld
.
vptr
.
reset
(
raw_ptr
,
guarded_builtin_delete
<
T
>
(
&
hld
.
vptr_deleter_guard_flag
));
return
hld
;
}
template
<
typename
T
>
T
*
as_raw_ptr_release_ownership
(
const
char
*
context
=
"as_raw_ptr_release_ownership"
)
{
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_vptr_is_using_builtin_delete
(
context
);
ensure_use_count_1
(
context
);
T
*
raw_ptr
=
static_cast
<
T
*>
(
vptr
.
get
());
vptr_deleter_guard_flag
=
false
;
vptr
.
reset
();
return
raw_ptr
;
}
template
<
typename
T
>
static
smart_holder
from_unique_ptr
(
std
::
unique_ptr
<
T
>
&&
unq_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_deleter_guard_flag
=
true
;
hld
.
vptr_is_using_builtin_delete
=
true
;
hld
.
vptr
.
reset
(
unq_ptr
.
get
(),
guarded_builtin_delete
<
T
>
(
&
hld
.
vptr_deleter_guard_flag
));
unq_ptr
.
release
();
return
hld
;
}
template
<
typename
T
>
std
::
unique_ptr
<
T
>
as_unique_ptr
()
{
return
std
::
unique_ptr
<
T
>
(
as_raw_ptr_release_ownership
<
T
>
(
"as_unique_ptr"
));
}
template
<
typename
T
,
typename
D
>
static
smart_holder
from_unique_ptr_with_deleter
(
std
::
unique_ptr
<
T
,
D
>
&&
unq_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
rtti_uqp_del
=
&
typeid
(
D
);
hld
.
vptr_deleter_guard_flag
=
true
;
hld
.
vptr
.
reset
(
unq_ptr
.
get
(),
guarded_custom_deleter
<
T
,
D
>
(
&
hld
.
vptr_deleter_guard_flag
));
unq_ptr
.
release
();
return
hld
;
}
template
<
typename
T
,
typename
D
>
std
::
unique_ptr
<
T
,
D
>
as_unique_ptr_with_deleter
()
{
static
const
char
*
context
=
"as_unique_ptr_with_deleter"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_compatible_rtti_uqp_del
<
D
>
(
context
);
ensure_use_count_1
(
context
);
T
*
raw_ptr
=
static_cast
<
T
*>
(
vptr
.
get
());
vptr_deleter_guard_flag
=
false
;
vptr
.
reset
();
return
std
::
unique_ptr
<
T
,
D
>
(
raw_ptr
);
}
template
<
typename
T
>
static
smart_holder
from_shared_ptr
(
std
::
shared_ptr
<
T
>
shd_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_is_external_shared_ptr
=
true
;
hld
.
vptr
=
std
::
static_pointer_cast
<
void
>
(
shd_ptr
);
return
hld
;
}
template
<
typename
T
>
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
);
}
}
template
<
typename
T
>
static
smart_holder
from_raw_ptr_unowned
(
T
*
raw_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_is_using_noop_deleter
=
true
;
hld
.
vptr
.
reset
(
raw_ptr
,
guarded_builtin_delete
<
T
>
(
&
hld
.
vptr_deleter_guard_flag
));
return
hld
;
}
template
<
typename
T
>
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
());
}
template
<
typename
T
>
T
&
lvalue_ref
()
const
{
static
const
char
*
context
=
"lvalue_ref"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_has_pointee
(
context
);
return
*
static_cast
<
T
*>
(
vptr
.
get
());
}
template
<
typename
T
>
T
&&
rvalue_ref
()
const
{
static
const
char
*
context
=
"rvalue_ref"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_has_pointee
(
context
);
return
std
::
move
(
*
static_cast
<
T
*>
(
vptr
.
get
()));
}
template
<
typename
T
>
static
smart_holder
from_raw_ptr_take_ownership
(
T
*
raw_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_deleter_guard_flag
=
true
;
hld
.
vptr_is_using_builtin_delete
=
true
;
hld
.
vptr
.
reset
(
raw_ptr
,
guarded_builtin_delete
<
T
>
(
&
hld
.
vptr_deleter_guard_flag
));
return
hld
;
}
template
<
typename
T
>
T
*
as_raw_ptr_release_ownership
(
const
char
*
context
=
"as_raw_ptr_release_ownership"
)
{
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_vptr_is_using_builtin_delete
(
context
);
ensure_use_count_1
(
context
);
T
*
raw_ptr
=
static_cast
<
T
*>
(
vptr
.
get
());
vptr_deleter_guard_flag
=
false
;
vptr
.
reset
();
return
raw_ptr
;
}
template
<
typename
T
>
static
smart_holder
from_unique_ptr
(
std
::
unique_ptr
<
T
>&&
unq_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_deleter_guard_flag
=
true
;
hld
.
vptr_is_using_builtin_delete
=
true
;
hld
.
vptr
.
reset
(
unq_ptr
.
get
(),
guarded_builtin_delete
<
T
>
(
&
hld
.
vptr_deleter_guard_flag
));
unq_ptr
.
release
();
return
hld
;
}
template
<
typename
T
>
std
::
unique_ptr
<
T
>
as_unique_ptr
()
{
return
std
::
unique_ptr
<
T
>
(
as_raw_ptr_release_ownership
<
T
>
(
"as_unique_ptr"
));
}
template
<
typename
T
,
typename
D
>
static
smart_holder
from_unique_ptr_with_deleter
(
std
::
unique_ptr
<
T
,
D
>&&
unq_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
rtti_uqp_del
=
&
typeid
(
D
);
hld
.
vptr_deleter_guard_flag
=
true
;
hld
.
vptr
.
reset
(
unq_ptr
.
get
(),
guarded_custom_deleter
<
T
,
D
>
(
&
hld
.
vptr_deleter_guard_flag
));
unq_ptr
.
release
();
return
hld
;
}
template
<
typename
T
,
typename
D
>
std
::
unique_ptr
<
T
,
D
>
as_unique_ptr_with_deleter
()
{
static
const
char
*
context
=
"as_unique_ptr_with_deleter"
;
ensure_compatible_rtti_held
<
T
>
(
context
);
ensure_compatible_rtti_uqp_del
<
D
>
(
context
);
ensure_use_count_1
(
context
);
T
*
raw_ptr
=
static_cast
<
T
*>
(
vptr
.
get
());
vptr_deleter_guard_flag
=
false
;
vptr
.
reset
();
return
std
::
unique_ptr
<
T
,
D
>
(
raw_ptr
);
}
template
<
typename
T
>
static
smart_holder
from_shared_ptr
(
std
::
shared_ptr
<
T
>
shd_ptr
)
{
smart_holder
hld
;
hld
.
rtti_held
=
&
typeid
(
T
);
hld
.
vptr_is_external_shared_ptr
=
true
;
hld
.
vptr
=
std
::
static_pointer_cast
<
void
>
(
shd_ptr
);
return
hld
;
}
template
<
typename
T
>
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
);
}
};
}
// namespace memory
}
// namespace pybindit
}
// namespace memory
}
// namespace pybindit
tests/core/smart_holder_poc_test.cpp
View file @
e7aea026
...
...
@@ -8,319 +8,294 @@ using pybindit::memory::smart_holder;
namespace
helpers
{
struct
movable_int
{
int
valu
;
movable_int
(
int
v
)
:
valu
{
v
}
{}
movable_int
(
movable_int
&&
other
)
{
valu
=
other
.
valu
;
other
.
valu
=
91
;
}
int
valu
;
movable_int
(
int
v
)
:
valu
{
v
}
{}
movable_int
(
movable_int
&&
other
)
{
valu
=
other
.
valu
;
other
.
valu
=
91
;
}
};
template
<
typename
T
>
struct
functor_builtin_delete
{
void
operator
()(
T
*
ptr
)
{
delete
ptr
;
}
void
operator
()(
T
*
ptr
)
{
delete
ptr
;
}
};
template
<
typename
T
>
struct
functor_other_delete
:
functor_builtin_delete
<
T
>
{};
}
// namespace helpers
}
// namespace helpers
TEST_CASE
(
"from_raw_ptr_unowned+as_raw_ptr_unowned"
,
"[S]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
*
hld
.
as_raw_ptr_unowned
<
int
>
()
==
19
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
*
hld
.
as_raw_ptr_unowned
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_raw_ptr_unowned+lvalue_ref"
,
"[S]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_raw_ptr_unowned+rvalue_ref"
,
"[S]"
)
{
helpers
::
movable_int
orig
(
19
);
{
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
orig
);
helpers
::
movable_int
othr
(
hld
.
rvalue_ref
<
helpers
::
movable_int
>
());
REQUIRE
(
othr
.
valu
==
19
);
REQUIRE
(
orig
.
valu
==
91
);
}
helpers
::
movable_int
orig
(
19
);
{
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
orig
);
helpers
::
movable_int
othr
(
hld
.
rvalue_ref
<
helpers
::
movable_int
>
());
REQUIRE
(
othr
.
valu
==
19
);
REQUIRE
(
orig
.
valu
==
91
);
}
}
TEST_CASE
(
"from_raw_ptr_unowned+as_raw_ptr_release_ownership"
,
"[E]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown non-owning holder (as_raw_ptr_release_ownership)."
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown non-owning holder (as_raw_ptr_release_ownership)."
);
}
TEST_CASE
(
"from_raw_ptr_unowned+as_unique_ptr"
,
"[E]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown non-owning holder (as_unique_ptr)."
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown non-owning holder (as_unique_ptr)."
);
}
TEST_CASE
(
"from_raw_ptr_unowned+as_unique_ptr_with_deleter"
,
"[E]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
}
TEST_CASE
(
"from_raw_ptr_unowned+as_shared_ptr"
,
"[S]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
*
hld
.
as_shared_ptr
<
int
>
()
==
19
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE
(
*
hld
.
as_shared_ptr
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+lvalue_ref"
,
"[S]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1"
,
"[S]"
)
{
auto
hld
=
smart_holder
::
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
());
REQUIRE
(
*
new_owner
==
19
);
auto
hld
=
smart_holder
::
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
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+as_raw_ptr_release_ownership2"
,
"[E]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown use_count != 1 (as_raw_ptr_release_ownership)."
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown use_count != 1 (as_raw_ptr_release_ownership)."
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+as_unique_ptr1"
,
"[S]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
std
::
unique_ptr
<
int
>
new_owner
=
hld
.
as_unique_ptr
<
int
>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
std
::
unique_ptr
<
int
>
new_owner
=
hld
.
as_unique_ptr
<
int
>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+as_unique_ptr2"
,
"[E]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown use_count != 1 (as_unique_ptr)."
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown use_count != 1 (as_unique_ptr)."
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+as_unique_ptr_with_deleter"
,
"[E]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
}
TEST_CASE
(
"from_raw_ptr_take_ownership+as_shared_ptr"
,
"[S]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
std
::
shared_ptr
<
int
>
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
std
::
shared_ptr
<
int
>
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_unique_ptr+lvalue_ref"
,
"[S]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_unique_ptr+as_raw_ptr_release_ownership1"
,
"[S]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
new_owner
=
std
::
unique_ptr
<
int
>
(
hld
.
as_raw_ptr_release_ownership
<
int
>
());
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
new_owner
=
std
::
unique_ptr
<
int
>
(
hld
.
as_raw_ptr_release_ownership
<
int
>
());
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_unique_ptr+as_raw_ptr_release_ownership2"
,
"[E]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown use_count != 1 (as_raw_ptr_release_ownership)."
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown use_count != 1 (as_raw_ptr_release_ownership)."
);
}
TEST_CASE
(
"from_unique_ptr+as_unique_ptr1"
,
"[S]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
unique_ptr
<
int
>
new_owner
=
hld
.
as_unique_ptr
<
int
>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
unique_ptr
<
int
>
new_owner
=
hld
.
as_unique_ptr
<
int
>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_unique_ptr+as_unique_ptr2"
,
"[E]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown use_count != 1 (as_unique_ptr)."
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
shd_ptr
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown use_count != 1 (as_unique_ptr)."
);
}
TEST_CASE
(
"from_unique_ptr+as_unique_ptr_with_deleter"
,
"[E]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
}
TEST_CASE
(
"from_unique_ptr+as_shared_ptr"
,
"[S]"
)
{
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
shared_ptr
<
int
>
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
std
::
unique_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
shared_ptr
<
int
>
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_unique_ptr_with_deleter+lvalue_ref"
,
"[S]"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_unique_ptr_with_deleter+as_raw_ptr_release_ownership"
,
"[E]"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown custom deleter (as_raw_ptr_release_ownership)."
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown custom deleter (as_raw_ptr_release_ownership)."
);
}
TEST_CASE
(
"from_unique_ptr_with_deleter+as_unique_ptr"
,
"[E]"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown custom deleter (as_unique_ptr)."
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown custom deleter (as_unique_ptr)."
);
}
TEST_CASE
(
"from_unique_ptr_with_deleter+as_unique_ptr_with_deleter1"
,
"[S]"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
new_owner
=
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
REQUIRE
(
!
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
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_unique_ptr_with_deleter+as_unique_ptr_with_deleter2"
,
"[E]"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_other_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Incompatible unique_ptr deleter (as_unique_ptr_with_deleter)."
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_other_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Incompatible unique_ptr deleter (as_unique_ptr_with_deleter)."
);
}
TEST_CASE
(
"from_unique_ptr_with_deleter+as_shared_ptr"
,
"[S]"
)
{
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
shared_ptr
<
int
>
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
std
::
unique_ptr
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_unique_ptr_with_deleter
(
std
::
move
(
orig_owner
));
REQUIRE
(
orig_owner
.
get
()
==
nullptr
);
std
::
shared_ptr
<
int
>
new_owner
=
hld
.
as_shared_ptr
<
int
>
();
REQUIRE
(
hld
.
has_pointee
());
REQUIRE
(
*
new_owner
==
19
);
}
TEST_CASE
(
"from_shared_ptr+lvalue_ref"
,
"[S]"
)
{
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE
(
hld
.
lvalue_ref
<
int
>
()
==
19
);
}
TEST_CASE
(
"from_shared_ptr+as_raw_ptr_release_ownership"
,
"[E]"
)
{
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown external shared_ptr (as_raw_ptr_release_ownership)."
);
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_release_ownership
<
int
>
(),
"Cannot disown external shared_ptr (as_raw_ptr_release_ownership)."
);
}
TEST_CASE
(
"from_shared_ptr+as_unique_ptr"
,
"[E]"
)
{
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown external shared_ptr (as_unique_ptr)."
);
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown external shared_ptr (as_unique_ptr)."
);
}
TEST_CASE
(
"from_shared_ptr+as_unique_ptr_with_deleter"
,
"[E]"
)
{
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
auto
condense_for_macro
=
[](
smart_holder
&
hld
)
{
hld
.
as_unique_ptr_with_deleter
<
int
,
helpers
::
functor_builtin_delete
<
int
>>
();
};
REQUIRE_THROWS_WITH
(
condense_for_macro
(
hld
),
"Missing unique_ptr deleter (as_unique_ptr_with_deleter)."
);
}
TEST_CASE
(
"from_shared_ptr+as_shared_ptr"
,
"[S]"
)
{
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE
(
*
hld
.
as_shared_ptr
<
int
>
()
==
19
);
std
::
shared_ptr
<
int
>
orig_owner
(
new
int
(
19
));
auto
hld
=
smart_holder
::
from_shared_ptr
(
orig_owner
);
REQUIRE
(
*
hld
.
as_shared_ptr
<
int
>
()
==
19
);
}
TEST_CASE
(
"error_unpopulated_holder"
,
"[E]"
)
{
smart_holder
hld
;
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_unowned
<
int
>
(),
"Unpopulated holder (as_raw_ptr_unowned)."
);
smart_holder
hld
;
REQUIRE_THROWS_WITH
(
hld
.
as_raw_ptr_unowned
<
int
>
(),
"Unpopulated holder (as_raw_ptr_unowned)."
);
}
TEST_CASE
(
"error_incompatible_type"
,
"[E]"
)
{
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
std
::
string
>
(),
"Incompatible type (as_unique_ptr)."
);
static
int
value
=
19
;
auto
hld
=
smart_holder
::
from_raw_ptr_unowned
(
&
value
);
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
std
::
string
>
(),
"Incompatible type (as_unique_ptr)."
);
}
TEST_CASE
(
"error_disowned_holder"
,
"[E]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
hld
.
as_unique_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
lvalue_ref
<
int
>
(),
"Disowned holder (lvalue_ref)."
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
hld
.
as_unique_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
lvalue_ref
<
int
>
(),
"Disowned holder (lvalue_ref)."
);
}
TEST_CASE
(
"error_cannot_disown_nullptr"
,
"[E]"
)
{
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
hld
.
as_unique_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown nullptr (as_unique_ptr)."
);
auto
hld
=
smart_holder
::
from_raw_ptr_take_ownership
(
new
int
(
19
));
hld
.
as_unique_ptr
<
int
>
();
REQUIRE_THROWS_WITH
(
hld
.
as_unique_ptr
<
int
>
(),
"Cannot disown nullptr (as_unique_ptr)."
);
}
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