3535#include < optional>
3636#include < pybind11/detail/common.h>
3737#include < string>
38+ #include < type_traits>
3839#include < vector>
3940
4041using PyAttributeKeys = std::vector<std::string>;
@@ -266,29 +267,24 @@ bool setAttributeFromBufferInfo(
266267 }
267268}
268269
269- struct SetAttributeFromObject
270+ namespace detail
270271{
271- static constexpr char const *errorMsg = " Attributable.set_attribute() " ;
272-
273- template < typename RequestedType>
274- static bool
275- call (Attributable &attr, std::string const &key, py::object & obj)
272+ template < typename RequestedType>
273+ bool setAttributeFromObject_default (
274+ Attributable &attr, std::string const &key, py::object &obj)
275+ {
276+ if ( std::string ( py::str ( obj. get_type ())) == " <class 'list'> " )
276277 {
277- if (std::string (py::str (obj.get_type ())) == " <class 'list'>" )
278- {
279- using ListType = std::vector<RequestedType>;
280- return attr.setAttribute <ListType>(key, obj.cast <ListType>());
281- }
282- else
283- {
284- return attr.setAttribute <RequestedType>(
285- key, obj.cast <RequestedType>());
286- }
278+ using ListType = std::vector<RequestedType>;
279+ return attr.setAttribute <ListType>(key, obj.cast <ListType>());
287280 }
288- };
281+ else
282+ {
283+ return attr.setAttribute <RequestedType>(key, obj.cast <RequestedType>());
284+ }
285+ }
289286
290- template <>
291- bool SetAttributeFromObject::call<double >(
287+ bool setAttributeFromObject_double (
292288 Attributable &attr, std::string const &key, py::object &obj)
293289{
294290 if (std::string (py::str (obj.get_type ())) == " <class 'list'>" )
@@ -313,8 +309,7 @@ bool SetAttributeFromObject::call<double>(
313309 }
314310}
315311
316- template <>
317- bool SetAttributeFromObject::call<bool >(
312+ bool setAttributeFromObject_bool (
318313 Attributable &attr, std::string const &key, py::object &obj)
319314{
320315 return attr.setAttribute <bool >(key, obj.cast <bool >());
@@ -358,11 +353,14 @@ std::optional<TargetType> tryCast(py::object const &obj)
358353 }
359354}
360355
361- template <>
362- bool SetAttributeFromObject::call< char > (
356+ template <typename Char_t >
357+ bool setAttributeFromObject_char (
363358 Attributable &attr, std::string const &key, py::object &obj)
364359{
365- using explicit_char_type = typename char_to_explicit_char<>::type;
360+ using explicit_char_type = std::conditional_t <
361+ std::is_same_v<Char_t, char >,
362+ typename char_to_explicit_char<>::type,
363+ Char_t>;
366364 using ListChar = std::vector<char >;
367365 using ListString = std::vector<std::string>;
368366
@@ -425,6 +423,39 @@ bool SetAttributeFromObject::call<char>(
425423 " object as any char-based type." );
426424 }
427425}
426+ } // namespace detail
427+
428+ struct SetAttributeFromObject
429+ {
430+ static constexpr char const *errorMsg = " Attributable.set_attribute()" ;
431+
432+ template <typename RequestedType>
433+ static bool
434+ call (Attributable &attr, std::string const &key, py::object &obj)
435+ {
436+ if constexpr (std::is_same_v<RequestedType, double >)
437+ {
438+ return ::detail::setAttributeFromObject_double (attr, key, obj);
439+ }
440+ else if constexpr (std::is_same_v<RequestedType, bool >)
441+ {
442+ return ::detail::setAttributeFromObject_bool (attr, key, obj);
443+ }
444+ else if constexpr (
445+ std::is_same_v<RequestedType, char > ||
446+ std::is_same_v<RequestedType, signed char > ||
447+ std::is_same_v<RequestedType, unsigned char >)
448+ {
449+ return ::detail::setAttributeFromObject_char<RequestedType>(
450+ attr, key, obj);
451+ }
452+ else
453+ {
454+ return ::detail::setAttributeFromObject_default<RequestedType>(
455+ attr, key, obj);
456+ }
457+ }
458+ };
428459
429460bool setAttributeFromObject (
430461 Attributable &attr,
0 commit comments