mirror of
https://github.com/pybind/pybind11.git
synced 2026-05-12 17:26:13 +00:00
std::valarray support for stl.h (#545)
* Added ternary support with descr args Current the `_<bool>(a, b)` ternary support only works for `char[]` `a` and `b`; this commit allows it to work for `descr` `a` and `b` arguments as well. * Add support for std::valarray to stl.h This abstracts the std::array into a `array_caster` which can then be used with either std::array or std::valarray, the main difference being that std::valarray is resizable. (It also lets the array_caster be potentially used for other std::array-like interfaces, much as the list_caster and map_caster currently provide). * Small stl.h cleanups - Remove redundant `type` typedefs - make internal list_caster methods private
This commit is contained in:
committed by
Wenzel Jakob
parent
ab90ec6ce9
commit
ae185b7f19
@@ -81,6 +81,10 @@ template <bool B, size_t Size1, size_t Size2>
|
||||
constexpr enable_if_t<!B, descr<Size2 - 1, 0>> _(char const(&)[Size1], char const(&text2)[Size2]) {
|
||||
return _(text2);
|
||||
}
|
||||
template <bool B, size_t SizeA1, size_t SizeA2, size_t SizeB1, size_t SizeB2>
|
||||
constexpr enable_if_t<B, descr<SizeA1, SizeA2>> _(descr<SizeA1, SizeA2> d, descr<SizeB1, SizeB2>) { return d; }
|
||||
template <bool B, size_t SizeA1, size_t SizeA2, size_t SizeB1, size_t SizeB2>
|
||||
constexpr enable_if_t<!B, descr<SizeB1, SizeB2>> _(descr<SizeA1, SizeA2>, descr<SizeB1, SizeB2> d) { return d; }
|
||||
|
||||
template <size_t Size> auto constexpr _() -> decltype(int_to_str<Size / 10, Size % 10>::digits) {
|
||||
return int_to_str<Size / 10, Size % 10>::digits;
|
||||
@@ -154,6 +158,8 @@ PYBIND11_NOINLINE inline descr _(const char *text) {
|
||||
|
||||
template <bool B> PYBIND11_NOINLINE enable_if_t<B, descr> _(const char *text1, const char *) { return _(text1); }
|
||||
template <bool B> PYBIND11_NOINLINE enable_if_t<!B, descr> _(char const *, const char *text2) { return _(text2); }
|
||||
template <bool B> PYBIND11_NOINLINE enable_if_t<B, descr> _(descr d, descr) { return d; }
|
||||
template <bool B> PYBIND11_NOINLINE enable_if_t<!B, descr> _(descr, descr d) { return d; }
|
||||
|
||||
template <typename Type> PYBIND11_NOINLINE descr _() {
|
||||
const std::type_info *types[2] = { &typeid(Type), nullptr };
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <unordered_map>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <valarray>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
@@ -72,7 +73,6 @@ template <typename Type, typename Key> struct set_caster {
|
||||
};
|
||||
|
||||
template <typename Type, typename Key, typename Value> struct map_caster {
|
||||
using type = Type;
|
||||
using key_conv = make_caster<Key>;
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
@@ -92,7 +92,7 @@ template <typename Type, typename Key, typename Value> struct map_caster {
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const type &src, return_value_policy policy, handle parent) {
|
||||
static handle cast(const Type &src, return_value_policy policy, handle parent) {
|
||||
dict d;
|
||||
for (auto const &kv: src) {
|
||||
auto key = reinterpret_steal<object>(key_conv::cast(kv.first, policy, parent));
|
||||
@@ -104,11 +104,10 @@ template <typename Type, typename Key, typename Value> struct map_caster {
|
||||
return d.release();
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(type, _("Dict[") + key_conv::name() + _(", ") + value_conv::name() + _("]"));
|
||||
PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name() + _(", ") + value_conv::name() + _("]"));
|
||||
};
|
||||
|
||||
template <typename Type, typename Value> struct list_caster {
|
||||
using type = Type;
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
@@ -126,11 +125,13 @@ template <typename Type, typename Value> struct list_caster {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T = Type,
|
||||
enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>
|
||||
void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); }
|
||||
void reserve_maybe(sequence, void *) { }
|
||||
|
||||
public:
|
||||
static handle cast(const Type &src, return_value_policy policy, handle parent) {
|
||||
list l(src.size());
|
||||
size_t index = 0;
|
||||
@@ -152,28 +153,40 @@ template <typename Type, typename Alloc> struct type_caster<std::vector<Type, Al
|
||||
template <typename Type, typename Alloc> struct type_caster<std::list<Type, Alloc>>
|
||||
: list_caster<std::list<Type, Alloc>, Type> { };
|
||||
|
||||
template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>> {
|
||||
using array_type = std::array<Type, Size>;
|
||||
using value_conv = make_caster<Type>;
|
||||
template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0> struct array_caster {
|
||||
using value_conv = make_caster<Value>;
|
||||
|
||||
private:
|
||||
template <bool R = Resizable>
|
||||
bool require_size(enable_if_t<R, size_t> size) {
|
||||
if (value.size() != size)
|
||||
value.resize(size);
|
||||
return true;
|
||||
}
|
||||
template <bool R = Resizable>
|
||||
bool require_size(enable_if_t<!R, size_t> size) {
|
||||
return size == Size;
|
||||
}
|
||||
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (!isinstance<list>(src))
|
||||
return false;
|
||||
auto l = reinterpret_borrow<list>(src);
|
||||
if (l.size() != Size)
|
||||
if (!require_size(l.size()))
|
||||
return false;
|
||||
value_conv conv;
|
||||
size_t ctr = 0;
|
||||
for (auto it : l) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value[ctr++] = cast_op<Type>(conv);
|
||||
value[ctr++] = cast_op<Value>(conv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const array_type &src, return_value_policy policy, handle parent) {
|
||||
list l(Size);
|
||||
static handle cast(const ArrayType &src, return_value_policy policy, handle parent) {
|
||||
list l(src.size());
|
||||
size_t index = 0;
|
||||
for (auto const &value: src) {
|
||||
auto value_ = reinterpret_steal<object>(value_conv::cast(value, policy, parent));
|
||||
@@ -183,9 +196,16 @@ template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>>
|
||||
}
|
||||
return l.release();
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(array_type, _("List[") + value_conv::name() + _("[") + _<Size>() + _("]]"));
|
||||
|
||||
PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name() + _<Resizable>(_(""), _("[") + _<Size>() + _("]")) + _("]"));
|
||||
};
|
||||
|
||||
template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>>
|
||||
: array_caster<std::array<Type, Size>, Type, false, Size> { };
|
||||
|
||||
template <typename Type> struct type_caster<std::valarray<Type>>
|
||||
: array_caster<std::valarray<Type>, Type, true> { };
|
||||
|
||||
template <typename Key, typename Compare, typename Alloc> struct type_caster<std::set<Key, Compare, Alloc>>
|
||||
: set_caster<std::set<Key, Compare, Alloc>, Key> { };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user