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 virtual TPimpl copy()
const = 0;
67 virtual PyObject* subscript(PyObject* key)
const = 0;
68 virtual int assSubscript(PyObject* key, PyObject* value) = 0;
69 virtual PyObject* keys()
const = 0;
70 virtual PyObject* values()
const = 0;
73 template<
typename Container>
74 class PyMapImpl:
public ContainerImpl<Container, PyMapImplBase>
77 typedef ContainerImpl<Container, PyMapImplBase> TBase;
78 typedef typename TBase::TContainerPtr TContainerPtr;
79 typedef typename TBase::TConstContainerPtr TConstContainerPtr;
80 typedef typename TBase::TContainerTraits TContainerTraits;
81 typedef PyMapImplBase::TPimpl TPimpl;
82 typedef ArgumentTraits<typename Container::key_type> TKeyArgTraits;
83 typedef ArgumentTraits<typename Container::mapped_type> TMappedArgTraits;
85 PyMapImpl(
const TContainerPtr& container,
bool readOnly =
false):
86 TBase(container, readOnly)
89 TPimpl copy()
const override
91 TContainerPtr copy = TContainerTraits::copy(this->container());
92 return TPimpl(
new PyMapImpl(copy));
94 PyObject* subscript(PyObject* key)
const override
96 LockGIL LASS_UNUSED(lock);
97 typename TKeyArgTraits::TStorage k;
98 if (pyGetSimpleObject(key, k) != 0)
100 PyErr_SetObject(PyExc_KeyError, key);
103 auto it = this->container().find(TKeyArgTraits::arg(k));
104 if (it == this->container().end())
106 PyErr_SetObject(PyExc_KeyError, key);
109 return pyBuildSimpleObject(it->second);
111 int assSubscript(PyObject* key, PyObject* value)
override
113 LockGIL LASS_UNUSED(lock);
114 if (!this->checkWritable())
120 typename TKeyArgTraits::TStorage k;
121 if (pyGetSimpleObject(key, k) != 0)
126 typename TMappedArgTraits::TStorage v;
127 if (pyGetSimpleObject(value, v) != 0)
132 this->container().emplace(TKeyArgTraits::arg(k), TMappedArgTraits::arg(v));
136 typename TKeyArgTraits::TStorage k;
137 if (pyGetSimpleObject(key, k) != 0)
139 PyErr_SetObject(PyExc_KeyError, key);
142 auto it = this->container().find(TKeyArgTraits::arg(k));
143 if (it == this->container().end())
145 PyErr_SetObject(PyExc_KeyError, key);
148 this->container().erase(it);
152 PyObject* keys()
const override
154 return new PyIteratorRange(
155 stde::first_iterator(this->container().begin()), stde::first_iterator(this->container().end()));
157 PyObject* values()
const override
159 return new PyIteratorRange(
160 stde::second_iterator(this->container().begin()), stde::second_iterator(this->container().end()));
162 const TPyObjPtr asNative()
const override
164 return pyBuildMap(this->container().begin(), this->container().end());
169 typedef PyObjectPtr<Map>::Type TMapPtr;
177 template <
typename Container> Map(
const util::SharedPtr<Container>& container )
179 TPimpl pimpl(
new PyMapImpl<Container>(
180 LASS_ENFORCE_POINTER(container)));
181 init(std::move(pimpl));
183 template<
typename Container> Map(
const util::SharedPtr<const Container>& container )
185 TPimpl pimpl(
new PyMapImpl<Container>(
186 LASS_ENFORCE_POINTER(container).
template constCast<Container>(),
true));
187 init(std::move(pimpl));
189 template<
typename Container> Map(
const Container& container )
191 util::SharedPtr<Container> p(
new Container(container));
192 TPimpl pimpl(
new PyMapImpl<Container>(p,
true));
193 init(std::move(pimpl));
197 std::string repr()
const;
205 const TMapPtr copy()
const;
208 const std::type_info& type()
const;
209 void* raw(
bool writable)
const;
211 static Py_ssize_t length(PyObject* self);
212 static PyObject* subscript(PyObject* self, PyObject* key);
213 static int assSubscript(PyObject* self, PyObject* key, PyObject* value);
216 typedef PyMapImplBase::TPimpl TPimpl;
219 void init(TPimpl&& pimpl);
225 struct ShadowTraits<
Map>:
public ShadowTraitsContainer< Map, ShadowTraits<Map> >
227 template <
typename Container>
static int getObjectImpl(PyObject* obj, util::SharedPtr<Container>& value,
bool writable)
229 if (!PyMapping_Check(obj))
231 PyErr_SetString(PyExc_TypeError,
"not a map");
236 if (obj->ob_type == Map::_lassPyClassDef.type())
238 const Map*
const map =
static_cast<Map*
>(obj);
239 void*
const raw = map->raw(writable);
240 if (raw &&
typeid(value) == map->type())
242 value = *
static_cast< util::SharedPtr<Container>*
>(raw);
247 const util::SharedPtr<Container> result(
new Container);
248 const Py_ssize_t size = PyMapping_Length(obj);
252 PyErr_SetString(PyExc_TypeError,
"Not a mapping");
255 TPyObjPtr fast = impl::checkedFastSequence(items.get(), size);
260 PyObject** pairs = PySequence_Fast_ITEMS(fast.get());
261 typedef ArgumentTraits<typename Container::key_type> TKeyArgTraits;
262 typedef ArgumentTraits<typename Container::mapped_type> TMappedArgTraits;
263 for (Py_ssize_t i = 0; i < size; ++i)
265 typename TKeyArgTraits::TStorage key;
266 typename TMappedArgTraits::TStorage mapped;
267 if (decodeTuple(pairs[i], key, mapped) != 0)
272 result->emplace(TKeyArgTraits::arg(key), TMappedArgTraits::arg(mapped));
274 value = std::move(result);
280template <
typename ContainerType>
281struct ShadoweeTraitsMap: meta::True
283 typedef impl::Map TShadow;
284 typedef impl::ShadowTraits<impl::Map> TShadowTraits;
285 typedef SharedPointerTraits<ContainerType> TPointerTraits;
291template<
typename K,
typename T,
typename C,
typename A>
292struct ShadoweeTraits< std::map<K, T, C, A> >:
293 public ShadoweeTraitsMap< std::map<K, T, C, A> >
303#ifdef LASS_GUARDIAN_OF_INCLUSION_STDE_VECTOR_MAP_H
312template<
typename K,
typename T,
typename C,
typename A>
313struct ShadoweeTraits< stde::vector_map<K, T, C, A> >:
314 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.