43#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_PYMAP_H
44#define LASS_GUARDIAN_OF_INCLUSION_UTIL_PYMAP_H
62 class LASS_PYTHON_DLL PyMapImplBase:
public ContainerImplBase
65 typedef std::unique_ptr<PyMapImplBase> TPimpl;
66 using ContainerImplBase::ContainerImplBase;
67 virtual TPimpl copy()
const = 0;
68 virtual PyObject* subscript(PyObject* key)
const = 0;
69 virtual int assSubscript(PyObject* key, PyObject* value) = 0;
70 virtual PyObject* keys()
const = 0;
71 virtual PyObject* values()
const = 0;
74 template<
typename Container>
75 class PyMapImpl:
public ContainerImpl<Container, PyMapImplBase>
78 typedef ContainerImpl<Container, PyMapImplBase> TBase;
79 typedef typename TBase::TContainerPtr TContainerPtr;
80 typedef typename TBase::TConstContainerPtr TConstContainerPtr;
81 typedef typename TBase::TContainerTraits TContainerTraits;
82 typedef PyMapImplBase::TPimpl TPimpl;
83 typedef ArgumentTraits<typename Container::key_type> TKeyArgTraits;
84 typedef ArgumentTraits<typename Container::mapped_type> TMappedArgTraits;
86 PyMapImpl(
const TContainerPtr& container,
bool readOnly =
false):
87 TBase(container, readOnly)
90 TPimpl copy()
const override
92 TContainerPtr copy = TContainerTraits::copy(this->container());
93 return TPimpl(
new PyMapImpl(copy));
95 PyObject* subscript(PyObject* key)
const override
98 typename TKeyArgTraits::TStorage k;
99 if (pyGetSimpleObject(key, k) != 0)
101 PyErr_SetObject(PyExc_KeyError, key);
104 auto it = this->container().find(TKeyArgTraits::arg(k));
105 if (it == this->container().end())
107 PyErr_SetObject(PyExc_KeyError, key);
110 return pyBuildSimpleObject(it->second);
112 int assSubscript(PyObject* key, PyObject* value)
override
115 if (!this->checkWritable())
121 typename TKeyArgTraits::TStorage k;
122 if (pyGetSimpleObject(key, k) != 0)
127 typename TMappedArgTraits::TStorage v;
128 if (pyGetSimpleObject(value, v) != 0)
133 this->container().insert_or_assign(TKeyArgTraits::arg(k), TMappedArgTraits::arg(v));
137 typename TKeyArgTraits::TStorage k;
138 if (pyGetSimpleObject(key, k) != 0)
140 PyErr_SetObject(PyExc_KeyError, key);
143 auto it = this->container().find(TKeyArgTraits::arg(k));
144 if (it == this->container().end())
146 PyErr_SetObject(PyExc_KeyError, key);
149 this->container().erase(it);
153 PyObject* keys()
const override
155 return new PyIteratorRange(
156 stde::first_iterator(this->container().begin()), stde::first_iterator(this->container().end()));
158 PyObject* values()
const override
160 return new PyIteratorRange(
161 stde::second_iterator(this->container().begin()), stde::second_iterator(this->container().end()));
163 const TPyObjPtr asNative()
const override
165 return pyBuildMap(this->container().begin(), this->container().end());
170 typedef PyObjectPtr<Map>::Type TMapPtr;
178 template <
typename Container> Map(
const util::SharedPtr<Container>& container )
180 TPimpl pimpl(
new PyMapImpl<Container>(
181 LASS_ENFORCE_POINTER(container)));
182 init(std::move(pimpl));
184 template<
typename Container> Map(
const util::SharedPtr<const Container>& container )
186 TPimpl pimpl(
new PyMapImpl<Container>(
187 (LASS_ENFORCE_POINTER(container)).
template constCast<Container>(),
true));
188 init(std::move(pimpl));
190 template<
typename Container> Map(
const Container& container )
192 util::SharedPtr<Container> p(
new Container(container));
193 TPimpl pimpl(
new PyMapImpl<Container>(p,
true));
194 init(std::move(pimpl));
198 std::string repr()
const;
206 const TMapPtr copy()
const;
209 const std::type_info& type()
const;
210 void* raw(
bool writable)
const;
212 static Py_ssize_t length(PyObject* self);
213 static PyObject* subscript(PyObject* self, PyObject* key);
214 static int assSubscript(PyObject* self, PyObject* key, PyObject* value);
217 typedef PyMapImplBase::TPimpl TPimpl;
220 void init(TPimpl&& pimpl);
226 struct ShadowTraits<
Map>:
public ShadowTraitsContainer< Map, ShadowTraits<Map> >
228 template <
typename Container>
static int getObjectImpl(PyObject* obj, util::SharedPtr<Container>& value,
bool writable)
230 if (!PyMapping_Check(obj))
232 PyErr_SetString(PyExc_TypeError,
"not a map");
237 if (obj->ob_type == Map::_lassPyClassDef.type())
239 const Map*
const map =
static_cast<Map*
>(obj);
240 void*
const raw = map->raw(writable);
241 if (raw &&
typeid(value) == map->type())
243 value = *
static_cast< util::SharedPtr<Container>*
>(raw);
248 const util::SharedPtr<Container> result(
new Container);
249 const Py_ssize_t size = PyMapping_Length(obj);
253 PyErr_SetString(PyExc_TypeError,
"Not a mapping");
256 TPyObjPtr fast = impl::checkedFastSequence(items.get(), size);
261 PyObject** pairs = PySequence_Fast_ITEMS(fast.get());
262 typedef ArgumentTraits<typename Container::key_type> TKeyArgTraits;
263 typedef ArgumentTraits<typename Container::mapped_type> TMappedArgTraits;
264 for (Py_ssize_t i = 0; i < size; ++i)
266 typename TKeyArgTraits::TStorage key;
267 typename TMappedArgTraits::TStorage mapped;
268 if (decodeTuple(pairs[i], key, mapped) != 0)
273 [[maybe_unused]]
auto r = result->emplace(TKeyArgTraits::arg(key), TMappedArgTraits::arg(mapped));
274 LASS_ASSERT(r.second);
276 value = std::move(result);
282template <
typename ContainerType>
283struct ShadoweeTraitsMap: meta::True
285 typedef impl::Map TShadow;
286 typedef impl::ShadowTraits<impl::Map> TShadowTraits;
287 typedef SharedPointerTraits<ContainerType> TPointerTraits;
293template<
typename K,
typename T,
typename C,
typename A>
294struct ShadoweeTraits< std::map<K, T, C, A> >:
295 public ShadoweeTraitsMap< std::map<K, T, C, A> >
305#ifdef LASS_GUARDIAN_OF_INCLUSION_STDE_VECTOR_MAP_H
314template<
typename K,
typename T,
typename C,
typename A>
315struct ShadoweeTraits< stde::vector_map<K, T, C, A> >:
316 public ShadoweeTraitsMap< stde::vector_map<K, T, C, A> >
use as base class if derived should not be copyable
void addMessageHeader(const char *header)
Prepend a message to the current Python exception value.
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
#define PY_HEADER(t_parentClass)
Place as first line of your Pythonized class.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.