Skip to content

Commit 000140e

Browse files
committed
Fixups for making the map binding work
1. Exposing detail::is_copy_assignable and detail::is_copy_assignable_v in nanobind/stl/detail/traits.h; 2. Exposing detail::is_copy_constructible_v in core nanobind (nanobind/nb_class.h); 3. Switching implementations to detail::is_copy{constructible,assignable}_v in bind_map.h;
1 parent c53d58b commit 000140e

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

include/nanobind/nb_class.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined
239239
template <typename T, typename SFINAE = int>
240240
struct is_copy_constructible : std::is_copy_constructible<T> { };
241241

242+
template <typename T>
243+
constexpr bool is_copy_constructible_v = is_copy_constructible<T>::value;
244+
242245
NAMESPACE_END(detail)
243246

244247
template <typename T, typename... Ts>
@@ -275,7 +278,7 @@ class class_ : public object {
275278
if constexpr (!std::is_same_v<Alias, T>)
276279
d.flags |= (uint32_t) detail::type_flags::is_trampoline;
277280

278-
if constexpr (detail::is_copy_constructible<T>::value) {
281+
if constexpr (detail::is_copy_constructible_v<T>) {
279282
d.flags |= (uint32_t) detail::type_flags::is_copy_constructible;
280283

281284
if constexpr (!std::is_trivially_copy_constructible_v<T>) {

include/nanobind/stl/bind_map.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <nanobind/nanobind.h>
1111
#include <nanobind/make_iterator.h>
12+
#include <nanobind/stl/detail/traits.h>
1213

1314
NAMESPACE_BEGIN(NB_NAMESPACE)
1415
NAMESPACE_BEGIN(detail)
@@ -139,10 +140,10 @@ class_<Map> bind_map(handle scope, const char *name, Args &&...args)
139140
cl.def("__contains__", [](const Map &, handle) -> bool { return false; });
140141

141142
// Assignment provided only if the type is copyable
142-
if constexpr(std::is_copy_assignable_v<MappedType> ||
143-
std::is_copy_constructible_v<MappedType>){
143+
if constexpr(detail::is_copy_assignable_v<MappedType> ||
144+
detail::is_copy_constructible_v<MappedType>){
144145
// Map assignment when copy-assignable: just copy the value
145-
if constexpr(std::is_copy_assignable_v<MappedType>){
146+
if constexpr(detail::is_copy_assignable_v<MappedType>){
146147
cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v)
147148
{
148149
auto it = m.find(k);

include/nanobind/stl/detail/traits.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,34 @@ struct is_copy_constructible<
3131
is_copy_constructible<typename T::value_type>::value;
3232
};
3333

34+
// std::pair is copy-constructible <=> both constituents are copy-constructible
3435
template <typename T1, typename T2>
3536
struct is_copy_constructible<std::pair<T1, T2>> {
3637
static constexpr bool value =
37-
is_copy_constructible<T1>::value ||
38+
is_copy_constructible<T1>::value &&
3839
is_copy_constructible<T2>::value;
3940
};
4041

42+
// The header file include/nanobind/stl/detail/traits.h extends this type trait
43+
template <typename T, typename SFINAE = int>
44+
struct is_copy_assignable : std::is_copy_assignable<T> { };
45+
46+
template <typename T>
47+
struct is_copy_assignable<T,
48+
enable_if_t<std::is_copy_assignable_v<T> &&
49+
std::is_same_v<typename T::value_type &,
50+
typename T::reference>>> {
51+
static constexpr bool value = is_copy_assignable<typename T::value_type>::value;
52+
};
53+
54+
template <typename T1, typename T2>
55+
struct is_copy_assignable<std::pair<T1, T2>> {
56+
static constexpr bool value = is_copy_assignable<T1>::value && is_copy_assignable<T2>::value;
57+
};
58+
59+
template <typename T>
60+
constexpr bool is_copy_assignable_v = is_copy_assignable<T>::value;
61+
4162
NAMESPACE_END(detail)
4263
NAMESPACE_END(NB_NAMESPACE)
4364

0 commit comments

Comments
 (0)