| Server IP : 217.160.0.135 / Your IP : 216.73.217.85 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1074145052 ( 1074145052) PHP Version : 8.3.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /usr/lib/python3/dist-packages/pythran/pythonic/types/ |
Upload File : |
#ifndef PYTHONIC_TYPES_DICT_HPP
#define PYTHONIC_TYPES_DICT_HPP
#include "pythonic/include/types/dict.hpp"
#include "pythonic/types/tuple.hpp"
#include "pythonic/types/empty_iterator.hpp"
#include "pythonic/utils/iterator.hpp"
#include "pythonic/utils/reserve.hpp"
#include "pythonic/builtins/None.hpp"
#include "pythonic/utils/shared_ref.hpp"
#include <memory>
#include <utility>
#include <limits>
#include <algorithm>
#include <iterator>
PYTHONIC_NS_BEGIN
namespace types
{
/// item implementation
template <class I>
item_iterator_adaptator<I>::item_iterator_adaptator(I const &i)
: I(i)
{
}
template <class I>
typename item_iterator_adaptator<I>::value_type item_iterator_adaptator<I>::
operator*() const
{
auto &&tmp = I::operator*();
return make_tuple(tmp.first, tmp.second);
}
/// key_iterator_adaptator implementation
template <class I>
key_iterator_adaptator<I>::key_iterator_adaptator()
: I()
{
}
template <class I>
key_iterator_adaptator<I>::key_iterator_adaptator(I const &i)
: I(i)
{
}
template <class I>
typename key_iterator_adaptator<I>::value_type key_iterator_adaptator<I>::
operator*() const
{
return (*this)->first;
}
/// value_iterator_adaptator implementation
template <class I>
value_iterator_adaptator<I>::value_iterator_adaptator()
: I()
{
}
template <class I>
value_iterator_adaptator<I>::value_iterator_adaptator(I const &i)
: I(i)
{
}
template <class I>
typename value_iterator_adaptator<I>::value_type value_iterator_adaptator<I>::
operator*() const
{
return (*this)->second;
}
template <class D>
dict_items<D>::dict_items()
{
}
template <class D>
dict_items<D>::dict_items(D const &d)
: data(d)
{
}
template <class D>
typename dict_items<D>::iterator dict_items<D>::begin() const
{
return data.item_begin();
}
template <class D>
typename dict_items<D>::iterator dict_items<D>::end() const
{
return data.item_end();
}
template <class D>
long dict_items<D>::size() const
{
return data.size();
}
template <class D>
dict_keys<D>::dict_keys()
{
}
template <class D>
dict_keys<D>::dict_keys(D const &d)
: data(d)
{
}
template <class D>
typename dict_keys<D>::iterator dict_keys<D>::begin() const
{
return data.key_begin();
}
template <class D>
typename dict_keys<D>::iterator dict_keys<D>::end() const
{
return data.key_end();
}
template <class D>
long dict_keys<D>::size() const
{
return data.size();
}
template <class D>
dict_values<D>::dict_values()
{
}
template <class D>
dict_values<D>::dict_values(D const &d)
: data(d)
{
}
template <class D>
typename dict_values<D>::iterator dict_values<D>::begin() const
{
return data.value_begin();
}
template <class D>
typename dict_values<D>::iterator dict_values<D>::end() const
{
return data.value_end();
}
template <class D>
long dict_values<D>::size() const
{
return data.size();
}
template <class K, class V>
dict<K, V>::dict()
: data(utils::no_memory())
{
}
template <class K, class V>
dict<K, V>::dict(empty_dict const &)
: data(DEFAULT_DICT_CAPACITY)
{
}
template <class K, class V>
dict<K, V>::dict(std::initializer_list<value_type> l)
: data(l.begin(), l.end())
{
}
template <class K, class V>
dict<K, V>::dict(dict<K, V> const &other)
: data(other.data)
{
}
template <class K, class V>
template <class Kp, class Vp>
dict<K, V>::dict(dict<Kp, Vp> const &other)
: data(other.data->begin(), other.data->end())
{
}
template <class K, class V>
template <class B, class E>
dict<K, V>::dict(B begin, E end)
: data(begin, end)
{
}
// iterators
template <class K, class V>
typename dict<K, V>::iterator dict<K, V>::begin()
{
return typename dict<K, V>::iterator(data->begin());
}
template <class K, class V>
typename dict<K, V>::const_iterator dict<K, V>::begin() const
{
return key_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::iterator dict<K, V>::end()
{
return typename dict<K, V>::iterator(data->end());
}
template <class K, class V>
typename dict<K, V>::const_iterator dict<K, V>::end() const
{
return key_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->end());
}
template <class K, class V>
typename dict<K, V>::item_iterator dict<K, V>::item_begin()
{
return item_iterator_adaptator<
typename dict<K, V>::container_type::iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::item_const_iterator dict<K, V>::item_begin() const
{
return item_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::item_iterator dict<K, V>::item_end()
{
return item_iterator_adaptator<
typename dict<K, V>::container_type::iterator>(data->end());
}
template <class K, class V>
typename dict<K, V>::item_const_iterator dict<K, V>::item_end() const
{
return item_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->end());
}
template <class K, class V>
typename dict<K, V>::key_iterator dict<K, V>::key_begin()
{
return key_iterator_adaptator<
typename dict<K, V>::container_type::iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::key_const_iterator dict<K, V>::key_begin() const
{
return key_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::key_iterator dict<K, V>::key_end()
{
return key_iterator_adaptator<
typename dict<K, V>::container_type::iterator>(data->end());
}
template <class K, class V>
typename dict<K, V>::key_const_iterator dict<K, V>::key_end() const
{
return key_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->end());
}
template <class K, class V>
typename dict<K, V>::value_iterator dict<K, V>::value_begin()
{
return value_iterator_adaptator<
typename dict<K, V>::container_type::iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::value_const_iterator dict<K, V>::value_begin() const
{
return value_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->begin());
}
template <class K, class V>
typename dict<K, V>::value_iterator dict<K, V>::value_end()
{
return value_iterator_adaptator<
typename dict<K, V>::container_type::iterator>(data->end());
}
template <class K, class V>
typename dict<K, V>::value_const_iterator dict<K, V>::value_end() const
{
return value_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->end());
}
// dict interface
template <class K, class V>
dict<K, V>::operator bool()
{
return !data->empty();
}
template <class K, class V>
V &dict<K, V>::operator[](K const &key)
{
return fast(key);
}
template <class K, class V>
V const &dict<K, V>::operator[](K const &key) const
{
return fast(key);
}
template <class K, class V>
V &dict<K, V>::fast(K const &key)
{
return (*data)[key];
}
template <class K, class V>
V const &dict<K, V>::fast(K const &key) const
{
return (*data)[key];
}
template <class K, class V>
typename dict<K, V>::item_const_iterator dict<K, V>::find(K const &key) const
{
return item_iterator_adaptator<
typename dict<K, V>::container_type::const_iterator>(data->find(key));
}
template <class K, class V>
void dict<K, V>::clear()
{
return data->clear();
}
template <class K, class V>
dict<K, V> dict<K, V>::copy() const
{
return dict<K, V>(this->data->begin(), this->data->end());
}
template <class K, class V>
template <class W>
typename __combined<V, W>::type dict<K, V>::get(K const &key, W d) const
{
auto ivalue = data->find(key);
if (ivalue != data->end())
return ivalue->second;
else
return d;
}
template <class K, class V>
none<V> dict<K, V>::get(K const &key) const
{
auto ivalue = data->find(key);
if (ivalue != data->end())
return ivalue->second;
else
return builtins::None;
}
template <class K, class V>
template <class W>
V &dict<K, V>::setdefault(K const &key, W d)
{
auto ivalue = data->find(key);
if (ivalue != data->end())
return ivalue->second;
else
return (*data)[key] = d;
}
template <class K, class V>
none<V> &dict<K, V>::setdefault(K const &key)
{
auto ivalue = data->find(key);
if (ivalue != data->end())
return ivalue->second;
else
return (*data)[key] = builtins::None;
}
template <class K, class V>
template <class K0, class W0>
void dict<K, V>::update(dict<K0, W0> const &d)
{
for (auto kv : *d.data)
(*data)[kv.first] = kv.second;
}
template <class K, class V>
template <class Iterable>
void dict<K, V>::update(Iterable const &d)
{
for (auto kv : d)
(*data)[std::get<0>(kv)] = std::get<1>(kv);
}
template <class K, class V>
template <class W>
typename __combined<V, W>::type dict<K, V>::pop(K const &key, W d)
{
auto ivalue = data->find(key);
if (ivalue != data->end()) {
auto tmp = ivalue->second;
data->erase(ivalue);
return tmp;
} else
return d;
}
template <class K, class V>
V dict<K, V>::pop(K const &key)
{
auto ivalue = data->find(key);
if (ivalue != data->end()) {
auto tmp = ivalue->second;
data->erase(ivalue);
return tmp;
} else
throw std::range_error("KeyError");
}
template <class K, class V>
make_tuple_t<K, V> dict<K, V>::popitem()
{
auto b = data->begin();
if (b == data->end())
throw std::range_error("KeyError");
else {
auto r = *b;
data->erase(b);
return make_tuple_t<K, V>{r.first, r.second};
}
}
template <class K, class V>
long dict<K, V>::size() const
{
return data->size();
}
template <class K, class V>
dict_items<dict<K, V>> dict<K, V>::items() const
{
return dict_items<dict<K, V>>(*this);
}
template <class K, class V>
dict_keys<dict<K, V>> dict<K, V>::keys() const
{
return dict_keys<dict<K, V>>(*this);
}
template <class K, class V>
dict_values<dict<K, V>> dict<K, V>::values() const
{
return dict_values<dict<K, V>>(*this);
}
// id interface
template <class K, class V>
intptr_t dict<K, V>::id() const
{
return reinterpret_cast<intptr_t>(&(*data));
}
template <class K, class V>
template <class T>
bool dict<K, V>::contains(T const &key) const
{
return data->find(key) != data->end();
}
template <class K, class V>
dict<K, V> empty_dict::operator+(dict<K, V> const &s)
{
return s;
}
empty_dict empty_dict::operator+(empty_dict const &)
{
return empty_dict();
}
empty_dict::operator bool() const
{
return false;
}
typename empty_dict::iterator empty_dict::begin() const
{
return empty_iterator();
}
typename empty_dict::iterator empty_dict::end() const
{
return empty_iterator();
}
template <class V>
bool empty_dict::contains(V const &) const
{
return false;
}
template <class K, class V>
dict<K, V> operator+(dict<K, V> const &d, empty_dict)
{
return d;
}
}
std::ostream &operator<<(std::ostream &os, types::empty_dict const &)
{
return os << "{}";
}
template <class K, class V>
std::ostream &operator<<(std::ostream &os, std::pair<K, V> const &p)
{
os << p.first << ": ";
return os << p.second;
}
template <class K, class V>
std::ostream &operator<<(std::ostream &os, types::dict<K, V> const &v)
{
os << '{';
auto iter = v.item_begin();
if (iter != v.item_end()) {
auto niter = iter;
++niter;
while (niter != v.item_end()) {
os << *iter << ", ";
++niter, ++iter;
}
os << *iter;
}
return os << '}';
}
PYTHONIC_NS_END
/* overload std::get */
namespace std
{
template <size_t I, class K, class V>
auto get(pythonic::types::dict<K, V> &d) -> decltype(d[I])
{
return d[I];
}
template <size_t I, class K, class V>
auto get(pythonic::types::dict<K, V> const &d) -> decltype(d[I])
{
return d[I];
}
}
#ifdef ENABLE_PYTHON_MODULE
#include "pythonic/python/core.hpp"
PYTHONIC_NS_BEGIN
template <typename K, typename V>
PyObject *to_python<types::dict<K, V>>::convert(types::dict<K, V> const &v)
{
PyObject *ret = PyDict_New();
for (auto kv = v.item_begin(); kv != v.item_end(); ++kv) {
PyObject *kobj = ::to_python(kv->first), *vobj = ::to_python(kv->second);
PyDict_SetItem(ret, kobj, vobj);
Py_DECREF(kobj);
Py_DECREF(vobj);
}
return ret;
}
PyObject *to_python<types::empty_dict>::convert(types::empty_dict)
{
return PyDict_New();
}
template <typename K, typename V>
bool from_python<types::dict<K, V>>::
is_convertible(PyObject *obj)
{
if (PyDict_Check(obj)) {
PyObject *key, *value;
Py_ssize_t pos = 0;
if (PyDict_Next(obj, &pos, &key, &value)) {
return ::is_convertible<K>(key) && ::is_convertible<V>(value);
} else
return true;
}
return false;
}
template <typename K, typename V>
types::dict<K, V> from_python<types::dict<K, V>>::convert(PyObject *obj)
{
types::dict<K, V> v = types::empty_dict();
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(obj, &pos, &key, &value))
v[ ::from_python<K>(key)] = ::from_python<V>(value);
return v;
}
PYTHONIC_NS_END
#endif
#endif