Skip to content

Commit

Permalink
added uint double map
Browse files Browse the repository at this point in the history
  • Loading branch information
scopatz committed Mar 22, 2013
1 parent 9acce0e commit 41e2e21
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions pyne/apigen/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def main():
('map', 'str', 'double'),
('map', 'int', 'int'),
('map', 'int', 'double'),
('map', 'uint', 'double'),
('map', 'int', 'complex'),
('map', 'int', 'vector[double]'),
('map', 'str', 'vector[double]'),
Expand Down
13 changes: 13 additions & 0 deletions pyne/stlconverters.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,19 @@ cdef class _MapIntDouble:



# MapUIntDouble
cdef class MapIterUIntDouble(object):
cdef cpp_map[extra_types.uint, double].iterator * iter_now
cdef cpp_map[extra_types.uint, double].iterator * iter_end
cdef void init(MapIterUIntDouble, cpp_map[extra_types.uint, double] *)

cdef class _MapUIntDouble:
cdef cpp_map[extra_types.uint, double] * map_ptr
cdef public bint _free_map




# MapIntComplex
cdef class MapIterIntComplex(object):
cdef cpp_map[int, extra_types.complex_t].iterator * iter_now
Expand Down
123 changes: 123 additions & 0 deletions pyne/stlconverters.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,129 @@ class MapIntDouble(_MapIntDouble, collections.MutableMapping):



# Map(UInt, Double)
cdef class MapIterUIntDouble(object):
cdef void init(self, cpp_map[extra_types.uint, double] * map_ptr):
cdef cpp_map[extra_types.uint, double].iterator * itn = <cpp_map[extra_types.uint, double].iterator *> malloc(sizeof(map_ptr.begin()))
itn[0] = map_ptr.begin()
self.iter_now = itn

cdef cpp_map[extra_types.uint, double].iterator * ite = <cpp_map[extra_types.uint, double].iterator *> malloc(sizeof(map_ptr.end()))
ite[0] = map_ptr.end()
self.iter_end = ite

def __dealloc__(self):
free(self.iter_now)
free(self.iter_end)

def __iter__(self):
return self

def __next__(self):
cdef cpp_map[extra_types.uint, double].iterator inow = deref(self.iter_now)
cdef cpp_map[extra_types.uint, double].iterator iend = deref(self.iter_end)

if inow != iend:
pyval = int(deref(inow).first)
else:
raise StopIteration

inc(deref(self.iter_now))
return pyval

cdef class _MapUIntDouble:
def __cinit__(self, new_map=True, bint free_map=True):
cdef pair[extra_types.uint, double] item

# Decide how to init map, if at all
if isinstance(new_map, _MapUIntDouble):
self.map_ptr = (<_MapUIntDouble> new_map).map_ptr
elif hasattr(new_map, 'items'):
self.map_ptr = new cpp_map[extra_types.uint, double]()
for key, value in new_map.items():
item = pair[extra_types.uint, double](<extra_types.uint> long(key), <double> value)
self.map_ptr.insert(item)
elif hasattr(new_map, '__len__'):
self.map_ptr = new cpp_map[extra_types.uint, double]()
for key, value in new_map:
item = pair[extra_types.uint, double](<extra_types.uint> long(key), <double> value)
self.map_ptr.insert(item)
elif bool(new_map):
self.map_ptr = new cpp_map[extra_types.uint, double]()

# Store free_map
self._free_map = free_map

def __dealloc__(self):
if self._free_map:
del self.map_ptr

def __contains__(self, key):
cdef extra_types.uint k
if not isinstance(key, int) and not isinstance(key, long):
return False
k = <extra_types.uint> long(key)

if 0 < self.map_ptr.count(k):
return True
else:
return False

def __len__(self):
return self.map_ptr.size()

def __iter__(self):
cdef MapIterUIntDouble mi = MapIterUIntDouble()
mi.init(self.map_ptr)
return mi

def __getitem__(self, key):
cdef extra_types.uint k
cdef double v

if not isinstance(key, int) and not isinstance(key, long):
raise TypeError("Only unsigned integer keys are valid.")
k = <extra_types.uint> long(key)

if 0 < self.map_ptr.count(k):
v = deref(self.map_ptr)[k]
return float(v)
else:
raise KeyError

def __setitem__(self, key, value):
cdef pair[extra_types.uint, double] item = pair[extra_types.uint, double](<extra_types.uint> long(key), <double> value)
self.map_ptr.insert(item)

def __delitem__(self, key):
cdef extra_types.uint k
if key in self:
k = <extra_types.uint> long(key)
self.map_ptr.erase(k)


class MapUIntDouble(_MapUIntDouble, collections.MutableMapping):
"""Wrapper class for C++ standard library maps of type <unsigned integer, double>.
Provides dictionary like interface on the Python level.
Parameters
----------
new_map : bool or dict-like
Boolean on whether to make a new map or not, or dict-like object
with keys and values which are castable to the appropriate type.
free_map : bool
Flag for whether the pointer to the C++ map should be deallocated
when the wrapper is dereferenced.
"""

def __str__(self):
return self.__repr__()

def __repr__(self):
return "{" + ", ".join(["{0}: {1}".format(repr(key), repr(value)) for key, value in self.items()]) + "}"



# Map(Int, Complex)
cdef class MapIterIntComplex(object):
cdef void init(self, cpp_map[int, extra_types.complex_t] * map_ptr):
Expand Down
22 changes: 22 additions & 0 deletions pyne/tests/test_stlconverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ def test_map_int_dbl():



# MapUIntDouble
def test_map_uint_dbl():
m = conv.MapUIntDouble()
m[1] = 18
m[65] = -65.5555
assert_equal(len(m), 2)
assert_equal(m[65], -65.5555)

m = conv.MapUIntDouble({4043370667L: 42.42, 42L: 1.0})
assert_equal(len(m), 2)
assert_equal(m[4043370667L], 42.42)

n = conv.MapUIntDouble(m, False)
assert_equal(len(n), 2)
assert_equal(n[4043370667L], 42.42)

# points to the same underlying map
n[65] = -65.5555
assert_equal(m[65], -65.5555)



# MapIntComplex
def test_map_int_complex():
m = conv.MapIntComplex()
Expand Down

0 comments on commit 41e2e21

Please sign in to comment.